Ver código fonte

Add support for creating DM portals by inviting user. Fixes #227

Tulir Asokan 3 anos atrás
pai
commit
fd11c50527
4 arquivos alterados com 36 adições e 9 exclusões
  1. 1 1
      mautrix_signal/matrix.py
  2. 27 7
      mautrix_signal/portal.py
  3. 7 0
      mautrix_signal/user.py
  4. 1 1
      requirements.txt

+ 1 - 1
mautrix_signal/matrix.py

@@ -35,7 +35,7 @@ from mautrix.types import (
     UserID,
 )
 
-from . import portal as po, signal as s, user as u
+from . import portal as po, puppet as pu, signal as s, user as u
 from .db import Message as DBMessage
 
 if TYPE_CHECKING:

+ 27 - 7
mautrix_signal/portal.py

@@ -1236,7 +1236,7 @@ class Portal(DBPortal, BasePortal):
             if not isinstance(info, (Contact, Profile, Address)):
                 raise ValueError(f"Unexpected type for direct chat update_info: {type(info)}")
             if not self.name:
-                puppet = await p.Puppet.get_by_address(self.chat_id)
+                puppet = await self.get_dm_puppet()
                 if not puppet.name:
                     await puppet.update_info(info)
                 self.name = puppet.name
@@ -1299,7 +1299,22 @@ class Portal(DBPortal, BasePortal):
         content = TextMessageEventContent(msgtype=MessageType.NOTICE, body=body)
         await self._send_message(sender.intent_for(self), content)
 
-    async def update_puppet_avatar(self, new_hash: str, avatar_url: ContentURI) -> None:
+    async def get_dm_puppet(self) -> p.Puppet | None:
+        if not self.is_direct:
+            return None
+        return await p.Puppet.get_by_address(self.chat_id)
+
+    async def update_info_from_puppet(self, puppet: p.Puppet | None = None) -> None:
+        if not self.is_direct:
+            return
+        if not puppet:
+            puppet = await self.get_dm_puppet()
+        await self.update_puppet_name(puppet.name, save=False)
+        await self.update_puppet_avatar(puppet.avatar_hash, puppet.avatar_url, save=False)
+
+    async def update_puppet_avatar(
+        self, new_hash: str, avatar_url: ContentURI, save: bool = True
+    ) -> None:
         if not self.encrypted and not self.private_chat_portal_meta:
             return
 
@@ -1313,16 +1328,17 @@ class Portal(DBPortal, BasePortal):
                 except Exception:
                     self.log.exception("Error setting avatar")
                     self.avatar_set = False
-                await self.update_bridge_info()
-                await self.update()
+                if save:
+                    await self.update_bridge_info()
+                    await self.update()
 
-    async def update_puppet_name(self, name: str) -> None:
+    async def update_puppet_name(self, name: str, save: bool = True) -> None:
         if not self.encrypted and not self.private_chat_portal_meta:
             return
 
         changed = await self._update_name(name)
 
-        if changed:
+        if changed and save:
             await self.update_bridge_info()
             await self.update()
 
@@ -1681,7 +1697,7 @@ class Portal(DBPortal, BasePortal):
         if self.mxid:
             self.by_mxid[self.mxid] = self
         if self.is_direct:
-            puppet = await p.Puppet.get_by_address(self.chat_id)
+            puppet = await self.get_dm_puppet()
             self._main_intent = puppet.default_mxid_intent
         elif not self.is_direct:
             self._main_intent = self.az.intent
@@ -1690,6 +1706,10 @@ class Portal(DBPortal, BasePortal):
         await DBMessage.delete_all(self.mxid)
         self.by_mxid.pop(self.mxid, None)
         self.mxid = None
+        self.name_set = False
+        self.avatar_set = False
+        self.relay_user_id = None
+        self.topic = None
         self.encrypted = False
         await self.update()
 

+ 7 - 0
mautrix_signal/user.py

@@ -156,6 +156,13 @@ class User(DBUser, BaseUser):
             return None
         return await pu.Puppet.get_by_address(self.address)
 
+    async def get_portal_with(self, puppet: pu.Puppet, create: bool = True) -> po.Portal | None:
+        if not self.username:
+            return None
+        return await po.Portal.get_by_chat_id(
+            puppet.address, receiver=self.username, create=create
+        )
+
     async def on_signin(self, account: Account) -> None:
         self.username = account.account_id
         self.uuid = account.address.uuid

+ 1 - 1
requirements.txt

@@ -4,5 +4,5 @@ commonmark>=0.8,<0.10
 aiohttp>=3,<4
 yarl>=1,<2
 attrs>=19.1
-mautrix==0.15.0rc4
+mautrix==0.15.0rc5
 asyncpg>=0.20,<0.26