Improve and rename bulk_get to filter by item stokens too + cstoken changes
Also change how we return cstokens
This commit is contained in:
parent
aaee8f5e38
commit
c30cc2f229
@ -167,6 +167,14 @@ class CollectionItemDepSerializer(serializers.ModelSerializer):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionItemBulkGetSerializer(serializers.ModelSerializer):
|
||||||
|
stoken = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.CollectionItem
|
||||||
|
fields = ('uid', 'stoken')
|
||||||
|
|
||||||
|
|
||||||
class CollectionSerializer(serializers.ModelSerializer):
|
class CollectionSerializer(serializers.ModelSerializer):
|
||||||
encryptionKey = CollectionEncryptionKeyField()
|
encryptionKey = CollectionEncryptionKeyField()
|
||||||
accessLevel = serializers.SerializerMethodField('get_access_level_from_context')
|
accessLevel = serializers.SerializerMethodField('get_access_level_from_context')
|
||||||
|
@ -43,6 +43,7 @@ from .serializers import (
|
|||||||
AuthenticationLoginInnerSerializer,
|
AuthenticationLoginInnerSerializer,
|
||||||
CollectionSerializer,
|
CollectionSerializer,
|
||||||
CollectionItemSerializer,
|
CollectionItemSerializer,
|
||||||
|
CollectionItemBulkGetSerializer,
|
||||||
CollectionItemDepSerializer,
|
CollectionItemDepSerializer,
|
||||||
CollectionItemRevisionSerializer,
|
CollectionItemRevisionSerializer,
|
||||||
CollectionItemChunkSerializer,
|
CollectionItemChunkSerializer,
|
||||||
@ -78,22 +79,33 @@ class BaseViewSet(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def filter_by_cstoken_and_limit(self, request, queryset):
|
def filter_by_cstoken(self, request, queryset):
|
||||||
limit = int(request.GET.get('limit', 50))
|
|
||||||
|
|
||||||
cstoken_id_field = self.cstoken_id_field + '__id'
|
cstoken_id_field = self.cstoken_id_field + '__id'
|
||||||
|
|
||||||
cstoken_rev = self.get_cstoken_rev(request)
|
cstoken_rev = self.get_cstoken_rev(request)
|
||||||
if cstoken_rev is not None:
|
if cstoken_rev is not None:
|
||||||
filter_by = {cstoken_id_field + '__gt': cstoken_rev.id}
|
filter_by = {cstoken_id_field + '__gt': cstoken_rev.id}
|
||||||
queryset = queryset.filter(**filter_by)
|
queryset = queryset.filter(**filter_by)
|
||||||
cstoken = cstoken_rev.uid
|
|
||||||
else:
|
return queryset, cstoken_rev
|
||||||
cstoken = None
|
|
||||||
|
def get_queryset_cstoken(self, queryset):
|
||||||
|
cstoken_id_field = self.cstoken_id_field + '__id'
|
||||||
|
|
||||||
|
new_cstoken_id = queryset.aggregate(cstoken_id=Max(cstoken_id_field))['cstoken_id']
|
||||||
|
new_cstoken = new_cstoken_id and CollectionItemRevision.objects.get(id=new_cstoken_id).uid
|
||||||
|
|
||||||
|
return queryset, new_cstoken
|
||||||
|
|
||||||
|
def filter_by_cstoken_and_limit(self, request, queryset):
|
||||||
|
limit = int(request.GET.get('limit', 50))
|
||||||
|
|
||||||
|
queryset, cstoken_rev = self.filter_by_cstoken(request, queryset)
|
||||||
|
cstoken = cstoken_rev.uid if cstoken_rev is not None else None
|
||||||
|
|
||||||
queryset = queryset[:limit]
|
queryset = queryset[:limit]
|
||||||
new_cstoken_id = queryset.aggregate(cstoken_id=Max(cstoken_id_field))['cstoken_id']
|
queryset, new_cstoken = self.get_queryset_cstoken(queryset)
|
||||||
new_cstoken = CollectionItemRevision.objects.get(id=new_cstoken_id).uid if new_cstoken_id is not None else cstoken
|
new_cstoken = new_cstoken or cstoken
|
||||||
|
|
||||||
return queryset, new_cstoken
|
return queryset, new_cstoken
|
||||||
|
|
||||||
@ -145,8 +157,9 @@ class CollectionViewSet(BaseViewSet):
|
|||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
'data': serializer.data,
|
'data': serializer.data,
|
||||||
|
'cstoken': new_cstoken,
|
||||||
}
|
}
|
||||||
return Response(ret, headers={'X-EteSync-SToken': new_cstoken})
|
return Response(ret)
|
||||||
|
|
||||||
|
|
||||||
class CollectionItemViewSet(BaseViewSet):
|
class CollectionItemViewSet(BaseViewSet):
|
||||||
@ -212,8 +225,9 @@ class CollectionItemViewSet(BaseViewSet):
|
|||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
'data': serializer.data,
|
'data': serializer.data,
|
||||||
|
'cstoken': new_cstoken,
|
||||||
}
|
}
|
||||||
return Response(ret, headers={'X-EteSync-SToken': new_cstoken})
|
return Response(ret)
|
||||||
|
|
||||||
@action_decorator(detail=True, methods=['GET'])
|
@action_decorator(detail=True, methods=['GET'])
|
||||||
def revision(self, request, collection_uid=None, uid=None):
|
def revision(self, request, collection_uid=None, uid=None):
|
||||||
@ -227,21 +241,40 @@ class CollectionItemViewSet(BaseViewSet):
|
|||||||
}
|
}
|
||||||
return Response(ret)
|
return Response(ret)
|
||||||
|
|
||||||
|
# FIXME: rename to something consistent with what the clients have - maybe list_updates?
|
||||||
@action_decorator(detail=False, methods=['POST'])
|
@action_decorator(detail=False, methods=['POST'])
|
||||||
def bulk_get(self, request, collection_uid=None):
|
def fetch_updates(self, request, collection_uid=None):
|
||||||
queryset = self.get_queryset()
|
queryset = self.get_queryset()
|
||||||
|
|
||||||
if isinstance(request.data, list):
|
serializer = CollectionItemBulkGetSerializer(data=request.data, many=True)
|
||||||
queryset = queryset.filter(uid__in=request.data)
|
if serializer.is_valid():
|
||||||
|
# FIXME: make configurable?
|
||||||
|
item_limit = 200
|
||||||
|
|
||||||
queryset, new_cstoken = self.filter_by_cstoken_and_limit(request, queryset)
|
if len(serializer.validated_data) > item_limit:
|
||||||
|
content = {'code': 'too_many_items',
|
||||||
|
'detail': 'Request has too many items. Limit: {}'. format(item_limit)}
|
||||||
|
return Response(content, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
queryset, cstoken_rev = self.filter_by_cstoken(request, queryset)
|
||||||
|
|
||||||
|
uids, stokens = zip(*[(item['uid'], item.get('stoken')) for item in serializer.validated_data])
|
||||||
|
rev_ids = CollectionItemRevision.objects.filter(uid__in=stokens, current=True).values_list('id', flat=True)
|
||||||
|
queryset = queryset.filter(uid__in=uids).exclude(revisions__id__in=rev_ids)
|
||||||
|
|
||||||
|
queryset, new_cstoken = self.get_queryset_cstoken(queryset)
|
||||||
|
cstoken = cstoken_rev and cstoken_rev.uid
|
||||||
|
new_cstoken = new_cstoken or cstoken
|
||||||
|
|
||||||
serializer = self.get_serializer_class()(queryset, context=self.get_serializer_context(), many=True)
|
serializer = self.get_serializer_class()(queryset, context=self.get_serializer_context(), many=True)
|
||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
'data': serializer.data,
|
'data': serializer.data,
|
||||||
|
'cstoken': new_cstoken,
|
||||||
}
|
}
|
||||||
return Response(ret, headers={'X-EteSync-SToken': new_cstoken})
|
return Response(ret)
|
||||||
|
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
@action_decorator(detail=False, methods=['POST'])
|
@action_decorator(detail=False, methods=['POST'])
|
||||||
def batch(self, request, collection_uid=None):
|
def batch(self, request, collection_uid=None):
|
||||||
|
Loading…
Reference in New Issue
Block a user