Implement fetch_updates.
This commit is contained in:
parent
a9bc08a98d
commit
a3ae769a2c
@ -15,7 +15,7 @@ from django_etebase import models
|
|||||||
from .authentication import get_authenticated_user
|
from .authentication import get_authenticated_user
|
||||||
from .exceptions import ValidationError, transform_validation_error
|
from .exceptions import ValidationError, transform_validation_error
|
||||||
from .msgpack import MsgpackRoute, MsgpackResponse
|
from .msgpack import MsgpackRoute, MsgpackResponse
|
||||||
from .stoken_handler import filter_by_stoken_and_limit, get_stoken_obj
|
from .stoken_handler import filter_by_stoken_and_limit, filter_by_stoken, get_stoken_obj, get_queryset_stoken
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
collection_router = APIRouter(route_class=MsgpackRoute)
|
collection_router = APIRouter(route_class=MsgpackRoute)
|
||||||
@ -133,6 +133,11 @@ class CollectionItemListResponse(BaseModel):
|
|||||||
done: bool
|
done: bool
|
||||||
|
|
||||||
|
|
||||||
|
class CollectionItemBulkGetIn(BaseModel):
|
||||||
|
uid: str
|
||||||
|
etag: t.Optional[str]
|
||||||
|
|
||||||
|
|
||||||
class ItemDepIn(BaseModel):
|
class ItemDepIn(BaseModel):
|
||||||
etag: str
|
etag: str
|
||||||
uid: str
|
uid: str
|
||||||
@ -417,6 +422,41 @@ def item_bulk_common(data: ItemBatchIn, user: User, stoken: t.Optional[str], uid
|
|||||||
return MsgpackResponse({})
|
return MsgpackResponse({})
|
||||||
|
|
||||||
|
|
||||||
|
@collection_router.post("/{collection_uid}/item/fetch_updates/")
|
||||||
|
def fetch_updates(
|
||||||
|
collection_uid: str,
|
||||||
|
data: t.List[CollectionItemBulkGetIn],
|
||||||
|
stoken: t.Optional[str] = None,
|
||||||
|
prefetch: Prefetch = PrefetchQuery,
|
||||||
|
user: User = Depends(get_authenticated_user),
|
||||||
|
):
|
||||||
|
_, queryset = get_item_queryset(user, collection_uid)
|
||||||
|
# FIXME: make configurable?
|
||||||
|
item_limit = 200
|
||||||
|
|
||||||
|
if len(data) > item_limit:
|
||||||
|
raise ValidationError("too_many_items", "Request has too many items.", status_code=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
queryset, stoken_rev = filter_by_stoken(stoken, queryset, models.CollectionItem.stoken_annotation)
|
||||||
|
|
||||||
|
uids, etags = zip(*[(item.uid, item.etag) for item in data])
|
||||||
|
revs = models.CollectionItemRevision.objects.filter(uid__in=etags, current=True)
|
||||||
|
queryset = queryset.filter(uid__in=uids).exclude(revisions__in=revs)
|
||||||
|
|
||||||
|
new_stoken_obj = get_queryset_stoken(queryset)
|
||||||
|
new_stoken = new_stoken_obj and new_stoken_obj.uid
|
||||||
|
stoken = stoken_rev and getattr(stoken_rev, "uid", None)
|
||||||
|
new_stoken = new_stoken or stoken
|
||||||
|
|
||||||
|
context = Context(user, prefetch)
|
||||||
|
ret = CollectionItemListResponse(
|
||||||
|
data=[CollectionItemOut.from_orm_context(item, context) for item in queryset],
|
||||||
|
stoken=new_stoken,
|
||||||
|
done=True, # we always return all the items, so it's always done
|
||||||
|
)
|
||||||
|
return MsgpackResponse(ret)
|
||||||
|
|
||||||
|
|
||||||
@collection_router.post("/{collection_uid}/item/transaction/")
|
@collection_router.post("/{collection_uid}/item/transaction/")
|
||||||
def item_transaction(
|
def item_transaction(
|
||||||
collection_uid: str, data: ItemBatchIn, stoken: t.Optional[str] = None, user: User = Depends(get_authenticated_user)
|
collection_uid: str, data: ItemBatchIn, stoken: t.Optional[str] = None, user: User = Depends(get_authenticated_user)
|
||||||
|
@ -33,7 +33,7 @@ def filter_by_stoken(
|
|||||||
return queryset, stoken_rev
|
return queryset, stoken_rev
|
||||||
|
|
||||||
|
|
||||||
def get_queryset_stoken(queryset: list) -> t.Optional[Stoken]:
|
def get_queryset_stoken(queryset: t.Iterable[t.Any]) -> t.Optional[Stoken]:
|
||||||
maxid = -1
|
maxid = -1
|
||||||
for row in queryset:
|
for row in queryset:
|
||||||
rowmaxid = getattr(row, "max_stoken") or -1
|
rowmaxid = getattr(row, "max_stoken") or -1
|
||||||
|
Loading…
Reference in New Issue
Block a user