mirror of
https://github.com/etesync/server
synced 2024-11-22 16:58:08 +00:00
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 .exceptions import ValidationError, transform_validation_error
|
||||
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()
|
||||
collection_router = APIRouter(route_class=MsgpackRoute)
|
||||
@ -133,6 +133,11 @@ class CollectionItemListResponse(BaseModel):
|
||||
done: bool
|
||||
|
||||
|
||||
class CollectionItemBulkGetIn(BaseModel):
|
||||
uid: str
|
||||
etag: t.Optional[str]
|
||||
|
||||
|
||||
class ItemDepIn(BaseModel):
|
||||
etag: str
|
||||
uid: str
|
||||
@ -417,6 +422,41 @@ def item_bulk_common(data: ItemBatchIn, user: User, stoken: t.Optional[str], uid
|
||||
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/")
|
||||
def item_transaction(
|
||||
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
|
||||
|
||||
|
||||
def get_queryset_stoken(queryset: list) -> t.Optional[Stoken]:
|
||||
def get_queryset_stoken(queryset: t.Iterable[t.Any]) -> t.Optional[Stoken]:
|
||||
maxid = -1
|
||||
for row in queryset:
|
||||
rowmaxid = getattr(row, "max_stoken") or -1
|
||||
|
Loading…
Reference in New Issue
Block a user