Fix message ID mapping for channels. Fixes #51

This commit is contained in:
Tulir Asokan
2018-02-06 14:05:53 +02:00
parent 72b8a25cec
commit 9145ebdc64
4 changed files with 22 additions and 15 deletions
+2 -2
View File
@@ -44,9 +44,9 @@ class Message(Base):
mxid = Column(String) mxid = Column(String)
mx_room = Column(String) mx_room = Column(String)
tgid = Column(Integer, primary_key=True) tgid = Column(Integer, primary_key=True)
user = Column(Integer, ForeignKey("user.tgid"), primary_key=True) tg_space = Column(Integer, primary_key=True)
__table_args__ = (UniqueConstraint('mxid', 'mx_room', 'user', name='_mx_id_room'),) __table_args__ = (UniqueConstraint('mxid', 'mx_room', 'tg_space', name='_mx_id_room'),)
class User(Base): class User(Base):
+7 -6
View File
@@ -37,9 +37,9 @@ class MatrixParser(HTMLParser):
mention_regex = re.compile("https://matrix.to/#/(@.+)") mention_regex = re.compile("https://matrix.to/#/(@.+)")
reply_regex = re.compile(r"https://matrix.to/#/(!.+?)/(\$.+)") reply_regex = re.compile(r"https://matrix.to/#/(!.+?)/(\$.+)")
def __init__(self, user_id=None): def __init__(self, tg_space=None):
super().__init__() super().__init__()
self._user_id = user_id self._tg_space = tg_space
self.text = "" self.text = ""
self.entities = [] self.entities = []
self._building_entities = {} self._building_entities = {}
@@ -91,13 +91,14 @@ class MatrixParser(HTMLParser):
else: else:
entity_type = MessageEntityMentionName entity_type = MessageEntityMentionName
args["user_id"] = user.tgid args["user_id"] = user.tgid
elif reply and self._user_id and (len(self.entities) == 0 elif reply and self._tg_space and (len(self.entities) == 0
and len(self._building_entities) == 0): and len(self._building_entities) == 0):
room_id = reply.group(1) room_id = reply.group(1)
message_id = reply.group(2) message_id = reply.group(2)
message = DBMessage.query.filter(DBMessage.mxid == message_id message = DBMessage.query.filter(DBMessage.mxid == message_id
and DBMessage.mx_room == room_id and DBMessage.mx_room == room_id
and DBMessage.user == self._user_id).one_or_none() and DBMessage.tg_space == self._tg_space
).one_or_none()
if not message: if not message:
return return
entity_type = MessageEntityReply entity_type = MessageEntityReply
@@ -178,9 +179,9 @@ class MatrixParser(HTMLParser):
self.entities.append(entity) self.entities.append(entity)
def matrix_to_telegram(html, user_id=None): def matrix_to_telegram(html, tg_space=None):
try: try:
parser = MatrixParser(user_id) parser = MatrixParser(tg_space)
parser.feed(html) parser.feed(html)
return parser.text, parser.entities return parser.text, parser.entities
except Exception: except Exception:
+12 -7
View File
@@ -379,8 +379,8 @@ class Portal:
type = message["msgtype"] type = message["msgtype"]
if type in {"m.text", "m.emote"}: if type in {"m.text", "m.emote"}:
if "format" in message and message["format"] == "org.matrix.custom.html": if "format" in message and message["format"] == "org.matrix.custom.html":
message, entities = formatter.matrix_to_telegram(message["formatted_body"], space = self.tgid if self.peer_type == "channel" else sender.tgid
sender.tgid) message, entities = formatter.matrix_to_telegram(message["formatted_body"], space)
if type == "m.emote": if type == "m.emote":
message = "/me " + message message = "/me " + message
reply_to = None reply_to = None
@@ -410,13 +410,17 @@ class Portal:
self.log.debug("Unhandled Matrix event: %s", message) self.log.debug("Unhandled Matrix event: %s", message)
return return
self.is_duplicate(response) self.is_duplicate(response)
self.db.add( self.db.add(DBMessage(
DBMessage(tgid=response.id, mx_room=self.mxid, mxid=event_id, user=sender.tgid)) tgid=response.id,
tg_space=self.tgid if self.peer_type == "channel" else sender.tgid,
mx_room=self.mxid,
mxid=event_id))
self.db.commit() self.db.commit()
def handle_matrix_deletion(self, deleter, event_id): def handle_matrix_deletion(self, deleter, event_id):
space = self.tgid if self.peer_type == "channel" else deleter.tgid
message = DBMessage.query.filter(DBMessage.mxid == event_id and message = DBMessage.query.filter(DBMessage.mxid == event_id and
DBMessage.user == deleter.tgid and DBMessage.tg_space == space and
DBMessage.mx_room == self.mxid).one_or_none() DBMessage.mx_room == self.mxid).one_or_none()
if not message: if not message:
return return
@@ -696,7 +700,7 @@ class Portal:
return return
self.db.add(DBMessage(tgid=evt.id, mx_room=self.mxid, mxid=response["event_id"], self.db.add(DBMessage(tgid=evt.id, mx_room=self.mxid, mxid=response["event_id"],
user=source.tgid)) tg_space=self.tgid if self.peer_type == "channel" else source.tgid))
self.db.commit() self.db.commit()
def handle_telegram_action(self, source, sender, action): def handle_telegram_action(self, source, sender, action):
@@ -742,7 +746,8 @@ class Portal:
self.main_intent.set_power_levels(self.mxid, levels) self.main_intent.set_power_levels(self.mxid, levels)
def update_telegram_pin(self, source, id): def update_telegram_pin(self, source, id):
message = DBMessage.query.get((id, source.tgid)) space = self.tgid if self.peer_type == "channel" else source.tgid
message = DBMessage.query.get((id, space))
if message: if message:
self.main_intent.set_pinned_messages(self.mxid, [message.mxid]) self.main_intent.set_pinned_messages(self.mxid, [message.mxid])
else: else:
+1
View File
@@ -177,6 +177,7 @@ class User:
if not portal or not portal.mxid: if not portal or not portal.mxid:
return return
# We check that these are user read receipts, so tg_space is always the user ID.
message = DBMessage.query.get((update.max_id, self.tgid)) message = DBMessage.query.get((update.max_id, self.tgid))
if not message: if not message:
return return