From e1e9ba80fa97b64037fe136b924b8860ffcaf1d6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 11 Feb 2018 22:40:21 +0200 Subject: [PATCH 01/10] Add Python 3.5 compatibility --- mautrix_appservice/appservice.py | 1 + mautrix_appservice/errors.py | 1 + mautrix_appservice/intent_api.py | 1 + mautrix_appservice/state_store.py | 1 + mautrix_telegram/__main__.py | 1 + mautrix_telegram/commands.py | 1 + mautrix_telegram/config.py | 1 + mautrix_telegram/db.py | 1 + mautrix_telegram/formatter.py | 1 + mautrix_telegram/matrix.py | 1 + mautrix_telegram/portal.py | 9 ++++++--- mautrix_telegram/puppet.py | 1 + mautrix_telegram/tgclient.py | 1 + mautrix_telegram/user.py | 1 + requirements.txt | 3 ++- setup.py | 3 ++- 16 files changed, 23 insertions(+), 5 deletions(-) diff --git a/mautrix_appservice/appservice.py b/mautrix_appservice/appservice.py index 7d25c4d7..1d26fbb2 100644 --- a/mautrix_appservice/appservice.py +++ b/mautrix_appservice/appservice.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # matrix-appservice-python - A Matrix Application Service framework written in Python. # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_appservice/errors.py b/mautrix_appservice/errors.py index b0834283..8c09936f 100644 --- a/mautrix_appservice/errors.py +++ b/mautrix_appservice/errors.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_appservice/intent_api.py b/mautrix_appservice/intent_api.py index 395dfe32..d7916cbe 100644 --- a/mautrix_appservice/intent_api.py +++ b/mautrix_appservice/intent_api.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_appservice/state_store.py b/mautrix_appservice/state_store.py index 5ce32aa1..1174dcde 100644 --- a/mautrix_appservice/state_store.py +++ b/mautrix_appservice/state_store.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # matrix-appservice-python - A Matrix Application Service framework written in Python. # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/__main__.py b/mautrix_telegram/__main__.py index 8439dfb0..a5415f5d 100644 --- a/mautrix_telegram/__main__.py +++ b/mautrix_telegram/__main__.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/commands.py b/mautrix_telegram/commands.py index e9555b41..2046f3e4 100644 --- a/mautrix_telegram/commands.py +++ b/mautrix_telegram/commands.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py index 82817f73..f2f81426 100644 --- a/mautrix_telegram/config.py +++ b/mautrix_telegram/config.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/db.py b/mautrix_telegram/db.py index d993b02c..ec6da354 100644 --- a/mautrix_telegram/db.py +++ b/mautrix_telegram/db.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/formatter.py b/mautrix_telegram/formatter.py index ce4a4c7b..cb920284 100644 --- a/mautrix_telegram/formatter.py +++ b/mautrix_telegram/formatter.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/matrix.py b/mautrix_telegram/matrix.py index e631ff4f..6765a8b7 100644 --- a/mautrix_telegram/matrix.py +++ b/mautrix_telegram/matrix.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index b15ebb6d..6c8a6168 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # @@ -564,12 +565,14 @@ class Portal: elif self.tgid: raise ValueError("Can't create Telegram chat for portal with existing Telegram chat.") - invites = await self._get_telegram_users_in_matrix_room() - if len(invites) < 2: + invite_ids = await self._get_telegram_users_in_matrix_room() + if len(invite_ids) < 2: # TODO[waiting-for-bots] This won't happen when the bot is enabled raise ValueError("Not enough Telegram users to create a chat") - invites = [await source.client.get_input_entity(id) for id in invites] + invites = [] + for id in invite_ids: + invites.append(await source.client.get_input_entity(id)) if self.peer_type == "chat": updates = await source.client(CreateChatRequest(title=self.title, users=invites)) diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index 8df387b6..c3736994 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/tgclient.py b/mautrix_telegram/tgclient.py index 84b6728e..335d8adf 100644 --- a/mautrix_telegram/tgclient.py +++ b/mautrix_telegram/tgclient.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index ba37e1ae..ec0dd468 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -1,3 +1,4 @@ +# -*- coding: future_fstrings -*- # mautrix-telegram - A Matrix-Telegram puppeting bridge # Copyright (C) 2018 Tulir Asokan # diff --git a/requirements.txt b/requirements.txt index c7ee0ddf..d40b82f5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ ruamel.yaml python-magic SQLAlchemy alembic --e git+https://github.com/LonamiWebs/Telethon@asyncio#egg=Telethon +-e git+https://github.com/tulir/Telethon@asyncio-3.5#egg=Telethon Markdown Pillow +future-fstrings diff --git a/setup.py b/setup.py index d9df9d6d..b007c318 100644 --- a/setup.py +++ b/setup.py @@ -21,10 +21,11 @@ setuptools.setup( "Markdown>=2.6.11,<3", "ruamel.yaml>=0.15.35,<0.16", "Pillow>=5.0.0,<6", + "future-fstrings>=0.4.1", "python-magic>=0.4.15,<0.5", ], dependency_links=[ - "https://github.com/LonamiWebs/Telethon/tarball/7da092894b306d720cc60c04daa2bfba58f81946#egg=Telethon" + "https://github.com/tulir/Telethon/tarball/ac46abc9680c5a74897fe6dbe9e585ad2577b1fa#egg=Telethon" ], classifiers=[ From 44bad0bf2be689ac3682dd58cf3485497ee68b50 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 14 Feb 2018 23:47:36 +0200 Subject: [PATCH 02/10] Make Python 3.5 support mergeable to master --- requirements/3.5.txt | 2 ++ requirements.txt => requirements/base.txt | 1 - requirements/default.txt | 2 ++ setup.py | 6 +++++- 4 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 requirements/3.5.txt rename requirements.txt => requirements/base.txt (56%) create mode 100644 requirements/default.txt diff --git a/requirements/3.5.txt b/requirements/3.5.txt new file mode 100644 index 00000000..c9b2ce0c --- /dev/null +++ b/requirements/3.5.txt @@ -0,0 +1,2 @@ +-r base.txt +-e git+https://github.com/tulir/Telethon@asyncio-3.5#egg=Telethon diff --git a/requirements.txt b/requirements/base.txt similarity index 56% rename from requirements.txt rename to requirements/base.txt index d40b82f5..bfa7bdde 100644 --- a/requirements.txt +++ b/requirements/base.txt @@ -3,7 +3,6 @@ ruamel.yaml python-magic SQLAlchemy alembic --e git+https://github.com/tulir/Telethon@asyncio-3.5#egg=Telethon Markdown Pillow future-fstrings diff --git a/requirements/default.txt b/requirements/default.txt new file mode 100644 index 00000000..1158be21 --- /dev/null +++ b/requirements/default.txt @@ -0,0 +1,2 @@ +-r base.txt +-e git+https://github.com/LonamiWebs/Telethon@asyncio#egg=Telethon diff --git a/setup.py b/setup.py index b007c318..c43e5c3a 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ import setuptools +import sys import mautrix_telegram setuptools.setup( @@ -25,7 +26,10 @@ setuptools.setup( "python-magic>=0.4.15,<0.5", ], dependency_links=[ - "https://github.com/tulir/Telethon/tarball/ac46abc9680c5a74897fe6dbe9e585ad2577b1fa#egg=Telethon" + ( + "https://github.com/LonamiWebs/Telethon/tarball/7da092894b306d720cc60c04daa2bfba58f81946#egg=Telethon" + if sys.version_info.major > 3 or sys.version_info.minor > 6 + else "https://github.com/tulir/Telethon/tarball/ac46abc9680c5a74897fe6dbe9e585ad2577b1fa#egg=Telethon") ], classifiers=[ From 664a4f109528769f49cd93ad2f23abf834c11cd5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 14 Feb 2018 23:51:18 +0200 Subject: [PATCH 03/10] Fix Telethon dependency in setup.py for Python 3.6 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c43e5c3a..b219a252 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ setuptools.setup( dependency_links=[ ( "https://github.com/LonamiWebs/Telethon/tarball/7da092894b306d720cc60c04daa2bfba58f81946#egg=Telethon" - if sys.version_info.major > 3 or sys.version_info.minor > 6 + if sys.version_info.major > 3 or sys.version_info.minor > 5 else "https://github.com/tulir/Telethon/tarball/ac46abc9680c5a74897fe6dbe9e585ad2577b1fa#egg=Telethon") ], From 6615a68cee49e80b10f077e936f7f57a318480da Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Feb 2018 13:14:30 +0200 Subject: [PATCH 04/10] Remove unnecessary get_input_entity calls --- mautrix_telegram/portal.py | 8 +++----- mautrix_telegram/puppet.py | 3 --- mautrix_telegram/user.py | 3 --- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 68b3ad84..078d490d 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -441,14 +441,13 @@ class Portal: del self.by_tgid[self.tgid_full] del self.by_mxid[self.mxid] elif source and source.tgid != user.tgid: - target = await user.get_input_entity(source) if self.peer_type == "chat": - await source.client(DeleteChatUserRequest(chat_id=self.tgid, user_id=target)) + await source.client(DeleteChatUserRequest(chat_id=self.tgid, user_id=user.tgid)) else: channel = await self.get_input_entity(source) rights = ChannelBannedRights(datetime.fromtimestamp(0), True) await source.client(EditBannedRequest(channel=channel, - user_id=target, + user_id=user.tgid, banned_rights=rights)) elif self.peer_type == "chat": await user.client(DeleteChatUserRequest(chat_id=self.tgid, user_id=InputUserSelf())) @@ -664,8 +663,7 @@ class Portal: await source.client( AddChatUserRequest(chat_id=self.tgid, user_id=puppet.tgid, fwd_limit=0)) elif self.peer_type == "channel": - target = await puppet.get_input_entity(source) - await source.client(InviteToChannelRequest(channel=self.peer, users=[target])) + await source.client(InviteToChannelRequest(channel=self.peer, users=[puppet.tgid])) else: raise ValueError("Invalid peer type for Telegram user invite") diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index c3736994..ad09a7ec 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -51,9 +51,6 @@ class Puppet: def tgid(self): return self.id - def get_input_entity(self, user): - return user.client.get_input_entity(PeerUser(user_id=self.tgid)) - def to_db(self): return self.db.merge( DBPuppet(id=self.id, username=self.username, displayname=self.displayname, diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 98969a32..2ad4c183 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -99,9 +99,6 @@ class User: else: self.portals = {} - def get_input_entity(self, user): - return user.client.get_input_entity(InputUser(user_id=self.tgid, access_hash=0)) - # region Database conversion def to_db(self): From 44fea382317b59e87ce46b1d3b5fc435ae9cc56c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Feb 2018 14:01:14 +0200 Subject: [PATCH 05/10] Fix lint warnings and properly handle ShortMessages --- mautrix_telegram/formatter.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mautrix_telegram/formatter.py b/mautrix_telegram/formatter.py index 2faa1146..824dc96e 100644 --- a/mautrix_telegram/formatter.py +++ b/mautrix_telegram/formatter.py @@ -242,8 +242,9 @@ async def telegram_event_to_matrix(evt, source, native_replies=False, message_li + f"
{html}
") if evt.reply_to_msg_id: - space = evt.to_id.channel_id if isinstance(evt, Message) and isinstance(evt.to_id, - PeerChannel) else source.tgid + space = (evt.to_id.channel_id + if isinstance(evt, Message) and isinstance(evt.to_id, PeerChannel) + else source.tgid) msg = DBMessage.query.get((evt.reply_to_msg_id, space)) if msg: if native_replies: @@ -260,7 +261,7 @@ async def telegram_event_to_matrix(evt, source, native_replies=False, message_li sender = event['sender'] puppet = p.Puppet.get_by_mxid(sender, create=False) displayname = puppet.displayname if puppet else sender - reply_to_user = (f"{displayname}") + reply_to_user = f"{displayname}" reply_to_msg = (("{reply_text}") if message_link_in_reply else "Reply") @@ -272,7 +273,7 @@ async def telegram_event_to_matrix(evt, source, native_replies=False, message_li else: html = quote + escape(text) - if evt.post and evt.post_author: + if isinstance(evt, Message) and evt.post and evt.post_author: if not html: html = escape(text) text += f"\n- {evt.post_author}" From 25edade2a9bf5b66c075fcbbfcca0458e1251e28 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Feb 2018 20:38:02 +0200 Subject: [PATCH 06/10] Use tuple comparison syntax when checking which Telethon branch to install --- setup.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index b219a252..208c4f5f 100644 --- a/setup.py +++ b/setup.py @@ -26,10 +26,9 @@ setuptools.setup( "python-magic>=0.4.15,<0.5", ], dependency_links=[ - ( - "https://github.com/LonamiWebs/Telethon/tarball/7da092894b306d720cc60c04daa2bfba58f81946#egg=Telethon" - if sys.version_info.major > 3 or sys.version_info.minor > 5 - else "https://github.com/tulir/Telethon/tarball/ac46abc9680c5a74897fe6dbe9e585ad2577b1fa#egg=Telethon") + ("https://github.com/LonamiWebs/Telethon/tarball/7da092894b306d720cc60c04daa2bfba58f81946#egg=Telethon" + if sys.version_info > (3, 5) + else "https://github.com/tulir/Telethon/tarball/ac46abc9680c5a74897fe6dbe9e585ad2577b1fa#egg=Telethon") ], classifiers=[ From 0d8428fa70e5ae8663dcb5b8b9f082f4da3cb92c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Feb 2018 15:11:14 +0200 Subject: [PATCH 07/10] Fix edit handling --- mautrix_telegram/portal.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 078d490d..0e77c148 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -769,7 +769,7 @@ class Portal: await intent.set_typing(self.mxid, is_typing=False) return await intent.send_text(self.mxid, text, html=html) - async def handle_telegram_edit(self, source, intent, evt): + async def handle_telegram_edit(self, source, sender, evt): if not self.mxid: return elif not config["bridge.edits_as_replies"]: @@ -780,6 +780,7 @@ class Portal: config["bridge.native_replies"], config["bridge.link_in_reply"], self.main_intent, reply_text="Edit") + 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) From 14d4e5ea6ae1392a723cf674add02fb36ce3aa67 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Feb 2018 17:36:20 +0200 Subject: [PATCH 08/10] Add protocol to links if its missing. Fixes #69 --- mautrix_telegram/formatter.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mautrix_telegram/formatter.py b/mautrix_telegram/formatter.py index 824dc96e..21236b4f 100644 --- a/mautrix_telegram/formatter.py +++ b/mautrix_telegram/formatter.py @@ -353,10 +353,11 @@ def _telegram_to_matrix(text, entities): skip_entity = True elif entity_type == MessageEntityEmail: html.append(f"{entity_text}") - elif entity_type == MessageEntityUrl: - html.append(f"{entity_text}") - elif entity_type == MessageEntityTextUrl: - html.append(f"{entity_text}") + elif entity_type in {MessageEntityTextUrl, MessageEntityUrl}: + url = escape(entity.url) if entity_type == MessageEntityTextUrl else entity_text + if not url.startswith(("https://", "http://", "ftp://", "magnet://")): + url = "http://" + url + html.append(f"{entity_text}") elif entity_type == MessageEntityBotCommand: html.append(f"!{entity_text[1:]}") elif entity_type == MessageEntityHashtag: From c80738e63d07602bad712e3cd1360f410bebf9a6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Feb 2018 17:36:41 +0200 Subject: [PATCH 09/10] Fix logging in --- mautrix_telegram/user.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 2ad4c183..81025f05 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -140,14 +140,15 @@ class User: device_model=device) self.client.add_update_handler(self.update_catch) - async def start(self): + async def start(self, delete_unless_authenticated=False): self.connected = await self.client.connect() if self.logged_in: asyncio.ensure_future(self.post_login(), loop=self.loop) - else: + elif delete_unless_authenticated: # User not logged in -> forget user self.client.disconnect() self.client.session.delete() + self.delete() return self async def post_login(self, info=None): @@ -469,4 +470,4 @@ def init(context): User.az, User.db, config, User.loop = context users = [User.from_db(user) for user in DBUser.query.all()] - return [user.start() for user in users] + return [user.start(delete_unless_authenticated=True) for user in users] From 57e1a863dc57dae04aed829c61023c0b2da4523b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Feb 2018 17:36:50 +0200 Subject: [PATCH 10/10] Minor style fixes --- mautrix_telegram/portal.py | 4 ++-- mautrix_telegram/puppet.py | 2 -- mautrix_telegram/tgclient.py | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 0e77c148..fe0570bd 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -690,7 +690,7 @@ class Portal: name = media.caption await intent.set_typing(self.mxid, is_typing=False) return await intent.send_image(self.mxid, uploaded["content_uri"], info=info, - text=name) + text=name) def convert_webp(self, file, to="png"): try: @@ -733,7 +733,7 @@ class Portal: type = "m.image" await intent.set_typing(self.mxid, is_typing=False) return await intent.send_file(self.mxid, uploaded["content_uri"], info=info, - text=name, file_type=type) + text=name, file_type=type) def handle_telegram_location(self, source, intent, location): long = location.long diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index ad09a7ec..596bcd2e 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -69,8 +69,6 @@ class Puppet: if self.username else 0) displayname_similarity = (SequenceMatcher(None, self.displayname, query).ratio() if self.displayname else 0) - #phone_number_similarity = (SequenceMatcher(None, self.phone_number, query).ratio() - # if self.phone_number else 0) similarity = max(username_similarity, displayname_similarity) return round(similarity * 1000) / 10 diff --git a/mautrix_telegram/tgclient.py b/mautrix_telegram/tgclient.py index 335d8adf..696f91cc 100644 --- a/mautrix_telegram/tgclient.py +++ b/mautrix_telegram/tgclient.py @@ -46,8 +46,8 @@ class MautrixTelegramClient(TelegramClient): return self._get_response_message(request, result) - async def send_file(self, entity, file, mime_type=None, caption=None, attributes=None, file_name=None, - reply_to=None, **kwargs): + async def send_file(self, entity, file, mime_type=None, caption=None, attributes=None, + file_name=None, reply_to=None, **kwargs): entity = await self.get_input_entity(entity) reply_to = self._get_reply_to(reply_to)