From 30768d0a0674e3196d10d04a598238b2033df523 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Mar 2018 21:16:09 +0200 Subject: [PATCH] Add option to use inline images for better captions. Fixes #83 --- example-config.yaml | 5 +++- mautrix_telegram/config.py | 52 ++++++++++++++++++++++++++++++-------- mautrix_telegram/portal.py | 10 ++++++++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/example-config.yaml b/example-config.yaml index 9a601c8f..f1b72855 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -83,6 +83,9 @@ bridge: allow_matrix_login: true # Whether or not to allow creating portals from Telegram. authless_relaybot_portals: true + # Use inline images instead of m.image to make rich captions possible. + # N.B. Inline images are not supported on all clients (e.g. Riot iOS). + inline_images: false # The prefix for commands. Only required in non-management rooms. command_prefix: "!tg" @@ -112,4 +115,4 @@ telegram: # The version of the config. The bridge will read this and automatically update the config if # the schema has changed. For the latest version, check the example config. -version: 1 +version: 2 diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py index 7bab5563..b7bcf8bc 100644 --- a/mautrix_telegram/config.py +++ b/mautrix_telegram/config.py @@ -16,6 +16,8 @@ # along with this program. If not, see . from ruamel.yaml import YAML from ruamel.yaml.comments import CommentedMap +from ruamel.yaml.tokens import CommentToken +from ruamel.yaml.error import CommentMark import random import string @@ -42,6 +44,9 @@ class DictWithRecursion: def __getitem__(self, key): return self.get(key, None) + def __contains__(self, key): + return self[key] is not None + def _recursive_set(self, data, key, value): if '.' in key: key, next_key = key.split('.', 1) @@ -71,6 +76,7 @@ class DictWithRecursion: return try: del data[key] + del data.ca.items[key] except KeyError: pass @@ -80,6 +86,7 @@ class DictWithRecursion: return try: del self._data[key] + del self._data.ca.items[key] except KeyError: pass @@ -93,10 +100,19 @@ class DictWithRecursion: except ValueError: path = None entry = self[path] if path else self._data - c = self._data.ca.items.setdefault(key, [None, [], None, None]) + c = entry.ca.items.setdefault(key, [None, [], None, None]) c[1] = [] entry.yaml_set_comment_before_after_key(key=key, before=message, indent=indent) + def comment_newline(self, key): + try: + path, key = key.rsplit(".", 1) + except ValueError: + path = None + entry = self[path] if path else self._data + c = entry.ca.items.setdefault(key, [None, [], None, None]) + c[2] = CommentToken("\n\n", CommentMark(0), None) + class Config(DictWithRecursion): def __init__(self, path, registration_path): @@ -131,10 +147,10 @@ class Config(DictWithRecursion): del self["bridge.whitelist"] del self["bridge.admins"] - self["bridge.authless_relaybot_portals"] = self.get("bridge.authless_relaybot_portals", - True) - self.comment("bridge.authless_relaybot_portals", - "Whether or not to allow creating portals from Telegram.") + if "bridge.authless_relaybot_portals" not in self: + self["bridge.authless_relaybot_portals"] = True + self.comment("bridge.authless_relaybot_portals", + "Whether or not to allow creating portals from Telegram.") self.comment("bridge.permissions", "\n".join(( "", @@ -156,13 +172,29 @@ class Config(DictWithRecursion): "\nThe version of the config. The bridge will read this and automatically " "update the config if\nthe schema has changed. For the latest version, " "check the example config.") + return self["version"] + + def update_1_2(self): + del self["bridge.link_in_reply"] + del self["bridge.native_replies"] + if "bridge.inline_images" not in self: + self["bridge.inline_images"] = False + self.comment("bridge.inline_images", + "Use inline images instead of m.image to make rich captions possible.\n" + "N.B. Inline images are not supported on all clients (e.g. Riot iOS).") + self.comment_newline("bridge.inline_images") + self["version"] = 2 + return self["version"] def check_updates(self): - if self.get("version", 0) == 0: - self.update_0_1() - else: - return - self.save() + version = self.get("version", 0) + new_version = version + if version < 1: + new_version = self.update_0_1() + if version < 2: + new_version = self.update_1_2() + if new_version != version: + self.save() def _get_permissions(self, key): level = self["bridge.permissions"].get(key, "") diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 1de1f907..01055ab6 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -16,6 +16,7 @@ # along with this program. If not, see . from collections import deque from datetime import datetime +from html import escape import asyncio import random import mimetypes @@ -838,6 +839,15 @@ class Portal: largest_size.location) if not file: return None + if config["bridge.inline_images"] and evt.message: + text, html, relates_to = await formatter.telegram_to_matrix(evt, source, + self.main_intent) + await intent.set_typing(self.mxid, is_typing=False) + print(self.main_intent.client.get_download_url(file.mxc)) + inline_img = f"Inline Telegram photo
\n" + html = inline_img + (html or escape(text)) + text = f"Inline image: {text}" + return await intent.send_text(self.mxid, text, html=html, relates_to=relates_to) info = { "h": largest_size.h, "w": largest_size.w,