1
0
mirror of https://github.com/etesync/server synced 2024-11-22 08:48:07 +00:00

Chunk uploading: implement properly using a custom Parser.

This commit is contained in:
Tom Hacohen 2020-08-04 13:42:28 +03:00
parent 11001ed62c
commit 1d5baece1e
4 changed files with 52 additions and 5 deletions

View File

@ -0,0 +1,17 @@
# Generated by Django 3.0.3 on 2020-08-04 10:59
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('django_etebase', '0021_auto_20200626_0913'),
]
operations = [
migrations.AlterUniqueTogether(
name='collectionitemchunk',
unique_together={('item', 'uid')},
),
]

View File

@ -100,6 +100,9 @@ class CollectionItemChunk(models.Model):
def __str__(self): def __str__(self):
return self.uid return self.uid
class Meta:
unique_together = ('item', 'uid')
def generate_stoken_uid(): def generate_stoken_uid():
return get_random_string(32, allowed_chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_') return get_random_string(32, allowed_chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_')

15
django_etebase/parsers.py Normal file
View File

@ -0,0 +1,15 @@
from rest_framework.parsers import FileUploadParser
class ChunkUploadParser(FileUploadParser):
"""
Parser for chunk upload data.
"""
media_type = 'application/octet-stream'
def get_filename(self, stream, media_type, parser_context):
"""
Detects the uploaded file name.
"""
view = parser_context['view']
return parser_context['kwargs'][view.lookup_field]

View File

@ -73,6 +73,7 @@ from .serializers import (
) )
from .utils import get_user_queryset from .utils import get_user_queryset
from .exceptions import EtebaseValidationError from .exceptions import EtebaseValidationError
from .parsers import ChunkUploadParser
User = get_user_model() User = get_user_model()
@ -398,11 +399,11 @@ class CollectionItemViewSet(BaseViewSet):
class CollectionItemChunkViewSet(viewsets.ViewSet): class CollectionItemChunkViewSet(viewsets.ViewSet):
allowed_methods = ['GET', 'POST'] allowed_methods = ['GET', 'PUT']
authentication_classes = BaseViewSet.authentication_classes authentication_classes = BaseViewSet.authentication_classes
permission_classes = BaseViewSet.permission_classes permission_classes = BaseViewSet.permission_classes
renderer_classes = BaseViewSet.renderer_classes renderer_classes = BaseViewSet.renderer_classes
parser_classes = (MultiPartParser, ) parser_classes = (ChunkUploadParser, )
serializer_class = CollectionItemChunkSerializer serializer_class = CollectionItemChunkSerializer
lookup_field = 'uid' lookup_field = 'uid'
@ -413,13 +414,24 @@ class CollectionItemChunkViewSet(viewsets.ViewSet):
user = self.request.user user = self.request.user
return queryset.filter(members__user=user) return queryset.filter(members__user=user)
def create(self, request, collection_uid=None, collection_item_uid=None, *args, **kwargs): def update(self, request, *args, collection_uid=None, collection_item_uid=None, uid=None, **kwargs):
col = get_object_or_404(self.get_collection_queryset(), main_item__uid=collection_uid) col = get_object_or_404(self.get_collection_queryset(), main_item__uid=collection_uid)
col_it = get_object_or_404(col.items, uid=collection_item_uid) col_it = get_object_or_404(col.items, uid=collection_item_uid)
serializer = self.get_serializer_class()(data=request.data) data = {
"uid": uid,
"chunkFile": request.data["file"],
}
serializer = self.get_serializer_class()(data=data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
serializer.save(item=col_it) try:
serializer.save(item=col_it)
except IntegrityError:
return Response(
{"code": "chunk_exists", "detail": "Chunk already exists."},
status=status.HTTP_409_CONFLICT
)
return Response({}, status=status.HTTP_201_CREATED) return Response({}, status=status.HTTP_201_CREATED)