Pārlūkot izejas kodu

Sync contacts when receiving sync message saying there are contacts

Tulir Asokan 4 gadi atpakaļ
vecāks
revīzija
39b32d229a
3 mainītis faili ar 64 papildinājumiem un 8 dzēšanām
  1. 41 2
      mausignald/types.py
  2. 6 3
      mautrix_signal/signal.py
  3. 17 3
      mautrix_signal/user.py

+ 41 - 2
mausignald/types.py

@@ -9,7 +9,7 @@ from uuid import UUID
 from attr import dataclass
 import attr
 
-from mautrix.types import SerializableAttrs, SerializableEnum
+from mautrix.types import SerializableAttrs, SerializableEnum, ExtensibleEnum
 
 GroupID = NewType('GroupID', str)
 
@@ -300,13 +300,52 @@ class Receipt(SerializableAttrs['Receipt']):
     when: int
 
 
+@dataclass
+class ContactSyncMeta(SerializableAttrs['ContactSyncMeta']):
+    id: Optional[str] = None
+
+
+@dataclass
+class ConfigItem(SerializableAttrs['ConfigItem']):
+    present: bool = False
+
+
+@dataclass
+class ClientConfiguration(SerializableAttrs['ClientConfiguration']):
+    read_receipts: Optional[ConfigItem] = attr.ib(factory=lambda: ConfigItem(),
+                                                  metadata={"json": "readReceipts"})
+    typing_indicators: Optional[ConfigItem] = attr.ib(factory=lambda: ConfigItem(),
+                                                      metadata={"json": "typingIndicators"})
+    link_previews: Optional[ConfigItem] = attr.ib(factory=lambda: ConfigItem(),
+                                                  metadata={"json": "linkPreviews"})
+    unidentified_delivery_indicators: Optional[ConfigItem] = attr.ib(
+        factory=lambda: ConfigItem(), metadata={"json": "unidentifiedDeliveryIndicators"})
+
+
+class StickerPackOperation(ExtensibleEnum):
+    INSTALL = "INSTALL"
+    # there are very likely others
+
+
+@dataclass
+class StickerPackOperations(SerializableAttrs['StickerPackOperations']):
+    type: StickerPackOperation
+    pack_id: str = attr.ib(metadata={"json": "packID"})
+    pack_key: str = attr.ib(metadata={"json": "packKey"})
+
+
 @dataclass
 class SyncMessage(SerializableAttrs['SyncMessage']):
     sent: Optional[SentSyncMessage] = None
     typing: Optional[TypingNotification] = None
     read_messages: Optional[List[OwnReadReceipt]] = attr.ib(default=None,
                                                             metadata={"json": "readMessages"})
-    contacts: Optional[Dict[str, Any]] = None
+    contacts: Optional[ContactSyncMeta] = None
+    groups: Optional[ContactSyncMeta] = None
+    configuration: Optional[ClientConfiguration] = None
+    # blocked_list: Optional[???] = attr.ib(default=None, metadata={"json": "blockedList"})
+    sticker_pack_operations: Optional[List[StickerPackOperations]] = attr.ib(
+        default=None, metadata={"json": "stickerPackOperations"})
     contacts_complete: bool = attr.ib(default=False, metadata={"json": "contactsComplete"})
 
 

+ 6 - 3
mautrix_signal/signal.py

@@ -55,15 +55,18 @@ class SignalHandler(SignaldClient):
         if evt.sync_message:
             if evt.sync_message.read_messages:
                 await self.handle_own_receipts(sender, evt.sync_message.read_messages)
-            if evt.sync_message.contacts:
-                # Contact list update?
-                pass
             if evt.sync_message.sent:
                 await self.handle_message(user, sender, evt.sync_message.sent.message,
                                           addr_override=evt.sync_message.sent.destination)
             if evt.sync_message.typing:
                 # Typing notification from own device
                 pass
+            if evt.sync_message.contacts or evt.sync_message.contacts_complete:
+                self.log.debug("Sync message includes contacts meta, syncing contacts...")
+                await user.sync_contacts()
+            if evt.sync_message.groups:
+                self.log.debug("Sync message includes groups meta, syncing contacts...")
+                await user.sync_groups()
 
     @staticmethod
     async def on_listen(evt: ListenEvent) -> None:

+ 17 - 3
mautrix_signal/user.py

@@ -49,12 +49,14 @@ class User(DBUser, BaseUser):
     is_admin: bool
     permission_level: str
 
+    _sync_lock: asyncio.Lock
     _notice_room_lock: asyncio.Lock
 
     def __init__(self, mxid: UserID, username: Optional[str] = None, uuid: Optional[UUID] = None,
                  notice_room: Optional[RoomID] = None) -> None:
         super().__init__(mxid=mxid, username=username, uuid=uuid, notice_room=notice_room)
         self._notice_room_lock = asyncio.Lock()
+        self._sync_lock = asyncio.Lock()
         perms = self.config.get_permissions(mxid)
         self.is_whitelisted, self.is_admin, self.permission_level = perms
         self.log = self.log.getChild(self.mxid)
@@ -136,16 +138,28 @@ class User(DBUser, BaseUser):
             await puppet.switch_mxid(access_token="auto", mxid=self.mxid)
 
     async def sync(self) -> None:
+        await self.sync_puppet()
+        await self.sync_contacts()
+        await self.sync_groups()
+
+    async def sync_puppet(self) -> None:
         try:
-            await self._sync_puppet()
+            async with self._sync_lock:
+                await self._sync_puppet()
         except Exception:
             self.log.exception("Error while syncing own puppet")
+
+    async def sync_contacts(self) -> None:
         try:
-            await self._sync_contacts()
+            async with self._sync_lock:
+                await self._sync_contacts()
         except Exception:
             self.log.exception("Error while syncing contacts")
+
+    async def sync_groups(self) -> None:
         try:
-            await self._sync_groups()
+            async with self._sync_lock:
+                await self._sync_groups()
         except Exception:
             self.log.exception("Error while syncing groups")