فهرست منبع

Update mautrix-python

Tulir Asokan 3 سال پیش
والد
کامیت
105cf52f5a
2فایلهای تغییر یافته به همراه49 افزوده شده و 39 حذف شده
  1. 48 38
      mautrix_signal/formatter.py
  2. 1 1
      requirements.txt

+ 48 - 38
mautrix_signal/formatter.py

@@ -1,5 +1,5 @@
 # mautrix-signal - A Matrix-Signal puppeting bridge
-# Copyright (C) 2020 Tulir Asokan
+# Copyright (C) 2021 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
@@ -13,17 +13,19 @@
 #
 # 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 typing import List, Tuple, cast
-from html import escape
+from __future__ import annotations
+
+from typing import cast
+import html
 import struct
 
-from mautrix.types import Format, MessageType, TextMessageEventContent
+from mautrix.types import Format, MessageType, TextMessageEventContent, UserID
 from mautrix.util.formatter import (
     EntityString,
     EntityType,
     MarkdownString,
     MatrixParser as BaseMatrixParser,
-    SimpleEntity,
+    SemiAbstractEntity,
 )
 
 from mausignald.types import Address, Mention, MessageData
@@ -31,9 +33,9 @@ from mausignald.types import Address, Mention, MessageData
 from . import puppet as pu, user as u
 
 
-# Helper methods from rom https://github.com/LonamiWebs/Telethon/blob/master/telethon/helpers.py
-# I don't know if this is how Signal actually calculates lengths, but it seems
-# to work better than plain len()
+# Helper methods from from https://github.com/LonamiWebs/Telethon/blob/master/telethon/helpers.py
+# I don't know if this is how Signal actually calculates lengths,
+# but it seems to work better than plain len()
 def add_surrogate(text: str) -> str:
     return "".join(
         "".join(chr(y) for y in struct.unpack("<HH", x.encode("utf-16le")))
@@ -59,32 +61,40 @@ async def signal_to_matrix(message: MessageData) -> TextMessageEventContent:
             last_offset = mention.start + mention.length
 
             text_chunks.append(before)
-            html_chunks.append(escape(before))
+            html_chunks.append(html.escape(before))
             puppet = await pu.Puppet.get_by_address(Address(uuid=mention.uuid))
             name = add_surrogate(puppet.name or puppet.mxid)
             text_chunks.append(name)
             html_chunks.append(f'<a href="https://matrix.to/#/{puppet.mxid}">{name}</a>')
         end = surrogated_text[last_offset:]
         text_chunks.append(end)
-        html_chunks.append(escape(end))
+        html_chunks.append(html.escape(end))
         content.body = del_surrogate("".join(text_chunks))
         content.format = Format.HTML
         content.formatted_body = del_surrogate("".join(html_chunks))
     return content
 
 
+class MentionEntity(Mention, SemiAbstractEntity):
+    @property
+    def offset(self) -> int:
+        return self.start
+
+    @offset.setter
+    def offset(self, val: int) -> None:
+        self.start = val
+
+    def copy(self) -> MentionEntity:
+        return MentionEntity(uuid=self.uuid, length=self.length, start=self.start)
+
+
 # TODO this has a lot of duplication with mautrix-facebook, maybe move to mautrix-python
-class SignalFormatString(EntityString[SimpleEntity, EntityType], MarkdownString):
-    def format(self, entity_type: EntityType, **kwargs) -> "SignalFormatString":
+class SignalFormatString(EntityString[MentionEntity, EntityType], MarkdownString):
+    def format(self, entity_type: EntityType, **kwargs) -> SignalFormatString:
         prefix = suffix = ""
         if entity_type == EntityType.USER_MENTION:
             self.entities.append(
-                SimpleEntity(
-                    type=entity_type,
-                    offset=0,
-                    length=len(self.text),
-                    extra_info={"user_id": kwargs["user_id"]},
-                )
+                MentionEntity(uuid=kwargs["uuid"], start=0, length=len(self.text)),
             )
             return self
         elif entity_type == EntityType.BOLD:
@@ -118,32 +128,32 @@ class SignalFormatString(EntityString[SimpleEntity, EntityType], MarkdownString)
 class MatrixParser(BaseMatrixParser[SignalFormatString]):
     fs = SignalFormatString
 
-    @classmethod
-    def parse(cls, data: str) -> SignalFormatString:
-        return cast(SignalFormatString, super().parse(data))
+    async def user_pill_to_fstring(
+        self, msg: SignalFormatString, user_id: UserID
+    ) -> SignalFormatString:
+        user = await u.User.get_by_mxid(user_id, create=False)
+        if user and user.uuid:
+            uuid = user.uuid
+        else:
+            puppet = await pu.Puppet.get_by_mxid(user_id, create=False)
+            if puppet:
+                uuid = puppet.uuid
+            else:
+                return msg
+        return msg.format(self.e.USER_MENTION, uuid=uuid)
 
+    async def parse(self, data: str) -> SignalFormatString:
+        return cast(SignalFormatString, await super().parse(data))
 
-async def matrix_to_signal(content: TextMessageEventContent) -> Tuple[str, List[Mention]]:
+
+async def matrix_to_signal(content: TextMessageEventContent) -> tuple[str, list[Mention]]:
     if content.msgtype == MessageType.EMOTE:
         content.body = f"/me {content.body}"
         if content.formatted_body:
             content.formatted_body = f"/me {content.formatted_body}"
-    mentions = []
     if content.format == Format.HTML and content.formatted_body:
-        parsed = MatrixParser.parse(add_surrogate(content.formatted_body))
-        text = del_surrogate(parsed.text)
-        for mention in parsed.entities:
-            mxid = mention.extra_info["user_id"]
-            user = await u.User.get_by_mxid(mxid, create=False)
-            if user and user.uuid:
-                uuid = user.uuid
-            else:
-                puppet = await pu.Puppet.get_by_mxid(mxid, create=False)
-                if puppet:
-                    uuid = puppet.uuid
-                else:
-                    continue
-            mentions.append(Mention(uuid=uuid, start=mention.offset, length=mention.length))
+        parsed = await MatrixParser().parse(add_surrogate(content.formatted_body))
+        text, mentions = del_surrogate(parsed.text), parsed.entities
     else:
-        text = content.body
+        text, mentions = content.body, []
     return text, mentions

+ 1 - 1
requirements.txt

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