From ad23445b6909bc01a1cd11b924c7b1fae48b61fe Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 23 Jun 2018 23:46:41 +0300 Subject: [PATCH] Simplify and improve message format config --- example-config.yaml | 22 ++++++++----- mautrix_telegram/config.py | 5 +-- mautrix_telegram/portal.py | 63 +++++++++++++------------------------- mautrix_telegram/user.py | 8 +++-- 4 files changed, 42 insertions(+), 56 deletions(-) diff --git a/example-config.yaml b/example-config.yaml index 7785d488..2e697f97 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -116,16 +116,22 @@ bridge: catch_up: false # The formats to use when sending messages to Telegram via the relay bot. + # + # Telegram doesn't have built-in emotes, so the m.emote format is also used for non-relaybot users. + # # Available variables: - # $sender_display_name - The display name of the sender - # $message - The message text itself + # $sender_display_name - The display name of the sender (e.g. Example User) + # $sender_username - The username (Matrix ID localpart) of the sender (e.g. exampleuser) + # $sender_mxid - The Matrix ID of the sender (e.g. @exampleuser:example.com) + # $message - The message content as HTML message_formats: - m_text: - plain: "<$sender_display_name> $message" - html: "<$sender_display_name> $message" - m_emote: - plain: "* $sender_display_name $message" - html: "* $sender_display_name $message" + m.text: "<$sender_display_name> $message" + m.emote: "* $sender_display_name $message" + m.file: "$sender_display_name sent a file: $message" + m.image: "$sender_display_name sent an image: $message" + m.audio: "$sender_display_name sent an audio file: $message" + m.video: "$sender_display_name sent a video: $message" + m.location: "$sender_display_name sent a location: $message" filter: # Filter mode to use. Either "blacklist" or "whitelist". diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py index 2d9aaccc..a26dd8ef 100644 --- a/mautrix_telegram/config.py +++ b/mautrix_telegram/config.py @@ -181,10 +181,7 @@ class Config(DictWithRecursion): copy("bridge.native_stickers") copy("bridge.catch_up") - copy("bridge.message_formats.m_text.plain") - copy("bridge.message_formats.m_text.html") - copy("bridge.message_formats.m_emote.plain") - copy("bridge.message_formats.m_emote.html") + copy_dict("bridge.message_formats") copy("bridge.filter.mode") copy("bridge.filter.list") diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 5ddab6a9..95b1e33d 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -659,56 +659,35 @@ class Portal: self.is_duplicate(response, (event_id, space)) return - if self.peer_type == "channel": + if self.peer_type == "channel" and not user.is_bot: await user.client(JoinChannelRequest(channel=await self.get_input_entity(user))) else: # We'll just assume the user is already in the chat. pass @staticmethod - def _preprocess_matrix_message(sender, use_relaybot, message): + def _apply_msg_format(sender, msgtype, message): + if "formatted_body" not in message: + message["format"] = "org.matrix.custom.html" + message["formatted_body"] = escape_html(message["body"]) + body = message["formatted_body"] + + tpl = config["bridge.message_formats"].get(msgtype, + "<$sender_display_name> $message") + tpl_args = dict(sender_mxid=sender.mxid, + sender_username=sender.mxid_localpart, + sender_display_name=sender.displayname, + message=body) + message["formatted_body"] = Template(tpl).safe_substitute(tpl_args) + + @classmethod + def _preprocess_matrix_message(cls, sender, use_relaybot, message): msgtype = message["msgtype"] if msgtype == "m.emote": - if "formatted_body" in message: - tpl = config["bridge.message_formats.m_emote.html"] - tpl_args = dict(sender_display_name=sender.displayname, - message=message['formatted_body']) - message["formatted_body"] = Template(tpl).safe_substitute(tpl_args) - tpl = config["bridge.message_formats.m_emote.plain"] - tpl_args = dict(sender_display_name=sender.displayname, message=message['body']) - message["body"] = Template(tpl).safe_substitute(tpl_args) + cls._apply_msg_format(sender, msgtype, message) message["msgtype"] = "m.text" - elif not use_relaybot: - html = message["formatted_body"] if "formatted_body" in message else None - text = message["body"] - if msgtype == "m.text": - # We use the plain text as HTML if available to ensure that we represent - # the event consistently. - if not html: - html = escape_html(text) - tpl = config["bridge.message_formats.m_text.html"] - tpl_args = dict(sender_display_name=sender.displayname, message=html) - html = Template(tpl).safe_substitute(tpl_args) - tpl = config["bridge.message_formats.m_text.plain"] - tpl_args = dict(sender_display_name=sender.displayname, message=text) - text = Template(tpl).safe_substitute(tpl_args) - else: - msgtype = msgtype[len("m."):] - prefix = { - "file": "a ", - "image": "an ", - "audio": "", - "video": "a ", - "location": "a ", - }.get(msgtype, "") - if html: - html = f"{sender.displayname} sent {prefix}{msgtype}: {html}" - text = ": " + text if text else "" - text = f"{sender.displayname} sent {prefix}{msgtype}{text}" - if html: - message["formatted_body"] = html - message["format"] = "org.matrix.custom.html" - message["body"] = text + elif use_relaybot: + cls._apply_msg_format(sender, msgtype, message) async def _matrix_event_to_entities(self, client, event): try: @@ -833,7 +812,7 @@ class Portal: reply_to = formatter.matrix_reply_to_telegram(message, space, room_id=self.mxid) message["mxtg_filename"] = message["body"] - self._preprocess_matrix_message(sender, logged_in, message) + self._preprocess_matrix_message(sender, not logged_in, message) type = message["msgtype"] if type == "m.text" or (self.bridge_notices and type == "m.notice"): diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 809b2ea8..8fa72233 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -64,11 +64,15 @@ class User(AbstractUser): return self.mxid @property - def displayname(self): - # TODO show better username + def mxid_localpart(self): match = re.compile("@(.+):(.+)").match(self.mxid) return match.group(1) + @property + def displayname(self): + # TODO show better display name + return self.mxid_localpart + @property def db_contacts(self): return [self.db.merge(DBContact(user=self.tgid, contact=puppet.id))