From b3082da99973d4a8d51f7334e9cc55409a3bfbee Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 8 Mar 2018 19:44:53 +0200 Subject: [PATCH] Add option to underline edited part of message in edits. Fixes #61 --- example-config.yaml | 2 ++ mautrix_telegram/formatter/from_telegram.py | 34 ++++++++++++++++++--- requirements/optional.txt | 1 + setup.py | 3 ++ 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 requirements/optional.txt diff --git a/example-config.yaml b/example-config.yaml index f2a96e96..59ffaa3b 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -74,6 +74,8 @@ bridge: # 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 + # Highlight changed/added parts in edits. Requires lxml. + highlight_edits: false # Whether or not Matrix bot messages (type m.notice) should be bridged. bridge_notices: false # The maximum number of simultaneous Telegram deletions to handle. diff --git a/mautrix_telegram/formatter/from_telegram.py b/mautrix_telegram/formatter/from_telegram.py index 7d4be35e..576f51be 100644 --- a/mautrix_telegram/formatter/from_telegram.py +++ b/mautrix_telegram/formatter/from_telegram.py @@ -15,7 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . from html import escape +try: + from lxml.html.diff import htmldiff +except ImportError: + htmldiff = None import logging +import re from telethon_aio.tl.types import * from mautrix_appservice import MatrixRequestError @@ -26,6 +31,7 @@ from .util import (add_surrogates, remove_surrogates, trim_reply_fallback_html, trim_reply_fallback_text, unicode_to_html) log = logging.getLogger("mau.fmt.tg") +should_highlight_edits = False def telegram_reply_to_matrix(evt, source): @@ -68,6 +74,21 @@ async def _add_forward_header(source, text, html, fwd_from_id): return text, html +def highlight_edits(new_html, old_html): + # Don't include `Edit:` text in diff. + if old_html.startswith("Edit: "): + old_html = old_html[len("Edit: "):] + + # Generate diff with lxml + new_html = htmldiff(old_html, new_html) + + # Replace with since Riot doesn't allow + new_html = new_html.replace("", "").replace("", "") + # Remove s since we just want to hide deletions. + new_html = re.sub(".+?", "", new_html) + return new_html + + 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) @@ -81,9 +102,6 @@ async def _add_reply_header(source, text, html, evt, relates_to, main_intent, is "event_id": msg.mxid, "room_id": msg.mx_room, } - if is_edit: - html = f"Edit: {html or escape(text)}" - text = f"Edit: {text}" try: event = await main_intent.get_event(msg.mx_room, msg.mxid) @@ -99,12 +117,19 @@ async def _add_reply_header(source, text, html, evt, relates_to, main_intent, is puppet = pu.Puppet.get_by_mxid(r_sender, create=False) r_displayname = puppet.displayname if puppet else r_sender r_sender_link = f"{r_displayname}" + + if is_edit and should_highlight_edits: + html = highlight_edits(html or escape(text), r_html_body) except (ValueError, KeyError, MatrixRequestError): r_sender_link = "unknown user" # r_sender = "unknown user" r_text_body = "Failed to fetch message" r_html_body = "Failed to fetch message" + if is_edit: + html = f"Edit: {html or escape(text)}" + text = f"Edit: {text}" + r_keyword = "In reply to" if not is_edit else "Edit to" r_msg_link = f"{r_keyword}" html = (f"
{r_msg_link} {r_sender_link} {r_html_body}
" @@ -257,4 +282,5 @@ def _parse_url(html, entity_text, url): def init_tg(context): - pass + global should_highlight_edits + should_highlight_edits = htmldiff and context.config["bridge.highlight_edits"] diff --git a/requirements/optional.txt b/requirements/optional.txt new file mode 100644 index 00000000..ab90481d --- /dev/null +++ b/requirements/optional.txt @@ -0,0 +1 @@ +lxml diff --git a/setup.py b/setup.py index dbc732ed..eabecf3d 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,9 @@ setuptools.setup( dependency_links=[ "https://github.com/tulir/telethon-asyncio/tarball/9b389cfb4b6d3876e9661c23507f17e96897e4b0#egg=telethon-aio-git-0.18.0+1" ], + extras_require={ + "highlight_edits": ["lxml>=4.1.1,<5"], + }, classifiers=[ "Development Status :: 4 Beta",