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 0b6f78ee..0fd002e0 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/auth.py b/mautrix_telegram/commands/auth.py index ceaeeca5..6c114785 100644 --- a/mautrix_telegram/commands/auth.py +++ b/mautrix_telegram/commands/auth.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/clean_rooms.py b/mautrix_telegram/commands/clean_rooms.py index 23ee4bf9..96a2154c 100644 --- a/mautrix_telegram/commands/clean_rooms.py +++ b/mautrix_telegram/commands/clean_rooms.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/handler.py b/mautrix_telegram/commands/handler.py index 030298d4..0e06e3a4 100644 --- a/mautrix_telegram/commands/handler.py +++ b/mautrix_telegram/commands/handler.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/meta.py b/mautrix_telegram/commands/meta.py index 2fb310f7..6ffff94f 100644 --- a/mautrix_telegram/commands/meta.py +++ b/mautrix_telegram/commands/meta.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/telegram.py b/mautrix_telegram/commands/telegram.py index ea5d6950..f77c2110 100644 --- a/mautrix_telegram/commands/telegram.py +++ b/mautrix_telegram/commands/telegram.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 0b6341d8..b8a4b372 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 45ce3cf3..9590b5ec 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 # @@ -268,7 +269,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") @@ -280,7 +281,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}" @@ -360,10 +361,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: diff --git a/mautrix_telegram/matrix.py b/mautrix_telegram/matrix.py index cbca6d09..f5f36adf 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 798f831b..6cba45b7 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 # @@ -440,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())) @@ -661,8 +661,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") @@ -689,7 +688,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, relates_to=relates_to) + text=name, relates_to=relates_to) def convert_webp(self, file, to="png"): try: @@ -732,7 +731,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, relates_to=relates_to) + text=name, file_type=type, relates_to=relates_to) def handle_telegram_location(self, source, intent, location, relates_to=None): long = location.long @@ -770,7 +769,7 @@ class Portal: await intent.set_typing(self.mxid, is_typing=False) return await intent.send_text(self.mxid, text, html=html, relates_to=relates_to) - 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"]: @@ -782,6 +781,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, relates_to=relates_to) diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index 8df387b6..596bcd2e 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 # @@ -50,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, @@ -71,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 84b6728e..696f91cc 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 # @@ -45,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) diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 7ff16cb0..81025f05 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 # @@ -98,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): @@ -142,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): @@ -471,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] 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 50% rename from requirements.txt rename to requirements/base.txt index c7ee0ddf..bfa7bdde 100644 --- a/requirements.txt +++ b/requirements/base.txt @@ -3,6 +3,6 @@ ruamel.yaml python-magic SQLAlchemy alembic --e git+https://github.com/LonamiWebs/Telethon@asyncio#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 d9df9d6d..208c4f5f 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ import setuptools +import sys import mautrix_telegram setuptools.setup( @@ -21,10 +22,13 @@ 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/LonamiWebs/Telethon/tarball/7da092894b306d720cc60c04daa2bfba58f81946#egg=Telethon" + if sys.version_info > (3, 5) + else "https://github.com/tulir/Telethon/tarball/ac46abc9680c5a74897fe6dbe9e585ad2577b1fa#egg=Telethon") ], classifiers=[