# -*- coding: future_fstrings -*-
# mautrix-telegram - A Matrix-Telegram puppeting bridge
# Copyright (C) 2018 Tulir Asokan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see
"
f"
{html}") 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
{r_msg_link} {r_sender_link}\n{r_html_body}" + (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, main_intent=None, is_edit=False, prefix_text=None, prefix_html=None): text = add_surrogates(evt.message) html = _telegram_entities_to_matrix_catch(text, evt.entities) if evt.entities else None relates_to = {} if prefix_html: html = prefix_html + (html or escape(text)) if prefix_text: text = prefix_text + text if evt.fwd_from: 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, main_intent, is_edit) if isinstance(evt, Message) and evt.post and evt.post_author: if not html: html = escape(text) text += f"\n- {evt.post_author}" html += f"
{entity_text}")
elif entity_type == MessageEntityPre:
skip_entity = _parse_pre(html, entity_text, entity.language)
elif entity_type == MessageEntityMention:
skip_entity = _parse_mention(html, entity_text)
elif entity_type == MessageEntityMentionName:
skip_entity = _parse_name_mention(html, entity_text, entity.user_id)
elif entity_type == MessageEntityEmail:
html.append(f"{entity_text}")
elif entity_type in {MessageEntityTextUrl, MessageEntityUrl}:
skip_entity = _parse_url(html, entity_text,
entity.url if entity_type == MessageEntityTextUrl else None)
elif entity_type == MessageEntityBotCommand:
html.append(f"!{entity_text[1:]}")
elif entity_type == MessageEntityHashtag:
html.append(f"{entity_text}")
else:
skip_entity = True
last_offset = entity.offset + (0 if skip_entity else entity.length)
html.append(text[last_offset:])
return "".join(html)
def _parse_pre(html, entity_text, language):
if language:
html.append(""
f"{entity_text}"
"")
else:
html.append(f"{entity_text}")
return False
def _parse_mention(html, entity_text):
username = entity_text[1:]
user = u.User.find_by_username(username) or pu.Puppet.find_by_username(username)
if user:
mxid = user.mxid
else:
portal = po.Portal.find_by_username(username)
mxid = portal.alias or portal.mxid if portal else None
if mxid:
html.append(f"{entity_text}")
else:
return True
return False
def _parse_name_mention(html, entity_text, user_id):
user = u.User.get_by_tgid(user_id)
if user:
mxid = user.mxid
else:
puppet = pu.Puppet.get(user_id, create=False)
mxid = puppet.mxid if puppet else None
if mxid:
html.append(f"{entity_text}")
else:
return True
return False
def _parse_url(html, entity_text, url):
url = escape(url) if url else entity_text
if not url.startswith(("https://", "http://", "ftp://", "magnet://")):
url = "http://" + url
html.append(f"{entity_text}")
return False
def init_tg(context):
global should_highlight_edits
should_highlight_edits = htmldiff and context.config["bridge.highlight_edits"]