lemoncurry/micropub/views/media.py

54 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