diff --git a/mautrix_telegram/__main__.py b/mautrix_telegram/__main__.py index 6023a7c8..0936e514 100644 --- a/mautrix_telegram/__main__.py +++ b/mautrix_telegram/__main__.py @@ -35,6 +35,7 @@ from .user import init as init_user, User from .bot import init as init_bot from .portal import init as init_portal from .puppet import init as init_puppet +from .formatter import init as init_formatter from .public import PublicBridgeWebsite from .context import Context @@ -99,6 +100,7 @@ with appserv.run(config["appservice.hostname"], config["appservice.port"]) as st init_abstract_user(context) context.bot = init_bot(context) context.mx = MatrixHandler(context) + init_formatter(context) init_portal(context) init_puppet(context) startup_actions = init_user(context) + [start, context.mx.init_as_bot()] diff --git a/mautrix_telegram/formatter/__init__.py b/mautrix_telegram/formatter/__init__.py index 0428e723..6252455a 100644 --- a/mautrix_telegram/formatter/__init__.py +++ b/mautrix_telegram/formatter/__init__.py @@ -1,2 +1,8 @@ -from .from_matrix import matrix_reply_to_telegram, matrix_to_telegram, matrix_text_to_telegram -from .from_telegram import telegram_reply_to_matrix, telegram_to_matrix +from .from_matrix import (matrix_reply_to_telegram, matrix_to_telegram, matrix_text_to_telegram, + init_mx) +from .from_telegram import (telegram_reply_to_matrix, telegram_to_matrix, init_tg) + + +def init(context): + init_mx(context) + init_tg(context) diff --git a/mautrix_telegram/formatter/from_matrix.py b/mautrix_telegram/formatter/from_matrix.py index b5b3576f..971e7a97 100644 --- a/mautrix_telegram/formatter/from_matrix.py +++ b/mautrix_telegram/formatter/from_matrix.py @@ -219,11 +219,46 @@ class MatrixParser(HTMLParser): command_regex = re.compile("(\s|^)!([A-Za-z0-9@]+)") +plain_mention_regex = None def matrix_text_to_telegram(text): text = command_regex.sub(r"\1/\2", text) - return text + entities, pmr_replacer = plain_mention_to_text() + text = plain_mention_regex.sub(pmr_replacer, text) + return text, entities + + +def plain_mention_to_text(): + entities = [] + + def replacer(match): + puppet = pu.Puppet.find_by_displayname(match.group(2)) + if puppet: + offset = match.start() + length = match.end() - offset + if puppet.username: + entity = MessageEntityMention(offset, length) + text = f"@{puppet.username}" + else: + entity = InputMessageEntityMentionName(offset, length, + user_id=InputUser(puppet.tgid, 0)) + text = puppet.displayname + entities.append(entity) + return text + return "".join(match.groups()) + + return entities, replacer + + +def plain_mention_to_html(match): + puppet = pu.Puppet.find_by_displayname(match.group(2)) + if puppet: + return (f"{match.group(1)}" + f"" + f"{puppet.displayname}" + "") + return "".join(match.groups()) def matrix_to_telegram(html): @@ -231,6 +266,7 @@ def matrix_to_telegram(html): parser = MatrixParser() html = html.replace("\n", "") html = command_regex.sub(r"\1\2", html) + html = plain_mention_regex.sub(plain_mention_to_html, html) parser.feed(add_surrogates(html)) return remove_surrogates(parser.text.strip()), parser.entities except Exception: @@ -258,3 +294,11 @@ def matrix_reply_to_telegram(content, tg_space, room_id=None): except KeyError: pass return None + + +def init_mx(context): + global plain_mention_regex + config = context.config + dn_template = config.get("bridge.displayname_template", "{displayname} (Telegram)") + dn_template = re.escape(dn_template).replace(re.escape("{displayname}"), "[^>]+") + plain_mention_regex = re.compile(f"(\s|^)({dn_template})") diff --git a/mautrix_telegram/formatter/from_telegram.py b/mautrix_telegram/formatter/from_telegram.py index 6dfbb1fe..7d4be35e 100644 --- a/mautrix_telegram/formatter/from_telegram.py +++ b/mautrix_telegram/formatter/from_telegram.py @@ -254,3 +254,7 @@ def _parse_url(html, entity_text, url): url = "http://" + url html.append(f"{entity_text}") return False + + +def init_tg(context): + pass diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index b6bd56e0..94153ff8 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -594,12 +594,9 @@ class Portal: for entity in entities: if isinstance(entity, InputMessageEntityMentionName): entity.user_id = await client.get_input_entity(entity.user_id.user_id) - - return await client.send_message(self.peer, message, entities=entities, - reply_to=reply_to) else: - message = formatter.matrix_text_to_telegram(message["body"]) - return await client.send_message(self.peer, message, reply_to=reply_to) + message, entities = formatter.matrix_text_to_telegram(message["body"]) + return await client.send_message(self.peer, message, reply_to=reply_to) async def _handle_matrix_file(self, client, message, reply_to): file = await self.main_intent.download_file(message["url"]) diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index 4340498a..782ad2a5 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -191,6 +191,21 @@ class Puppet: return None + @classmethod + def find_by_displayname(cls, displayname): + if not displayname: + return None + + for _, puppet in cls.cache.items(): + if puppet.displayname and puppet.displayname == displayname: + return puppet + + puppet = DBPuppet.query.filter(DBPuppet.displayname == displayname).one_or_none() + if puppet: + return cls.from_db(puppet) + + return None + def init(context): global config