api_views: use atomicwrites for writing petale content (#41379)

This commit is contained in:
Benjamin Dauvergne 2020-04-06 17:09:47 +02:00
parent 7b292a2c17
commit 75dc1f103b
3 changed files with 22 additions and 16 deletions

1
debian/control vendored
View File

@ -12,6 +12,7 @@ Depends: ${misc:Depends}, ${python3:Depends},
python3-django-jsonfield, python3-django-jsonfield,
python3-djangorestframework, python3-djangorestframework,
python3-requests, python3-requests,
python3-atomicwrites
Description: Simple key value datastore Description: Simple key value datastore
Package: petale Package: petale

View File

@ -38,6 +38,8 @@ from rest_framework import status
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from atomicwrites import atomic_write
from .models import CUT, Petal, Partner, AccessControlList from .models import CUT, Petal, Partner, AccessControlList
from .utils import logit, StreamingHash from .utils import logit, StreamingHash
from .exceptions import (PartnerNotFound, CutNotFound, KeyNotFound, NotFound, MissingContentType, from .exceptions import (PartnerNotFound, CutNotFound, KeyNotFound, NotFound, MissingContentType,
@ -259,26 +261,28 @@ class PetalAPIView(APIView):
petal.check_limits(content_length) petal.check_limits(content_length)
streaming_digest = StreamingHash(request)
def update_meta():
# update metadata
petal.content_type = content_type
petal.etag = streaming_digest.etag()
petal.size = content_length
# update partner size
Partner.objects.filter(id=petal.partner.id).update(size=F('size') + size_delta)
petal.save()
if created: if created:
status_code = status.HTTP_201_CREATED status_code = status.HTTP_201_CREATED
old_name = None petal.data.save(petal_name, streaming_digest, save=False)
update_meta()
else: else:
old_name = petal.data.name with atomic_write(petal.data.path, overwrite=True, mode='wb') as fd:
for block in iter(lambda: streaming_digest.read(512), b''):
fd.write(block)
update_meta()
streaming_digest = StreamingHash(request)
petal.data.save(petal_name, streaming_digest, save=False)
# update metadata
petal.content_type = content_type
petal.etag = streaming_digest.etag()
petal.size = content_length
# update partner size
Partner.objects.filter(id=petal.partner.id).update(size=F('size') + size_delta)
petal.save()
if old_name:
petal.data.storage.delete(old_name)
return Response( return Response(
{}, {},
status=status_code, status=status_code,

View File

@ -126,6 +126,7 @@ setup(
'django-jsonfield', 'django-jsonfield',
'djangorestframework>=3.3', 'djangorestframework>=3.3',
'requests', 'requests',
'atomicwrites',
], ],
zip_safe=False, zip_safe=False,
cmdclass={ cmdclass={