From df0f7d134d5b07894762d07190b62019bf84a55e Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Sun, 19 Apr 2020 17:32:40 +0300 Subject: [PATCH] Collection items: add a transaction endpoint. --- django_etesync/models.py | 4 ++++ django_etesync/views.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/django_etesync/models.py b/django_etesync/models.py index c6ec571..05b81b3 100644 --- a/django_etesync/models.py +++ b/django_etesync/models.py @@ -71,6 +71,10 @@ class CollectionItem(models.Model): def content(self): return self.revisions.get(current=True) + @cached_property + def stoken(self): + return self.content.uid + def chunk_directory_path(instance, filename): item = instance.item diff --git a/django_etesync/views.py b/django_etesync/views.py index b9cd878..87c8010 100644 --- a/django_etesync/views.py +++ b/django_etesync/views.py @@ -14,7 +14,7 @@ from django.conf import settings from django.contrib.auth import get_user_model -from django.db import IntegrityError +from django.db import transaction, IntegrityError from django.db.models import Max from django.http import HttpResponseBadRequest, HttpResponse, Http404 from django.shortcuts import get_object_or_404 @@ -215,6 +215,35 @@ class CollectionItemViewSet(BaseViewSet): } return Response(ret, headers={'X-EteSync-SToken': new_stoken}) + @action_decorator(detail=False, methods=['POST']) + def transaction(self, request, collection_uid=None): + collection_object = get_object_or_404(self.get_collection_queryset(Collection.objects), uid=collection_uid) + + items = request.data.get('items') + # FIXME: deps should actually be just pairs of uid and stoken + deps = request.data.get('deps', None) + serializer = self.get_serializer_class()(data=items, context=self.get_serializer_context(), many=True) + deps_serializer = self.get_serializer_class()(data=deps, context=self.get_serializer_context(), many=True) + if serializer.is_valid() and (deps is None or deps_serializer.is_valid()): + try: + with transaction.atomic(): + collections = serializer.save(collection=collection_object) + except IntegrityError: + content = {'code': 'integrity_error'} + return Response(content, status=status.HTTP_400_BAD_REQUEST) + + ret = { + "data": [collection.stoken for collection in collections], + } + return Response(ret, status=status.HTTP_201_CREATED) + + return Response( + { + "items": serializer.errors, + "deps": deps_serializer.errors if deps is not None else [], + }, + status=status.HTTP_400_BAD_REQUEST) + class CollectionItemChunkViewSet(viewsets.ViewSet): allowed_methods = ['GET', 'POST']