Use native reply fallback format. Fixes #86

This commit is contained in:
Tulir Asokan
2018-03-06 21:14:37 +02:00
parent fe00145d1c
commit 97957a5731
5 changed files with 80 additions and 57 deletions
-6
View File
@@ -70,12 +70,6 @@ bridge:
- username
- phone number
# Whether or not to use native Matrix replies. At the time of writing, only riot-web supports
# replies and the format of them is subject to change.
native_replies: true
# If native replies are disabled, should the custom replies contain a link to the message being
# replied to?
link_in_reply: false
# Show message editing as a reply to the original message.
# If this is false, message edits are not shown at all, as Matrix does not support editing yet.
edits_as_replies: false
+9 -1
View File
@@ -25,7 +25,7 @@ from telethon_aio.tl.types import *
from .. import user as u, puppet as pu, portal as po
from ..db import Message as DBMessage
from .util import add_surrogates, remove_surrogates
from .util import (add_surrogates, remove_surrogates, trim_reply_fallback_html, trim_reply_fallback_text)
log = logging.getLogger("mau.fmt.mx")
@@ -232,6 +232,14 @@ def matrix_reply_to_telegram(content, tg_space, room_id=None):
reply = content["m.relates_to"]["m.in_reply_to"]
room_id = room_id or reply["room_id"]
event_id = reply["event_id"]
try:
if content["format"] == "org.custom.matrix.html":
content["formatted_body"] = trim_reply_fallback_html(content["formatted_body"])
except KeyError:
pass
content["body"] = trim_reply_fallback_text(content["body"])
message = DBMessage.query.filter(DBMessage.mxid == event_id,
DBMessage.tg_space == tg_space,
DBMessage.mx_room == room_id).one_or_none()
+42 -34
View File
@@ -22,7 +22,8 @@ from mautrix_appservice import MatrixRequestError
from .. import user as u, puppet as pu, portal as po
from ..db import Message as DBMessage
from .util import add_surrogates, remove_surrogates
from .util import (add_surrogates, remove_surrogates, trim_reply_fallback_html,
trim_reply_fallback_text)
log = logging.getLogger("mau.fmt.tg")
@@ -67,8 +68,7 @@ async def _add_forward_header(source, text, html, fwd_from_id):
return text, html
async def _add_reply_header(source, text, html, evt, relates_to,
native_replies, message_link_in_reply, main_intent, reply_text):
async def _add_reply_header(source, text, html, evt, relates_to, main_intent, is_edit):
space = (evt.to_id.channel_id
if isinstance(evt, Message) and isinstance(evt.to_id, PeerChannel)
else source.tgid)
@@ -77,42 +77,50 @@ async def _add_reply_header(source, text, html, evt, relates_to,
if not msg:
return text, html
if native_replies:
relates_to["m.in_reply_to"] = {
"event_id": msg.mxid,
"room_id": msg.mx_room,
}
if reply_text == "Edit":
html = f"<u>Edit:</u> {html or escape(text)}"
text = f"Edit: {text}"
return text, html
relates_to["m.in_reply_to"] = {
"event_id": msg.mxid,
"room_id": msg.mx_room,
}
if is_edit:
html = f"<u>Edit:</u> {html or escape(text)}"
text = f"Edit: {text}"
reply_displayname = "unknown user"
try:
event = await main_intent.get_event(msg.mx_room, msg.mxid)
content = event["content"]
body = (content["formatted_body"]
if "formatted_body" in content
else escape(content["body"]))
sender = event['sender']
puppet = pu.Puppet.get_by_mxid(sender, create=False)
reply_displayname = puppet.displayname if puppet else sender
reply_to_user = f"<a href='https://matrix.to/#/{sender}'>{reply_displayname}</a>"
reply_to_msg = (("<a href='https://matrix.to/#/"
f"{msg.mx_room}/{msg.mxid}'>{reply_text}</a>")
if message_link_in_reply else "Reply")
quote = f"{reply_to_msg} to {reply_to_user}<blockquote>{body}</blockquote>"
r_sender = event["sender"]
r_text_body = trim_reply_fallback_text(content["body"])
r_html_body = trim_reply_fallback_html(content["formatted_body"]
if "formatted_body" in content
else escape(content["body"]))
puppet = pu.Puppet.get_by_mxid(r_sender, create=False)
r_displayname = puppet.displayname if puppet else r_sender
r_sender_link = f"<a href='https://matrix.to/#/{r_sender}'>{r_displayname}</a>"
except (ValueError, KeyError, MatrixRequestError):
quote = f"{reply_text} to unknown user <em>(Failed to fetch message)</em>:<br/>"
if not html:
html = escape(text)
html = quote + html
text = f"{reply_text} to {reply_displayname}:\n{text}"
return text, html
r_sender_link = "unknown user"
# r_sender = "unknown user"
r_text_body = "Failed to fetch message"
r_html_body = "<em>Failed to fetch message</em>"
r_keyword = "In reply to" if not is_edit else "Edit to"
r_msg_link = f"<a href='https://matrix.to/#/{msg.mx_room}/{msg.mxid}'>{r_keyword}</a>"
html = (f"<blockquote data-mx-reply>{r_msg_link} {r_sender_link} {r_html_body}</blockquote>"
+ (html or escape(text)))
lines = r_text_body.strip().split("\n")
text_with_quote = f"> <{r_displayname}> {lines.pop(0)}"
for line in lines:
if line:
text_with_quote += f"\n> {line}"
text_with_quote += "\n\n"
text_with_quote += text
return text_with_quote, html
async def telegram_to_matrix(evt, source, native_replies=False, message_link_in_reply=False,
main_intent=None, reply_text="Reply"):
async def telegram_to_matrix(evt, source, main_intent=None, is_edit=False):
text = add_surrogates(evt.message)
html = _telegram_entities_to_matrix_catch(text, evt.entities) if evt.entities else None
relates_to = {}
@@ -121,8 +129,8 @@ async def telegram_to_matrix(evt, source, native_replies=False, message_link_in_
text, html = await _add_forward_header(source, text, html, evt.fwd_from.from_id)
if evt.reply_to_msg_id:
text, html = await _add_reply_header(source, text, html, evt, relates_to, native_replies,
message_link_in_reply, main_intent, reply_text)
text, html = await _add_reply_header(source, text, html, evt, relates_to, main_intent,
is_edit)
if isinstance(evt, Message) and evt.post and evt.post_author:
if not html:
+19 -2
View File
@@ -1,8 +1,9 @@
# Unicode surrogate handling
# From https://github.com/LonamiWebs/Telethon/blob/master/telethon/extensions/markdown.py
import struct
import re
# Unicode surrogate handling from
# https://github.com/LonamiWebs/Telethon/blob/master/telethon/extensions/markdown.py
def add_surrogates(text):
if text is None:
return None
@@ -14,3 +15,19 @@ def remove_surrogates(text):
if text is None:
return None
return text.encode("utf-16", "surrogatepass").decode("utf-16")
def trim_reply_fallback_text(text):
if not text.startswith("> ") or "\n" not in text:
return text
lines = text.split("\n")
while len(lines) > 0 and lines[0].startswith("> "):
lines.pop(0)
return "\n".join(lines)
HTML_REPLY_FALLBACK_REGEX = re.compile(r"^<blockquote data-mx-reply>[\s\S]+?</blockquote>")
def trim_reply_fallback_html(html):
return HTML_REPLY_FALLBACK_REGEX.sub("", html)
+10 -14
View File
@@ -33,6 +33,7 @@ from mautrix_appservice import MatrixRequestError, IntentError
from .db import Portal as DBPortal, Message as DBMessage
from . import puppet as p, user as u, formatter, util
from .formatter.util import trim_reply_fallback_html, trim_reply_fallback_text
mimetypes.init()
@@ -575,9 +576,10 @@ class Portal:
message["msgtype"] = "m.text"
elif not sender.logged_in:
if "formatted_body" in message:
message["formatted_body"] = (f"&lt;{sender.displayname}&gt; "
f"{message['formatted_body']}")
message["body"] = f"<{sender.displayname}> {message['body']}"
html = message["formatted_body"]
message["formatted_body"] = f"&lt;{sender.displayname}&gt; {html}"
text = message["body"]
message["body"] = f"<{sender.displayname}> {text}"
return type
async def _handle_matrix_text(self, client, message, reply_to):
@@ -592,7 +594,8 @@ class Portal:
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)
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)
@@ -922,11 +925,7 @@ class Portal:
async def handle_telegram_text(self, source, intent, evt):
self.log.debug(f"Sending {evt.message} to {self.mxid} by {intent.mxid}")
text, html, relates_to = await formatter.telegram_to_matrix(
evt, source,
config["bridge.native_replies"],
config["bridge.link_in_reply"],
self.main_intent)
text, html, relates_to = await formatter.telegram_to_matrix(evt, source, self.main_intent)
await intent.set_typing(self.mxid, is_typing=False)
return await intent.send_text(self.mxid, text, html=html, relates_to=relates_to)
@@ -950,11 +949,8 @@ class Portal:
return
evt.reply_to_msg_id = evt.id
text, html, relates_to = await formatter.telegram_to_matrix(
evt, source,
config["bridge.native_replies"],
config["bridge.link_in_reply"],
self.main_intent, reply_text="Edit")
text, html, relates_to = await formatter.telegram_to_matrix(evt, source, self.main_intent,
is_edit=True)
intent = sender.intent if sender else self.main_intent
await intent.set_typing(self.mxid, is_typing=False)
response = await intent.send_text(self.mxid, text, html=html, relates_to=relates_to)