From 232ec6ee42615cb58f0a7dff4aed277a3947bdae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 22 Feb 2018 19:21:29 +0200 Subject: [PATCH] Add room pill bridging. Fixes #62 --- mautrix_appservice/intent_api.py | 2 +- mautrix_telegram/formatter/from_matrix.py | 16 ++++++++--- mautrix_telegram/portal.py | 34 +++++++++++++++++++++-- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/mautrix_appservice/intent_api.py b/mautrix_appservice/intent_api.py index f011f3c0..fa148b2e 100644 --- a/mautrix_appservice/intent_api.py +++ b/mautrix_appservice/intent_api.py @@ -168,7 +168,7 @@ class IntentAPI: self.mxid = mxid self.log = log - results = self.mxid_regex.search(mxid) + results = self.mxid_regex.match(mxid) if not results: raise ValueError("invalid MXID") self.localpart = results.group(1) diff --git a/mautrix_telegram/formatter/from_matrix.py b/mautrix_telegram/formatter/from_matrix.py index dfbe490b..ab543523 100644 --- a/mautrix_telegram/formatter/from_matrix.py +++ b/mautrix_telegram/formatter/from_matrix.py @@ -22,7 +22,7 @@ import logging from telethon.tl.types import * -from .. import user as u, puppet as p +from .. import user as u, puppet as pu, portal as po from ..db import Message as DBMessage from .util import add_surrogates, remove_surrogates @@ -30,7 +30,8 @@ log = logging.getLogger("mau.fmt.mx") class MatrixParser(HTMLParser): - mention_regex = re.compile("https://matrix.to/#/(@.+)") + mention_regex = re.compile("https://matrix.to/#/(@.+:.+)") + room_regex = re.compile("https://matrix.to/#/(#.+:.+)") def __init__(self): super().__init__() @@ -69,10 +70,11 @@ class MatrixParser(HTMLParser): url = attrs["href"] except KeyError: return - mention = self.mention_regex.search(url) + mention = self.mention_regex.match(url) + room = self.room_regex.match(url) if mention: mxid = mention.group(1) - user = p.Puppet.get_by_mxid(mxid, create=False) + user = pu.Puppet.get_by_mxid(mxid, create=False) if not user: user = u.User.get_by_mxid(mxid, create=False) if not user: @@ -83,6 +85,12 @@ class MatrixParser(HTMLParser): else: entity_type = MessageEntityMentionName args["user_id"] = user.tgid + elif room: + username = po.Portal.get_username_from_mx_alias(room.group(1)) + portal = po.Portal.find_by_username(username) + if portal and portal.username: + url = f"@{portal.username}" + entity_type = MessageEntityMention elif url.startswith("mailto:"): url = url[len("mailto:"):] entity_type = MessageEntityEmail diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index ed14c20a..949b929a 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -21,6 +21,7 @@ import random import mimetypes import hashlib import logging +import re import magic @@ -44,6 +45,9 @@ class Portal: az = None bot = None bridge_notices = False + mx_alias_regex = None + hs_domain = None + mxid_regex = None by_mxid = {} by_tgid = {} @@ -278,9 +282,7 @@ class Portal: return levels def _get_room_alias(self, username=None): - username = username or self.username - return config.get("bridge.alias_template", "telegram_{groupname}").format( - groupname=username) + return self.alias_template.format(groupname=username or self.username) async def sync_telegram_users(self, source, users): allowed_tgids = set() @@ -1110,6 +1112,28 @@ class Portal: return None + @classmethod + def get_username_from_mx_alias(cls, alias): + match = cls.mx_alias_regex.match(alias) + if match: + return match.group(1) + return None + + @classmethod + def find_by_username(cls, username): + if not username: + return None + + for _, portal in cls.by_tgid.items(): + if portal.username == username: + return portal + + portal = DBPortal.query.filter(DBPortal.username == username).one_or_none() + if portal: + return cls.from_db(portal) + + return None + @classmethod def get_by_tgid(cls, tgid, tg_receiver=None, peer_type=None): tg_receiver = tg_receiver or tgid @@ -1163,3 +1187,7 @@ def init(context): global config Portal.az, Portal.db, config, _, Portal.bot = context Portal.bridge_notices = config["bridge.bridge_notices"] + Portal.alias_template = config.get("bridge.alias_template", "telegram_{groupname}") + Portal.hs_domain = config["homeserver"]["domain"] + localpart = Portal.alias_template.format(groupname="(.+)") + Portal.mx_alias_regex = re.compile(f"#{localpart}:{Portal.hs_domain}")