client: Store and load sync tokens.

This commit is contained in:
Damir Jelić 2019-06-11 16:06:35 +02:00
parent 2fc738dc20
commit 383f197e58
3 changed files with 61 additions and 3 deletions

View File

@ -276,6 +276,12 @@ class PanClient(AsyncClient):
self.index.commit() self.index.commit()
self.pan_store.save_token(
self.server_name,
self.user_id,
self.next_batch
)
for room_id, room in response.rooms.join.items(): for room_id, room in response.rooms.join.items():
if room.timeline.limited: if room.timeline.limited:
logger.info("Room {} had a limited timeline, queueing " logger.info("Room {} had a limited timeline, queueing "
@ -389,6 +395,11 @@ class PanClient(AsyncClient):
} }
} }
self.next_batch = self.pan_store.load_token(
self.server_name,
self.user_id
)
# We don't store any room state so initial sync needs to be with the # We don't store any room state so initial sync needs to be with the
# full_state parameter. Subsequent ones are normal. # full_state parameter. Subsequent ones are normal.
while True: while True:
@ -415,7 +426,6 @@ class PanClient(AsyncClient):
await self.sync_forever(timeout, sync_filter) await self.sync_forever(timeout, sync_filter)
async def start_sas(self, message, device): async def start_sas(self, message, device):
try: try:
await self.start_key_verification(device) await self.start_key_verification(device)

View File

@ -16,9 +16,10 @@ import datetime
import json import json
import os import os
from collections import defaultdict from collections import defaultdict
from typing import Any, Dict, List, Optional, Tuple, Union from typing import Dict, List, Optional, Tuple
import attr import attr
from nio import RoomMessage
from nio.store import (Accounts, DeviceKeys, DeviceTrustState, TrustState, from nio.store import (Accounts, DeviceKeys, DeviceTrustState, TrustState,
use_database) use_database)
from peewee import (SQL, DateTimeField, DoesNotExist, ForeignKeyField, Model, from peewee import (SQL, DateTimeField, DoesNotExist, ForeignKeyField, Model,
@ -98,6 +99,16 @@ class UserMessages(Model):
column_name="event_id") column_name="event_id")
class PanSyncTokens(Model):
token = TextField()
user = ForeignKeyField(
model=ServerUsers,
column_name="user_id")
class Meta:
constraints = [SQL("UNIQUE(user_id)")]
@attr.s @attr.s
class ClientInfo: class ClientInfo:
user_id = attr.ib(type=str) user_id = attr.ib(type=str)
@ -120,6 +131,7 @@ class PanStore:
Profile, Profile,
Event, Event,
UserMessages, UserMessages,
PanSyncTokens
] ]
def __attrs_post_init__(self): def __attrs_post_init__(self):
@ -153,10 +165,36 @@ class PanStore:
except DoesNotExist: except DoesNotExist:
return None return None
@use_database
def save_token(self, server, pan_user, token):
# type: (str, str, str) -> None
"""Save a sync token for a pan user."""
server = Servers.get(name=server)
user = ServerUsers.get(server=server, user_id=pan_user)
PanSyncTokens.replace(user=user, token=token).execute()
@use_database
def load_token(self, server, pan_user):
# type: (str, str) -> Optional[str]
"""Load a sync token for a pan user.
Returns the sync token if one is found.
"""
server = Servers.get(name=server)
user = ServerUsers.get(server=server, user_id=pan_user)
token = PanSyncTokens.get_or_none(user=user)
if token:
return token.token
return None
@use_database @use_database
def save_event(self, server, pan_user, event, room_id, display_name, def save_event(self, server, pan_user, event, room_id, display_name,
avatar_url): avatar_url):
# type (str, str, str, RoomMessage, str, str, str) -> Optional[int] # type: (str, str, str, RoomMessage, str, str, str) -> Optional[int]
"""Save an event to the store. """Save an event to the store.
Returns the database id of the event. Returns the database id of the event.

View File

@ -116,3 +116,13 @@ class TestClass(object):
event_dict = panstore.load_event_by_columns("example", user, found_id) event_dict = panstore.load_event_by_columns("example", user, found_id)
assert event_dict["result"] == event.source assert event_dict["result"] == event.source
def test_token_storing(self, panstore_with_users):
panstore = panstore_with_users
accounts = panstore.load_all_users()
user, _ = accounts[0]
assert not panstore.load_token("example", user)
panstore.save_token("example", user, "abc123")
assert "abc123" == panstore.load_token("example", user)