Explorar o código

Fix bugs and add command to start PMs

Tulir Asokan %!s(int64=4) %!d(string=hai) anos
pai
achega
9853392c66

+ 1 - 0
mautrix_signal/commands/__init__.py

@@ -1,2 +1,3 @@
 from .auth import SECTION_AUTH
 from .conn import SECTION_CONNECTION
+from .signal import SECTION_CREATING_PORTALS

+ 49 - 0
mautrix_signal/commands/signal.py

@@ -0,0 +1,49 @@
+# mautrix-signal - A Matrix-Signal puppeting bridge
+# Copyright (C) 2020 Tulir Asokan
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+from mautrix.bridge.commands import HelpSection, command_handler
+from mausignald.types import Address
+
+from .. import puppet as pu, portal as po
+from .typehint import CommandEvent
+
+SECTION_CREATING_PORTALS = HelpSection("Creating portals", 20, "")
+
+remove_extra_chars = str.maketrans("", "", " .,-()")
+
+
+@command_handler(needs_auth=True, management_only=False, help_section=SECTION_CREATING_PORTALS,
+                 help_text="Open a private chat portal with a specific phone number",
+                 help_args="<_phone_>")
+async def pm(evt: CommandEvent) -> None:
+    if len(evt.args) == 0 or not evt.args[0].startswith("+"):
+        await evt.reply("**Usage:** `$cmdprefix+sp pm <phone>` "
+                        "(enter phone number in international format)")
+        return
+    phone = "".join(evt.args).translate(remove_extra_chars)
+    if not phone[1:].isdecimal():
+        await evt.reply("**Usage:** `$cmdprefix+sp pm <phone>` "
+                        "(enter phone number in international format)")
+        return
+    puppet = await pu.Puppet.get_by_address(Address(number=phone))
+    portal = await po.Portal.get_by_chat_id(puppet.address, receiver=evt.sender.username,
+                                            create=True)
+    if portal.mxid:
+        await evt.reply(f"You already have a private chat with {puppet.name}: "
+                        f"[{portal.mxid}](https://matrix.to/#/{portal.mxid})")
+        await portal.main_intent.invite_user(portal.mxid, evt.sender.mxid)
+        return
+    await portal.create_matrix_room(evt.sender, puppet.address)
+    await evt.reply(f"Created a portal room with [{puppet.name}](https://matrix.to/#/{puppet.mxid}) and invited you to it")

+ 15 - 7
mautrix_signal/puppet.py

@@ -24,6 +24,7 @@ from mausignald.types import Address, Contact, Profile
 from mautrix.bridge import BasePuppet
 from mautrix.appservice import IntentAPI
 from mautrix.types import UserID, SyncToken, RoomID
+from mautrix.errors import MForbidden
 from mautrix.util.simple_template import SimpleTemplate
 
 from .db import Puppet as DBPuppet
@@ -61,7 +62,7 @@ class Puppet(DBPuppet, BasePuppet):
         super().__init__(uuid=uuid, number=number, name=name, uuid_registered=uuid_registered,
                          number_registered=number_registered, custom_mxid=custom_mxid,
                          access_token=access_token, next_batch=next_batch, base_url=base_url)
-        self.log = self.log.getChild(str(uuid) or number)
+        self.log = self.log.getChild(str(uuid) if uuid else number)
 
         self.default_mxid = self.get_mxid_from_id(self.address)
         self.default_mxid_intent = self.az.intent.user(self.default_mxid)
@@ -131,17 +132,24 @@ class Puppet(DBPuppet, BasePuppet):
         self.default_mxid = self.get_mxid_from_id(self.address)
         self.default_mxid_intent = self.az.intent.user(self.default_mxid)
         self.intent = self._fresh_intent()
-        await self.intent.ensure_registered()
+        await self.default_mxid_intent.ensure_registered()
         if self.name:
-            await self.intent.set_displayname(self.name)
-        self.log = self.log.getChild(str(uuid))
-        self.log.debug(f"Migrating memberships {prev_intent.mxid} -> {self.default_mxid_intent}")
-        for room_id in await prev_intent.get_joined_rooms():
+            await self.default_mxid_intent.set_displayname(self.name)
+        self.log = Puppet.log.getChild(str(uuid))
+        self.log.debug(f"Migrating memberships {prev_intent.mxid}"
+                       f" -> {self.default_mxid_intent.mxid}")
+        try:
+            joined_rooms = await prev_intent.get_joined_rooms()
+        except MForbidden as e:
+            self.log.debug(f"Got MForbidden ({e.message}) when getting joined rooms of old mxid, "
+                           "assuming there are no rooms to rejoin")
+            return
+        for room_id in joined_rooms:
             await prev_intent.invite_user(room_id, self.default_mxid)
             await prev_intent.leave_room(room_id)
             await self.default_mxid_intent.join_room_by_id(room_id)
 
-    async def update_info(self, info: Union[Profile, Contact]) -> None:
+    async def update_info(self, info: Union[Profile, Contact, Address]) -> None:
         if isinstance(info, (Contact, Address)):
             address = info.address if isinstance(info, Contact) else info
             if address.uuid and not self.uuid:

+ 1 - 1
requirements.txt

@@ -4,5 +4,5 @@ commonmark>=0.8,<0.10
 aiohttp>=3,<3.7
 yarl>=1,<1.6
 attrs>=19.1
-mautrix==0.8.0.beta9
+mautrix==0.8.0rc1
 asyncpg>=0.20,<0.22