forked from 00dani/lemoncurry
52 lines
1.4 KiB
Python
52 lines
1.4 KiB
Python
import hashlib
|
|
|
|
from django.core.files.storage import default_storage as store
|
|
from django.http import HttpResponse
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.views.decorators.http import require_POST
|
|
import magic
|
|
|
|
from lemonauth import tokens
|
|
from lemoncurry.utils import absolute_url
|
|
from .. import error
|
|
|
|
ACCEPTED_MEDIA_TYPES = (
|
|
"image/gif",
|
|
"image/jpeg",
|
|
"image/png",
|
|
)
|
|
|
|
|
|
@csrf_exempt
|
|
@require_POST
|
|
def media(request):
|
|
token = tokens.auth(request)
|
|
if "file" not in request.FILES:
|
|
raise error.bad_req(
|
|
"a file named 'file' must be provided to the media endpoint"
|
|
)
|
|
file = request.FILES["file"]
|
|
if file.content_type not in ACCEPTED_MEDIA_TYPES:
|
|
raise error.bad_req("unacceptable file type {0}".format(file.content_type))
|
|
|
|
mime = None
|
|
sha = hashlib.sha256()
|
|
for chunk in file.chunks():
|
|
if mime is None:
|
|
mime = magic.from_buffer(chunk, mime=True)
|
|
sha.update(chunk)
|
|
|
|
if mime != file.content_type:
|
|
raise error.bad_req(
|
|
"detected file type {0} did not match specified file type {1}".format(
|
|
mime, file.content_type
|
|
)
|
|
)
|
|
|
|
path = "mp/{0[0]}/{2}.{1}".format(*mime.split("/"), sha.hexdigest())
|
|
path = store.save(path, file)
|
|
url = absolute_url(request, store.url(path))
|
|
|
|
res = HttpResponse(status=201)
|
|
res["Location"] = url
|
|
return res
|