From bb1470e57f90a114f0334588055c772debfde48d Mon Sep 17 00:00:00 2001 From: MrNaif2018 Date: Mon, 15 Jul 2019 15:37:18 +0300 Subject: [PATCH 01/14] Add section to docs about scheduling --- docs/source/index.rst | 1 + docs/source/topics/scheduling.rst | 73 +++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 docs/source/topics/scheduling.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 5cb9bb2e..b8927657 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -40,6 +40,7 @@ Welcome to Pyrogram topics/more-on-updates topics/config-file topics/smart-plugins + topics/scheduling topics/auto-auth topics/session-settings topics/tgcrypto diff --git a/docs/source/topics/scheduling.rst b/docs/source/topics/scheduling.rst new file mode 100644 index 00000000..70f70215 --- /dev/null +++ b/docs/source/topics/scheduling.rst @@ -0,0 +1,73 @@ +Scheduling tasks +================ + +Pyrogram itself as Telegram MTProto API Framework contains only stuff +related to Telegram. Scheduling is out of it's scope. + +But it is easy to integrate pyrogram with your favourite scheduler. + +schedule +-------- + +Note that schedule is not suitable for async version of pyrogram. + +.. code-block:: python + + import time + import schedule + + + def job(): + app.send_message("me", "Hi!") + + + schedule.every(10).minutes.do(job) + schedule.every().hour.do(job) + schedule.every().day.at("10:30").do(job) + schedule.every(5).to(10).minutes.do(job) + schedule.every().monday.do(job) + schedule.every().wednesday.at("13:15").do(job) + schedule.every().minute.at(":17").do(job) + + with app: + while True: + schedule.run_pending() + time.sleep(1) + + +apscheduler +----------- + +.. code-block:: python + + import time + from apscheduler.schedulers.background import BackgroundScheduler + + + def job(): + app.send_message("me", "Hi!") + + + scheduler = BackgroundScheduler() + scheduler.add_job(job, 'interval', seconds=3) + + scheduler.start() + app.run() + +Apscheduler supports async version of pyrogram too, here is async example: + +.. code-block:: python + + from apscheduler.schedulers.asyncio import AsyncIOScheduler + + + async def job(): + await app.send_message("me", "Hi!") + + + scheduler = AsyncIOScheduler() + scheduler.add_job(job, 'interval', seconds=3) + + scheduler.start() + app.run() + From 85c21308757d21fbb55b610ab7f59b8a8ba1f12a Mon Sep 17 00:00:00 2001 From: MrNaif2018 Date: Mon, 15 Jul 2019 16:56:59 +0300 Subject: [PATCH 02/14] Update .gitignore with vscode and alternate docs build dir --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 0b1a0699..ce3407dd 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ pyrogram/api/all.py # PyCharm stuff .idea/ +# VS Code +.vscode/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -78,6 +81,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/source/_build # PyBuilder target/ From 02451ffeb56bed9918ef548b4744afe069143495 Mon Sep 17 00:00:00 2001 From: Mendel E Date: Mon, 29 Jul 2019 07:31:07 -0400 Subject: [PATCH 03/14] Try/except handler.check() Previously, when handler.check raised errors, it would be excepted by the try on line 153, and would fail to loop through the rest of the groups/handlers. --- pyrogram/client/ext/dispatcher.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 55a31452..5b6bccd2 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -166,8 +166,13 @@ class Dispatcher: args = None if isinstance(handler, handler_type): - if handler.check(parsed_update): - args = (parsed_update,) + try: + if handler.check(parsed_update): + args = (parsed_update,) + except Exception as e: + log.error(e, exc_info=True) + continue + elif isinstance(handler, RawUpdateHandler): args = (update, users, chats) From 47e5b9a7cbeb225ea7a0213f69d653b3bb07ec59 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 00:53:17 +0200 Subject: [PATCH 04/14] Set Message.text instead of Message.caption in case of web_page previews --- .../types/messages_and_media/message.py | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 4b98c290..a5105888 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -602,10 +602,26 @@ class Message(Object, Update): date=message.date, chat=Chat._parse(client, message, users, chats), from_user=User._parse(client, users.get(message.from_id, None)), - text=Str(message.message).init(entities) or None if media is None else None, - caption=Str(message.message).init(entities) or None if media is not None else None, - entities=entities or None if media is None else None, - caption_entities=entities or None if media is not None else None, + text=( + Str(message.message).init(entities) or None + if media is None or web_page is not None + else None + ), + caption=( + Str(message.message).init(entities) or None + if media is not None and web_page is None + else None + ), + entities=( + entities or None + if media is None or web_page is not None + else None + ), + caption_entities=( + entities or None + if media is not None and web_page is None + else None + ), author_signature=message.post_author, forward_from=forward_from, forward_sender_name=forward_sender_name, From 93a2fed8e662a1cd581065b0c2c50f4778c8b065 Mon Sep 17 00:00:00 2001 From: MrNaif2018 <39452697+MrNaif2018@users.noreply.github.com> Date: Thu, 1 Aug 2019 10:11:29 +0300 Subject: [PATCH 05/14] Improved examples, added links to docs --- docs/source/topics/scheduling.rst | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/source/topics/scheduling.rst b/docs/source/topics/scheduling.rst index 70f70215..1f4e1e01 100644 --- a/docs/source/topics/scheduling.rst +++ b/docs/source/topics/scheduling.rst @@ -9,8 +9,6 @@ But it is easy to integrate pyrogram with your favourite scheduler. schedule -------- -Note that schedule is not suitable for async version of pyrogram. - .. code-block:: python import time @@ -20,20 +18,15 @@ Note that schedule is not suitable for async version of pyrogram. def job(): app.send_message("me", "Hi!") - - schedule.every(10).minutes.do(job) - schedule.every().hour.do(job) - schedule.every().day.at("10:30").do(job) - schedule.every(5).to(10).minutes.do(job) - schedule.every().monday.do(job) - schedule.every().wednesday.at("13:15").do(job) - schedule.every().minute.at(":17").do(job) + schedule.every(3).seconds.do(job) with app: while True: schedule.run_pending() time.sleep(1) +Note that schedule is not suitable for async version of pyrogram. +For more information read `library `_ docs. apscheduler ----------- @@ -71,3 +64,4 @@ Apscheduler supports async version of pyrogram too, here is async example: scheduler.start() app.run() +For more information read `library `_ docs. From 6973f584886bc5d65e6aa5d88a5f98abeb8a287e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 12:37:22 +0200 Subject: [PATCH 06/14] Update scheduling.rst --- docs/source/topics/scheduling.rst | 50 +++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/docs/source/topics/scheduling.rst b/docs/source/topics/scheduling.rst index 1f4e1e01..3cb95ec7 100644 --- a/docs/source/topics/scheduling.rst +++ b/docs/source/topics/scheduling.rst @@ -1,23 +1,34 @@ -Scheduling tasks +Scheduling Tasks ================ -Pyrogram itself as Telegram MTProto API Framework contains only stuff -related to Telegram. Scheduling is out of it's scope. +Scheduling tasks means executing one or more functions periodically at pre-defined intervals or after a delay. This is +useful, for example, to send recurring messages to specific chats or users. -But it is easy to integrate pyrogram with your favourite scheduler. +Since there's no built-in task scheduler in Pyrogram, this page will only show examples on how to integrate Pyrogram +with the main Python schedule libraries such as ``schedule`` and ``apscheduler``. For more detailed information, you can +visit and learn from each library documentation. -schedule --------- +Using ``schedule`` +------------------ + +- Install with ``pip3 install schedule`` +- Documentation: https://schedule.readthedocs.io .. code-block:: python import time + import schedule + from pyrogram import Client + + app = Client("my_account") + def job(): app.send_message("me", "Hi!") + schedule.every(3).seconds.do(job) with app: @@ -25,43 +36,52 @@ schedule schedule.run_pending() time.sleep(1) -Note that schedule is not suitable for async version of pyrogram. -For more information read `library `_ docs. -apscheduler ------------ + +Using ``apscheduler`` +--------------------- + +- Install with ``pip3 install apscheduler`` +- Documentation: https://apscheduler.readthedocs.io .. code-block:: python - import time from apscheduler.schedulers.background import BackgroundScheduler + from pyrogram import Client + + app = Client("my_account") + def job(): app.send_message("me", "Hi!") scheduler = BackgroundScheduler() - scheduler.add_job(job, 'interval', seconds=3) + scheduler.add_job(job, "interval", seconds=3) scheduler.start() app.run() -Apscheduler supports async version of pyrogram too, here is async example: +``apscheduler`` does also support async code, here's an example with +`Pyrogram Asyncio `_: .. code-block:: python from apscheduler.schedulers.asyncio import AsyncIOScheduler + from pyrogram import Client + + app = Client("my_account") + async def job(): await app.send_message("me", "Hi!") scheduler = AsyncIOScheduler() - scheduler.add_job(job, 'interval', seconds=3) + scheduler.add_job(job, "interval", seconds=3) scheduler.start() app.run() -For more information read `library `_ docs. From f8f2ad5a60025eaf7a611b7680faa5bec50c1bd7 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 12:44:34 +0200 Subject: [PATCH 07/14] Tidy up docs --- docs/source/index.rst | 4 ++-- docs/source/topics/{serialize.rst => serializing.rst} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/source/topics/{serialize.rst => serializing.rst} (100%) diff --git a/docs/source/index.rst b/docs/source/index.rst index b8927657..f6961bc6 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -40,14 +40,14 @@ Welcome to Pyrogram topics/more-on-updates topics/config-file topics/smart-plugins - topics/scheduling topics/auto-auth topics/session-settings topics/tgcrypto topics/storage-engines topics/text-formatting - topics/serialize + topics/serializing topics/proxy + topics/scheduling topics/bots-interaction topics/mtproto-vs-botapi topics/debugging diff --git a/docs/source/topics/serialize.rst b/docs/source/topics/serializing.rst similarity index 100% rename from docs/source/topics/serialize.rst rename to docs/source/topics/serializing.rst From 3fedae8d820cd455aab69cc8a8a9627bd05af833 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 17:26:59 +0200 Subject: [PATCH 08/14] Update faq.rst --- docs/source/faq.rst | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 2dde12f2..a05ff39c 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -192,7 +192,6 @@ dismissed and their IP addresses are now kept as aliases to the nearest one. Thanks to `@FrayxRulez `_ for telling about alias DCs. - I want to migrate my account from DCX to DCY. --------------------------------------------- @@ -246,9 +245,13 @@ The error in question is ``[400 PEER_ID_INVALID]``, and could mean several thing - The chat id you tried to use is simply wrong, double check it. - The chat id refers to a group or channel you are not a member of. -- The chat id refers to a user you have't seen yet (from contacts, groups in common, forwarded messages or private - chats). - The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``. +- The chat id refers to a user your current session haven't met yet. + +About the last point: in order for you to meet a user and thus communicate with them, you should ask yourself how to +contact people using official apps. The answer is the same for Pyrogram too and involves normal usages such as searching +for usernames, meet them in a common group, have their phone contacts saved, getting a message mentioning them (either a +forward or a mention in the message text). UnicodeEncodeError: '' codec can't encode … ----------------------------------------------------- @@ -258,6 +261,14 @@ shows up when you try to print something and has very little to do with Pyrogram your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to a better terminal altogether. +Uploading with URLs gives error WEBPAGE_CURL_FAILED +--------------------------------------------------- + +When uploading media files using an URL, the server automatically tries to download the media and uploads it to the +Telegram cloud. This error usually happens in case the provided URL is not publicly accessible by Telegram itself or the +media exceeds 20 MB in size. In such cases, your only option is to download the media yourself and upload from your +local machine. + My verification code expires immediately! ----------------------------------------- From d727754ad6256eaaa8a2b49850e99e5862a88d30 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 18:41:04 +0200 Subject: [PATCH 09/14] Remove Null primitive It's unused --- compiler/api/compiler.py | 1 - pyrogram/api/core/primitives/__init__.py | 5 ++-- pyrogram/api/core/primitives/null.py | 32 ------------------------ 3 files changed, 3 insertions(+), 35 deletions(-) delete mode 100644 pyrogram/api/core/primitives/null.py diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 3995fd5f..255884db 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -478,7 +478,6 @@ def start(): f.write("\n 0xbc799737: \"pyrogram.api.core.BoolFalse\",") f.write("\n 0x997275b5: \"pyrogram.api.core.BoolTrue\",") - f.write("\n 0x56730bcc: \"pyrogram.api.core.Null\",") f.write("\n 0x1cb5c415: \"pyrogram.api.core.Vector\",") f.write("\n 0x73f1f8dc: \"pyrogram.api.core.MsgContainer\",") f.write("\n 0xae500895: \"pyrogram.api.core.FutureSalts\",") diff --git a/pyrogram/api/core/primitives/__init__.py b/pyrogram/api/core/primitives/__init__.py index 8885878b..f86e3cab 100644 --- a/pyrogram/api/core/primitives/__init__.py +++ b/pyrogram/api/core/primitives/__init__.py @@ -16,10 +16,11 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .bool import Bool, BoolTrue, BoolFalse +from .bool import Bool, BoolFalse, BoolTrue from .bytes import Bytes from .double import Double from .int import Int, Long, Int128, Int256 -from .null import Null from .string import String from .vector import Vector + +__all__ = ["Bool", "BoolFalse", "BoolTrue", "Bytes", "Double", "Int", "Long", "Int128", "Int256", "String", "Vector"] diff --git a/pyrogram/api/core/primitives/null.py b/pyrogram/api/core/primitives/null.py deleted file mode 100644 index ffddea94..00000000 --- a/pyrogram/api/core/primitives/null.py +++ /dev/null @@ -1,32 +0,0 @@ -# Pyrogram - Telegram MTProto API Client Library for Python -# Copyright (C) 2017-2019 Dan Tès -# -# This file is part of Pyrogram. -# -# Pyrogram is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Pyrogram 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 Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with Pyrogram. If not, see . - -from io import BytesIO - -from ..tl_object import TLObject - - -class Null(TLObject): - ID = 0x56730bcc - - @staticmethod - def read(b: BytesIO, *args) -> None: - return None - - def __new__(cls) -> bytes: - return cls.ID.to_bytes(4, "little") From 9ad5e62dea5fa5d9786770097c2b0de8db10b6f4 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 18:44:20 +0200 Subject: [PATCH 10/14] Move all imported schema objects outside TLObject --- pyrogram/api/__init__.py | 3 +-- pyrogram/api/core/__init__.py | 5 +---- pyrogram/api/core/tl_object.py | 6 +++--- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/pyrogram/api/__init__.py b/pyrogram/api/__init__.py index 8d7831ff..78f1a579 100644 --- a/pyrogram/api/__init__.py +++ b/pyrogram/api/__init__.py @@ -19,8 +19,7 @@ from importlib import import_module from .all import objects -from .core.tl_object import TLObject for k, v in objects.items(): path, name = v.rsplit(".", 1) - TLObject.all[k] = getattr(import_module(path), name) + objects[k] = getattr(import_module(path), name) diff --git a/pyrogram/api/core/__init__.py b/pyrogram/api/core/__init__.py index aaf5a324..ff4fc9c5 100644 --- a/pyrogram/api/core/__init__.py +++ b/pyrogram/api/core/__init__.py @@ -22,8 +22,5 @@ from .gzip_packed import GzipPacked from .list import List from .message import Message from .msg_container import MsgContainer -from .primitives import ( - Bool, BoolTrue, BoolFalse, Bytes, Double, - Int, Long, Int128, Int256, Null, String, Vector -) +from .primitives import * from .tl_object import TLObject diff --git a/pyrogram/api/core/tl_object.py b/pyrogram/api/core/tl_object.py index 4b951404..d39a8ae2 100644 --- a/pyrogram/api/core/tl_object.py +++ b/pyrogram/api/core/tl_object.py @@ -20,17 +20,17 @@ from collections import OrderedDict from io import BytesIO from json import dumps +from ..all import objects + class TLObject: - all = {} - __slots__ = [] QUALNAME = "Base" @staticmethod def read(b: BytesIO, *args): # TODO: Rename b -> data - return TLObject.all[int.from_bytes(b.read(4), "little")].read(b, *args) + return objects[int.from_bytes(b.read(4), "little")].read(b, *args) def write(self, *args) -> bytes: pass From ad0f8284f686b2501460a51943b2149deb9331ce Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 19:07:08 +0200 Subject: [PATCH 11/14] Use the correct way to parse peer identifiers --- pyrogram/client/client.py | 45 +++++++------- pyrogram/client/ext/utils.py | 60 ++++++++++++------- pyrogram/client/methods/chats/get_chat.py | 4 +- pyrogram/client/methods/chats/get_dialogs.py | 6 +- .../bots_and_keyboards/callback_query.py | 12 +--- .../types/messages_and_media/message.py | 7 ++- pyrogram/client/types/user_and_chats/chat.py | 5 +- .../client/types/user_and_chats/dialog.py | 12 +--- 8 files changed, 80 insertions(+), 71 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 64595a91..511dbf2a 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -1015,7 +1015,7 @@ class Client(Methods, BaseClient): access_hash = 0 peer_type = "group" elif isinstance(peer, (types.Channel, types.ChannelForbidden)): - peer_id = int("-100" + str(peer.id)) + peer_id = utils.get_channel_id(peer.id) access_hash = peer.access_hash username = getattr(peer, "username", None) @@ -1131,7 +1131,7 @@ class Client(Methods, BaseClient): try: diff = self.send( functions.updates.GetChannelDifference( - channel=self.resolve_peer(int("-100" + str(channel_id))), + channel=self.resolve_peer(utils.get_channel_id(channel_id)), filter=types.ChannelMessagesFilter( ranges=[types.MessageRange( min_id=update.message.id, @@ -1519,33 +1519,38 @@ class Client(Methods, BaseClient): except KeyError: raise PeerIdInvalid - if peer_id > 0: + peer_type = utils.get_type(peer_id) + + if peer_type == "user": self.fetch_peers( self.send( functions.users.GetUsers( - id=[types.InputUser( - user_id=peer_id, - access_hash=0 - )] + id=[ + types.InputUser( + user_id=peer_id, + access_hash=0 + ) + ] ) ) ) + elif peer_type == "chat": + self.send( + functions.messages.GetChats( + id=[-peer_id] + ) + ) else: - if str(peer_id).startswith("-100"): - self.send( - functions.channels.GetChannels( - id=[types.InputChannel( - channel_id=int(str(peer_id)[4:]), + self.send( + functions.channels.GetChannels( + id=[ + types.InputChannel( + channel_id=utils.get_channel_id(peer_id), access_hash=0 - )] - ) - ) - else: - self.send( - functions.messages.GetChats( - id=[-peer_id] - ) + ) + ] ) + ) try: return self.storage.get_peer_by_id(peer_id) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index e0a797e2..d89f83bb 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -18,10 +18,11 @@ import base64 import struct -from typing import Union, List +from typing import List +from typing import Union import pyrogram - +from pyrogram.api.types import PeerUser, PeerChat, PeerChannel from . import BaseClient from ...api import types @@ -62,23 +63,6 @@ def encode(s: bytes) -> str: return base64.urlsafe_b64encode(r).decode().rstrip("=") -def get_peer_id(input_peer) -> int: - return ( - input_peer.user_id if isinstance(input_peer, types.InputPeerUser) - else -input_peer.chat_id if isinstance(input_peer, types.InputPeerChat) - else int("-100" + str(input_peer.channel_id)) - ) - - -def get_input_peer(peer_id: int, access_hash: int): - return ( - types.InputPeerUser(user_id=peer_id, access_hash=access_hash) if peer_id > 0 - else types.InputPeerChannel(channel_id=int(str(peer_id)[4:]), access_hash=access_hash) - if (str(peer_id).startswith("-100") and access_hash) - else types.InputPeerChat(chat_id=-peer_id) - ) - - def get_offset_date(dialogs): for m in reversed(dialogs.messages): if isinstance(m, types.MessageEmpty): @@ -183,7 +167,7 @@ def parse_deleted_messages(client, update) -> List["pyrogram.Message"]: pyrogram.Message( message_id=message, chat=pyrogram.Chat( - id=int("-100" + str(channel_id)), + id=get_channel_id(channel_id), type="channel", client=client ) if channel_id is not None else None, @@ -203,3 +187,39 @@ def unpack_inline_message_id(inline_message_id: str) -> types.InputBotInlineMess id=r[1], access_hash=r[2] ) + + +MIN_CHANNEL_ID = -1002147483647 +MAX_CHANNEL_ID = -1000000000000 +MIN_CHAT_ID = -2147483647 +MAX_USER_ID = 2147483647 + + +def get_peer_id(peer: Union[PeerUser, PeerChat, PeerChannel]) -> int: + if isinstance(peer, PeerUser): + return peer.user_id + + if isinstance(peer, PeerChat): + return -peer.chat_id + + if isinstance(peer, PeerChannel): + return MAX_CHANNEL_ID - peer.channel_id + + raise ValueError("Peer type invalid: {}".format(peer)) + + +def get_type(peer_id: int) -> str: + if peer_id < 0: + if MIN_CHAT_ID <= peer_id: + return "chat" + + if MIN_CHANNEL_ID <= peer_id < MAX_CHANNEL_ID: + return "channel" + elif 0 < peer_id <= MAX_USER_ID: + return "user" + + raise ValueError("Peer id invalid: {}".format(peer_id)) + + +def get_channel_id(peer_id: int) -> int: + return MAX_CHANNEL_ID - peer_id diff --git a/pyrogram/client/methods/chats/get_chat.py b/pyrogram/client/methods/chats/get_chat.py index 48c5cc22..0773ce6c 100644 --- a/pyrogram/client/methods/chats/get_chat.py +++ b/pyrogram/client/methods/chats/get_chat.py @@ -20,7 +20,7 @@ from typing import Union import pyrogram from pyrogram.api import functions, types -from ...ext import BaseClient +from ...ext import BaseClient, utils class GetChat(BaseClient): @@ -70,7 +70,7 @@ class GetChat(BaseClient): chat_id = -r.chat.id if isinstance(r.chat, types.Channel): - chat_id = int("-100" + str(r.chat.id)) + chat_id = utils.get_channel_id(r.chat.id) peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/get_dialogs.py b/pyrogram/client/methods/chats/get_dialogs.py index f77ad30a..30078d57 100644 --- a/pyrogram/client/methods/chats/get_dialogs.py +++ b/pyrogram/client/methods/chats/get_dialogs.py @@ -23,7 +23,7 @@ from typing import List import pyrogram from pyrogram.api import functions, types from pyrogram.errors import FloodWait -from ...ext import BaseClient +from ...ext import BaseClient, utils log = logging.getLogger(__name__) @@ -100,10 +100,8 @@ class GetDialogs(BaseClient): chat_id = to_id.user_id else: chat_id = message.from_id - elif isinstance(to_id, types.PeerChat): - chat_id = -to_id.chat_id else: - chat_id = int("-100" + str(to_id.channel_id)) + chat_id = utils.get_peer_id(to_id) messages[chat_id] = pyrogram.Message._parse(self, message, users, chats) diff --git a/pyrogram/client/types/bots_and_keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py index d58865b2..9ba1804b 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_query.py @@ -25,6 +25,7 @@ from pyrogram.api import types from ..object import Object from ..update import Update from ..user_and_chats import User +from ...ext import utils class CallbackQuery(Object, Update): @@ -90,16 +91,7 @@ class CallbackQuery(Object, Update): inline_message_id = None if isinstance(callback_query, types.UpdateBotCallbackQuery): - peer = callback_query.peer - - if isinstance(peer, types.PeerUser): - peer_id = peer.user_id - elif isinstance(peer, types.PeerChat): - peer_id = -peer.chat_id - else: - peer_id = int("-100" + str(peer.channel_id)) - - message = client.get_messages(peer_id, callback_query.msg_id) + message = client.get_messages(utils.get_peer_id(callback_query.peer), callback_query.msg_id) elif isinstance(callback_query, types.UpdateInlineBotCallbackQuery): inline_message_id = b64encode( pack( diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index a5105888..ed0088cd 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -31,7 +31,8 @@ from ..object import Object from ..update import Update from ..user_and_chats.chat import Chat from ..user_and_chats.user import User -from ...parser import utils, Parser +from ...ext import utils +from ...parser import utils as parser_utils, Parser class Str(str): @@ -54,7 +55,7 @@ class Str(str): return Parser.unparse(self, self.entities, True) def __getitem__(self, item): - return utils.remove_surrogates(utils.add_surrogates(self)[item]) + return parser_utils.remove_surrogates(parser_utils.add_surrogates(self)[item]) class Message(Object, Update): @@ -446,7 +447,7 @@ class Message(Object, Update): new_chat_title=new_chat_title, new_chat_photo=new_chat_photo, delete_chat_photo=delete_chat_photo, - migrate_to_chat_id=int("-100" + str(migrate_to_chat_id)) if migrate_to_chat_id else None, + migrate_to_chat_id=utils.get_channel_id(migrate_to_chat_id) if migrate_to_chat_id else None, migrate_from_chat_id=-migrate_from_chat_id if migrate_from_chat_id else None, group_chat_created=group_chat_created, channel_chat_created=channel_chat_created, diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index cac5d0c7..396831cc 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -23,6 +23,7 @@ from pyrogram.api import types from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto from ..object import Object +from ...ext import utils class Chat(Object): @@ -180,7 +181,7 @@ class Chat(Object): @staticmethod def _parse_channel_chat(client, channel: types.Channel) -> "Chat": - peer_id = int("-100" + str(channel.id)) + peer_id = utils.get_channel_id(channel.id) return Chat( id=peer_id, @@ -672,7 +673,7 @@ class Chat(Object): can_pin_messages=can_pin_messages, can_promote_members=can_promote_members ) - + def join(self): """Bound method *join* of :obj:`Chat`. diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index 4ea82184..a78e501b 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -21,6 +21,7 @@ import pyrogram from pyrogram.api import types from ..object import Object from ..user_and_chats import Chat +from ...ext import utils class Dialog(Object): @@ -70,18 +71,9 @@ class Dialog(Object): @staticmethod def _parse(client, dialog: types.Dialog, messages, users, chats) -> "Dialog": - chat_id = dialog.peer - - if isinstance(chat_id, types.PeerUser): - chat_id = chat_id.user_id - elif isinstance(chat_id, types.PeerChat): - chat_id = -chat_id.chat_id - else: - chat_id = int("-100" + str(chat_id.channel_id)) - return Dialog( chat=Chat._parse_dialog(client, dialog.peer, users, chats), - top_message=messages.get(chat_id), + top_message=messages.get(utils.get_peer_id(dialog.peer)), unread_messages_count=dialog.unread_count, unread_mentions_count=dialog.unread_mentions_count, unread_mark=dialog.unread_mark, From aa135ea457880a051531b7624c65f8d1dc6b45da Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 1 Aug 2019 19:11:43 +0200 Subject: [PATCH 12/14] Reformat project --- pyrogram/client/ext/utils.py | 3 ++- pyrogram/client/methods/users/block_user.py | 3 +-- pyrogram/client/methods/users/delete_profile_photos.py | 1 - pyrogram/client/methods/users/get_profile_photos.py | 1 - pyrogram/client/methods/users/get_profile_photos_count.py | 1 - pyrogram/client/methods/users/unblock_user.py | 3 +-- pyrogram/client/parser/__init__.py | 2 +- pyrogram/client/storage/__init__.py | 2 +- .../client/types/bots_and_keyboards/inline_keyboard_button.py | 1 + .../client/types/bots_and_keyboards/inline_keyboard_markup.py | 1 + .../client/types/bots_and_keyboards/reply_keyboard_markup.py | 1 + pyrogram/errors/rpc_error.py | 3 ++- pyrogram/session/auth.py | 1 - pyrogram/session/internals/msg_factory.py | 3 ++- pyrogram/session/session.py | 4 ++-- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index d89f83bb..fbee9ea8 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -21,8 +21,9 @@ import struct from typing import List from typing import Union -import pyrogram from pyrogram.api.types import PeerUser, PeerChat, PeerChannel + +import pyrogram from . import BaseClient from ...api import types diff --git a/pyrogram/client/methods/users/block_user.py b/pyrogram/client/methods/users/block_user.py index 120a4aaf..ff29089c 100644 --- a/pyrogram/client/methods/users/block_user.py +++ b/pyrogram/client/methods/users/block_user.py @@ -18,8 +18,7 @@ from typing import Union -import pyrogram -from pyrogram.api import functions, types +from pyrogram.api import functions from ...ext import BaseClient diff --git a/pyrogram/client/methods/users/delete_profile_photos.py b/pyrogram/client/methods/users/delete_profile_photos.py index c155ede8..5c3b26e8 100644 --- a/pyrogram/client/methods/users/delete_profile_photos.py +++ b/pyrogram/client/methods/users/delete_profile_photos.py @@ -21,7 +21,6 @@ from typing import List, Union from pyrogram.api import functions, types from pyrogram.client.ext import utils - from ...ext import BaseClient diff --git a/pyrogram/client/methods/users/get_profile_photos.py b/pyrogram/client/methods/users/get_profile_photos.py index dece6b5d..2723a36c 100644 --- a/pyrogram/client/methods/users/get_profile_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -21,7 +21,6 @@ from typing import Union, List import pyrogram from pyrogram.api import functions, types from pyrogram.client.ext import utils - from ...ext import BaseClient diff --git a/pyrogram/client/methods/users/get_profile_photos_count.py b/pyrogram/client/methods/users/get_profile_photos_count.py index 4069f85b..51a4091e 100644 --- a/pyrogram/client/methods/users/get_profile_photos_count.py +++ b/pyrogram/client/methods/users/get_profile_photos_count.py @@ -19,7 +19,6 @@ from typing import Union from pyrogram.api import functions, types - from ...ext import BaseClient diff --git a/pyrogram/client/methods/users/unblock_user.py b/pyrogram/client/methods/users/unblock_user.py index 8b87cd7e..e42fbd24 100644 --- a/pyrogram/client/methods/users/unblock_user.py +++ b/pyrogram/client/methods/users/unblock_user.py @@ -18,8 +18,7 @@ from typing import Union -import pyrogram -from pyrogram.api import functions, types +from pyrogram.api import functions from ...ext import BaseClient diff --git a/pyrogram/client/parser/__init__.py b/pyrogram/client/parser/__init__.py index 4769038d..53806619 100644 --- a/pyrogram/client/parser/__init__.py +++ b/pyrogram/client/parser/__init__.py @@ -16,4 +16,4 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .parser import Parser \ No newline at end of file +from .parser import Parser diff --git a/pyrogram/client/storage/__init__.py b/pyrogram/client/storage/__init__.py index 00d2f144..657c06eb 100644 --- a/pyrogram/client/storage/__init__.py +++ b/pyrogram/client/storage/__init__.py @@ -16,6 +16,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .memory_storage import MemoryStorage from .file_storage import FileStorage +from .memory_storage import MemoryStorage from .storage import Storage diff --git a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py index 54aa7802..514b0303 100644 --- a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py +++ b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py @@ -22,6 +22,7 @@ from pyrogram.api.types import ( KeyboardButtonUrl, KeyboardButtonCallback, KeyboardButtonSwitchInline, KeyboardButtonGame ) + from .callback_game import CallbackGame from ..object import Object diff --git a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py index 7b811f88..bdca85d1 100644 --- a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py +++ b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py @@ -19,6 +19,7 @@ from typing import List from pyrogram.api.types import ReplyInlineMarkup, KeyboardButtonRow + from . import InlineKeyboardButton from ..object import Object diff --git a/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py index 4e666d1f..f958051b 100644 --- a/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py +++ b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py @@ -20,6 +20,7 @@ from typing import List, Union from pyrogram.api.types import KeyboardButtonRow from pyrogram.api.types import ReplyKeyboardMarkup as RawReplyKeyboardMarkup + from . import KeyboardButton from ..object import Object diff --git a/pyrogram/errors/rpc_error.py b/pyrogram/errors/rpc_error.py index 806b5373..9969d3fa 100644 --- a/pyrogram/errors/rpc_error.py +++ b/pyrogram/errors/rpc_error.py @@ -21,8 +21,9 @@ from datetime import datetime from importlib import import_module from typing import Type -from pyrogram.api.core import TLObject from pyrogram.api.types import RpcError as RawRPCError + +from pyrogram.api.core import TLObject from .exceptions.all import exceptions diff --git a/pyrogram/session/auth.py b/pyrogram/session/auth.py index b05b2855..f6d137fa 100644 --- a/pyrogram/session/auth.py +++ b/pyrogram/session/auth.py @@ -27,7 +27,6 @@ from pyrogram.api import functions, types from pyrogram.api.core import TLObject, Long, Int from pyrogram.connection import Connection from pyrogram.crypto import AES, RSA, Prime - from .internals import MsgId log = logging.getLogger(__name__) diff --git a/pyrogram/session/internals/msg_factory.py b/pyrogram/session/internals/msg_factory.py index 2b833ce8..453eefc1 100644 --- a/pyrogram/session/internals/msg_factory.py +++ b/pyrogram/session/internals/msg_factory.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.api.core import Message, MsgContainer, TLObject from pyrogram.api.functions import Ping from pyrogram.api.types import MsgsAck, HttpWait + +from pyrogram.api.core import Message, MsgContainer, TLObject from .msg_id import MsgId from .seq_no import SeqNo diff --git a/pyrogram/session/session.py b/pyrogram/session/session.py index 21e2ba10..689fe584 100644 --- a/pyrogram/session/session.py +++ b/pyrogram/session/session.py @@ -26,15 +26,15 @@ from os import urandom from queue import Queue from threading import Event, Thread +from pyrogram.api.all import layer + import pyrogram from pyrogram import __copyright__, __license__, __version__ from pyrogram.api import functions, types, core -from pyrogram.api.all import layer from pyrogram.api.core import Message, TLObject, MsgContainer, Long, FutureSalt, Int from pyrogram.connection import Connection from pyrogram.crypto import AES, KDF from pyrogram.errors import RPCError, InternalServerError, AuthKeyDuplicated - from .internals import MsgId, MsgFactory log = logging.getLogger(__name__) From 67112a34e92c2265f9aed555b9299fb594cd0869 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 2 Aug 2019 00:33:48 +0200 Subject: [PATCH 13/14] Remove __slots__ from Pyrogram types --- .../client/types/bots_and_keyboards/callback_game.py | 2 -- .../client/types/bots_and_keyboards/callback_query.py | 2 -- .../client/types/bots_and_keyboards/force_reply.py | 2 -- .../types/bots_and_keyboards/game_high_score.py | 2 -- .../bots_and_keyboards/inline_keyboard_button.py | 4 ---- .../bots_and_keyboards/inline_keyboard_markup.py | 2 -- .../types/bots_and_keyboards/keyboard_button.py | 2 -- .../types/bots_and_keyboards/reply_keyboard_markup.py | 2 -- .../types/bots_and_keyboards/reply_keyboard_remove.py | 2 -- pyrogram/client/types/inline_mode/inline_query.py | 1 - .../client/types/inline_mode/inline_query_result.py | 2 -- .../inline_mode/inline_query_result_animation.py | 5 ----- .../types/inline_mode/inline_query_result_article.py | 2 -- .../types/inline_mode/inline_query_result_photo.py | 5 ----- pyrogram/client/types/input_media/input_media.py | 1 - .../client/types/input_media/input_media_animation.py | 2 -- .../client/types/input_media/input_media_audio.py | 2 -- .../client/types/input_media/input_media_document.py | 2 -- .../client/types/input_media/input_media_photo.py | 2 -- .../client/types/input_media/input_media_video.py | 2 -- .../client/types/input_media/input_phone_contact.py | 2 -- .../input_message_content/input_message_content.py | 2 -- .../input_text_message_content.py | 2 -- pyrogram/client/types/messages_and_media/animation.py | 2 -- pyrogram/client/types/messages_and_media/audio.py | 4 ---- pyrogram/client/types/messages_and_media/contact.py | 2 -- pyrogram/client/types/messages_and_media/document.py | 2 -- pyrogram/client/types/messages_and_media/game.py | 2 -- pyrogram/client/types/messages_and_media/location.py | 2 -- pyrogram/client/types/messages_and_media/message.py | 11 ----------- .../client/types/messages_and_media/message_entity.py | 2 -- pyrogram/client/types/messages_and_media/photo.py | 2 -- pyrogram/client/types/messages_and_media/poll.py | 2 -- .../client/types/messages_and_media/poll_option.py | 2 -- pyrogram/client/types/messages_and_media/sticker.py | 4 ---- .../types/messages_and_media/stripped_thumbnail.py | 2 -- pyrogram/client/types/messages_and_media/thumbnail.py | 2 -- pyrogram/client/types/messages_and_media/venue.py | 2 -- pyrogram/client/types/messages_and_media/video.py | 5 ----- .../client/types/messages_and_media/video_note.py | 2 -- pyrogram/client/types/messages_and_media/voice.py | 2 -- pyrogram/client/types/messages_and_media/webpage.py | 6 ------ pyrogram/client/types/object.py | 8 +++----- pyrogram/client/types/update.py | 2 -- pyrogram/client/types/user_and_chats/chat.py | 6 ------ pyrogram/client/types/user_and_chats/chat_member.py | 2 -- .../client/types/user_and_chats/chat_permissions.py | 7 ------- pyrogram/client/types/user_and_chats/chat_photo.py | 2 -- pyrogram/client/types/user_and_chats/chat_preview.py | 2 -- pyrogram/client/types/user_and_chats/dialog.py | 2 -- pyrogram/client/types/user_and_chats/user.py | 6 ------ 51 files changed, 3 insertions(+), 144 deletions(-) diff --git a/pyrogram/client/types/bots_and_keyboards/callback_game.py b/pyrogram/client/types/bots_and_keyboards/callback_game.py index acf6df60..338cfb06 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_game.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_game.py @@ -25,7 +25,5 @@ class CallbackGame(Object): Use BotFather to set up your game. """ - __slots__ = [] - def __init__(self): super().__init__() diff --git a/pyrogram/client/types/bots_and_keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py index 9ba1804b..9a5674ae 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_query.py @@ -61,8 +61,6 @@ class CallbackQuery(Object, Update): """ - __slots__ = ["id", "from_user", "chat_instance", "message", "inline_message_id", "data", "game_short_name"] - def __init__( self, *, diff --git a/pyrogram/client/types/bots_and_keyboards/force_reply.py b/pyrogram/client/types/bots_and_keyboards/force_reply.py index 6c542aa8..ef5c0ccb 100644 --- a/pyrogram/client/types/bots_and_keyboards/force_reply.py +++ b/pyrogram/client/types/bots_and_keyboards/force_reply.py @@ -37,8 +37,6 @@ class ForceReply(Object): 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. """ - __slots__ = ["selective"] - def __init__( self, selective: bool = None diff --git a/pyrogram/client/types/bots_and_keyboards/game_high_score.py b/pyrogram/client/types/bots_and_keyboards/game_high_score.py index 5d576ad4..38e2242a 100644 --- a/pyrogram/client/types/bots_and_keyboards/game_high_score.py +++ b/pyrogram/client/types/bots_and_keyboards/game_high_score.py @@ -37,8 +37,6 @@ class GameHighScore(Object): Position in high score table for the game. """ - __slots__ = ["user", "score", "position"] - def __init__( self, *, diff --git a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py index 514b0303..678be614 100644 --- a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py +++ b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py @@ -59,10 +59,6 @@ class InlineKeyboardButton(Object): # TODO: Add callback_game and pay fields - __slots__ = [ - "text", "url", "callback_data", "switch_inline_query", "switch_inline_query_current_chat", "callback_game" - ] - def __init__( self, text: str, diff --git a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py index bdca85d1..811c4365 100644 --- a/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py +++ b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py @@ -32,8 +32,6 @@ class InlineKeyboardMarkup(Object): List of button rows, each represented by a List of InlineKeyboardButton objects. """ - __slots__ = ["inline_keyboard"] - def __init__( self, inline_keyboard: List[List[InlineKeyboardButton]] diff --git a/pyrogram/client/types/bots_and_keyboards/keyboard_button.py b/pyrogram/client/types/bots_and_keyboards/keyboard_button.py index 8374db1b..21c03613 100644 --- a/pyrogram/client/types/bots_and_keyboards/keyboard_button.py +++ b/pyrogram/client/types/bots_and_keyboards/keyboard_button.py @@ -41,8 +41,6 @@ class KeyboardButton(Object): Available in private chats only. """ - __slots__ = ["text", "request_contact", "request_location"] - def __init__( self, text: str, diff --git a/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py index f958051b..12799bd7 100644 --- a/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py +++ b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py @@ -50,8 +50,6 @@ class ReplyKeyboardMarkup(Object): select the new language. Other users in the group don't see the keyboard. """ - __slots__ = ["keyboard", "resize_keyboard", "one_time_keyboard", "selective"] - def __init__( self, keyboard: List[List[Union[KeyboardButton, str]]], diff --git a/pyrogram/client/types/bots_and_keyboards/reply_keyboard_remove.py b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_remove.py index d451a8e8..1623c9bd 100644 --- a/pyrogram/client/types/bots_and_keyboards/reply_keyboard_remove.py +++ b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_remove.py @@ -38,8 +38,6 @@ class ReplyKeyboardRemove(Object): keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. """ - __slots__ = ["selective"] - def __init__( self, selective: bool = None diff --git a/pyrogram/client/types/inline_mode/inline_query.py b/pyrogram/client/types/inline_mode/inline_query.py index 065c4492..27b73ff4 100644 --- a/pyrogram/client/types/inline_mode/inline_query.py +++ b/pyrogram/client/types/inline_mode/inline_query.py @@ -48,7 +48,6 @@ class InlineQuery(Object, Update): location (:obj:`Location`. *optional*): Sender location, only for bots that request user location. """ - __slots__ = ["id", "from_user", "query", "offset", "location"] def __init__( self, diff --git a/pyrogram/client/types/inline_mode/inline_query_result.py b/pyrogram/client/types/inline_mode/inline_query_result.py index 1ff3e5e1..ef26eacc 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result.py +++ b/pyrogram/client/types/inline_mode/inline_query_result.py @@ -53,8 +53,6 @@ class InlineQueryResult(Object): - :obj:`InlineQueryResultAnimation` """ - __slots__ = ["type", "id", "input_message_content", "reply_markup"] - def __init__( self, type: str, diff --git a/pyrogram/client/types/inline_mode/inline_query_result_animation.py b/pyrogram/client/types/inline_mode/inline_query_result_animation.py index 4d2d5596..c4cb26e4 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result_animation.py +++ b/pyrogram/client/types/inline_mode/inline_query_result_animation.py @@ -68,11 +68,6 @@ class InlineQueryResultAnimation(InlineQueryResult): Content of the message to be sent instead of the photo. """ - __slots__ = [ - "animation_url", "thumb_url", "title", "description", "caption", "parse_mode", "reply_markup", - "input_message_content" - ] - def __init__( self, animation_url: str, diff --git a/pyrogram/client/types/inline_mode/inline_query_result_article.py b/pyrogram/client/types/inline_mode/inline_query_result_article.py index c21416f5..735a1e02 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result_article.py +++ b/pyrogram/client/types/inline_mode/inline_query_result_article.py @@ -49,8 +49,6 @@ class InlineQueryResultArticle(InlineQueryResult): Inline keyboard attached to the message. """ - __slots__ = ["title", "url", "description", "thumb_url"] - def __init__( self, title: str, diff --git a/pyrogram/client/types/inline_mode/inline_query_result_photo.py b/pyrogram/client/types/inline_mode/inline_query_result_photo.py index 3442764e..ffcc21c0 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result_photo.py +++ b/pyrogram/client/types/inline_mode/inline_query_result_photo.py @@ -68,11 +68,6 @@ class InlineQueryResultPhoto(InlineQueryResult): Content of the message to be sent instead of the photo. """ - __slots__ = [ - "photo_url", "thumb_url", "title", "description", "caption", "parse_mode", "reply_markup", - "input_message_content" - ] - def __init__( self, photo_url: str, diff --git a/pyrogram/client/types/input_media/input_media.py b/pyrogram/client/types/input_media/input_media.py index 2b5d7f0f..9b89fe12 100644 --- a/pyrogram/client/types/input_media/input_media.py +++ b/pyrogram/client/types/input_media/input_media.py @@ -30,7 +30,6 @@ class InputMedia(Object): - :obj:`InputMediaPhoto` - :obj:`InputMediaVideo` """ - __slots__ = ["media", "caption", "parse_mode"] def __init__(self, media: str, caption: str, parse_mode: str): super().__init__() diff --git a/pyrogram/client/types/input_media/input_media_animation.py b/pyrogram/client/types/input_media/input_media_animation.py index d6c67d56..dc70cbec 100644 --- a/pyrogram/client/types/input_media/input_media_animation.py +++ b/pyrogram/client/types/input_media/input_media_animation.py @@ -56,8 +56,6 @@ class InputMediaAnimation(InputMedia): Animation duration. """ - __slots__ = ["thumb", "width", "height", "duration"] - def __init__( self, media: str, diff --git a/pyrogram/client/types/input_media/input_media_audio.py b/pyrogram/client/types/input_media/input_media_audio.py index f01444a8..5ed670a6 100644 --- a/pyrogram/client/types/input_media/input_media_audio.py +++ b/pyrogram/client/types/input_media/input_media_audio.py @@ -58,8 +58,6 @@ class InputMediaAudio(InputMedia): Title of the audio """ - __slots__ = ["thumb", "duration", "performer", "title"] - def __init__( self, media: str, diff --git a/pyrogram/client/types/input_media/input_media_document.py b/pyrogram/client/types/input_media/input_media_document.py index af549c81..14756e02 100644 --- a/pyrogram/client/types/input_media/input_media_document.py +++ b/pyrogram/client/types/input_media/input_media_document.py @@ -47,8 +47,6 @@ class InputMediaDocument(InputMedia): Pass None to completely disable style parsing. """ - __slots__ = ["thumb"] - def __init__( self, media: str, diff --git a/pyrogram/client/types/input_media/input_media_photo.py b/pyrogram/client/types/input_media/input_media_photo.py index 30c53777..5e18cdd6 100644 --- a/pyrogram/client/types/input_media/input_media_photo.py +++ b/pyrogram/client/types/input_media/input_media_photo.py @@ -43,8 +43,6 @@ class InputMediaPhoto(InputMedia): Pass None to completely disable style parsing. """ - __slots__ = [] - def __init__( self, media: str, diff --git a/pyrogram/client/types/input_media/input_media_video.py b/pyrogram/client/types/input_media/input_media_video.py index 3500ff55..6b64caa8 100644 --- a/pyrogram/client/types/input_media/input_media_video.py +++ b/pyrogram/client/types/input_media/input_media_video.py @@ -61,8 +61,6 @@ class InputMediaVideo(InputMedia): Pass True, if the uploaded video is suitable for streaming. """ - __slots__ = ["thumb", "width", "height", "duration", "supports_streaming"] - def __init__( self, media: str, diff --git a/pyrogram/client/types/input_media/input_phone_contact.py b/pyrogram/client/types/input_media/input_phone_contact.py index 9c03694d..7498768d 100644 --- a/pyrogram/client/types/input_media/input_phone_contact.py +++ b/pyrogram/client/types/input_media/input_phone_contact.py @@ -37,8 +37,6 @@ class InputPhoneContact(Object): Contact's last name """ - __slots__ = [] - def __init__(self, phone: str, first_name: str, last_name: str = ""): super().__init__(None) diff --git a/pyrogram/client/types/input_message_content/input_message_content.py b/pyrogram/client/types/input_message_content/input_message_content.py index b02c6b38..6561b5a8 100644 --- a/pyrogram/client/types/input_message_content/input_message_content.py +++ b/pyrogram/client/types/input_message_content/input_message_content.py @@ -31,8 +31,6 @@ class InputMessageContent(Object): - :obj:`InputTextMessageContent` """ - __slots__ = [] - def __init__(self): super().__init__() diff --git a/pyrogram/client/types/input_message_content/input_text_message_content.py b/pyrogram/client/types/input_message_content/input_text_message_content.py index f90b7096..3ab67d96 100644 --- a/pyrogram/client/types/input_message_content/input_text_message_content.py +++ b/pyrogram/client/types/input_message_content/input_text_message_content.py @@ -41,8 +41,6 @@ class InputTextMessageContent(InputMessageContent): Disables link previews for links in this message. """ - __slots__ = ["message_text", "parse_mode", "disable_web_page_preview"] - def __init__(self, message_text: str, parse_mode: Union[str, None] = object, disable_web_page_preview: bool = None): super().__init__() diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index 5441a114..ba6744ce 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -58,8 +58,6 @@ class Animation(Object): Animation thumbnails. """ - __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "duration", "thumbs"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index 3d9cf8a6..6d8a12e9 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -58,10 +58,6 @@ class Audio(Object): Thumbnails of the music file album cover. """ - __slots__ = [ - "file_id", "file_name", "mime_type", "file_size", "date", "duration", "performer", "title", "thumbs" - ] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/contact.py b/pyrogram/client/types/messages_and_media/contact.py index d18f5e18..ad263397 100644 --- a/pyrogram/client/types/messages_and_media/contact.py +++ b/pyrogram/client/types/messages_and_media/contact.py @@ -42,8 +42,6 @@ class Contact(Object): Additional data about the contact in the form of a vCard. """ - __slots__ = ["phone_number", "first_name", "last_name", "user_id", "vcard"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index 45994e16..4bb40980 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -49,8 +49,6 @@ class Document(Object): Document thumbnails as defined by sender. """ - __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "thumbs"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/game.py b/pyrogram/client/types/messages_and_media/game.py index 2b400e65..38c00fdf 100644 --- a/pyrogram/client/types/messages_and_media/game.py +++ b/pyrogram/client/types/messages_and_media/game.py @@ -48,8 +48,6 @@ class Game(Object): Upload via BotFather. """ - __slots__ = ["id", "title", "short_name", "description", "photo", "animation"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/location.py b/pyrogram/client/types/messages_and_media/location.py index 5af55f0f..4dec0277 100644 --- a/pyrogram/client/types/messages_and_media/location.py +++ b/pyrogram/client/types/messages_and_media/location.py @@ -33,8 +33,6 @@ class Location(Object): Latitude as defined by sender. """ - __slots__ = ["longitude", "latitude"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index ed0088cd..7616a6ec 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -264,17 +264,6 @@ class Message(Object, Update): # TODO: Add game missing field. Also invoice, successful_payment, connected_website - __slots__ = [ - "message_id", "date", "chat", "from_user", "forward_from", "forward_sender_name", "forward_from_chat", - "forward_from_message_id", "forward_signature", "forward_date", "reply_to_message", "mentioned", "empty", - "service", "media", "edit_date", "media_group_id", "author_signature", "text", "entities", "caption_entities", - "audio", "document", "photo", "sticker", "animation", "game", "video", "voice", "video_note", "caption", - "contact", "location", "venue", "web_page", "poll", "new_chat_members", "left_chat_member", "new_chat_title", - "new_chat_photo", "delete_chat_photo", "group_chat_created", "supergroup_chat_created", "channel_chat_created", - "migrate_to_chat_id", "migrate_from_chat_id", "pinned_message", "game_high_score", "views", "via_bot", - "outgoing", "matches", "command", "reply_markup" - ] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/message_entity.py b/pyrogram/client/types/messages_and_media/message_entity.py index 1c3076a2..63aeb447 100644 --- a/pyrogram/client/types/messages_and_media/message_entity.py +++ b/pyrogram/client/types/messages_and_media/message_entity.py @@ -47,8 +47,6 @@ class MessageEntity(Object): For "text_mention" only, the mentioned user. """ - __slots__ = ["type", "offset", "length", "url", "user"] - ENTITIES = { types.MessageEntityMention.ID: "mention", types.MessageEntityHashtag.ID: "hashtag", diff --git a/pyrogram/client/types/messages_and_media/photo.py b/pyrogram/client/types/messages_and_media/photo.py index 653fe4c0..8ccaaf19 100644 --- a/pyrogram/client/types/messages_and_media/photo.py +++ b/pyrogram/client/types/messages_and_media/photo.py @@ -49,8 +49,6 @@ class Photo(Object): Available thumbnails of this photo. """ - __slots__ = ["file_id", "width", "height", "file_size", "date", "thumbs"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index 2570fdf1..fecc5f7d 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -48,8 +48,6 @@ class Poll(Object, Update): Index of your chosen option (0-9), None in case you haven't voted yet. """ - __slots__ = ["id", "question", "options", "is_closed", "total_voters", "chosen_option"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/poll_option.py b/pyrogram/client/types/messages_and_media/poll_option.py index 35f6b071..2882860a 100644 --- a/pyrogram/client/types/messages_and_media/poll_option.py +++ b/pyrogram/client/types/messages_and_media/poll_option.py @@ -35,8 +35,6 @@ class PollOption(Object): The data this poll option is holding. """ - __slots__ = ["text", "voter_count", "data"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/sticker.py b/pyrogram/client/types/messages_and_media/sticker.py index 78fdda38..2fc5caa1 100644 --- a/pyrogram/client/types/messages_and_media/sticker.py +++ b/pyrogram/client/types/messages_and_media/sticker.py @@ -65,10 +65,6 @@ class Sticker(Object): # TODO: Add mask position - __slots__ = [ - "file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "emoji", "set_name", "thumbs" - ] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/stripped_thumbnail.py b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py index 1c967042..ea24e071 100644 --- a/pyrogram/client/types/messages_and_media/stripped_thumbnail.py +++ b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py @@ -29,8 +29,6 @@ class StrippedThumbnail(Object): Thumbnail data """ - __slots__ = ["data"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/thumbnail.py b/pyrogram/client/types/messages_and_media/thumbnail.py index ee173b1c..936241c6 100644 --- a/pyrogram/client/types/messages_and_media/thumbnail.py +++ b/pyrogram/client/types/messages_and_media/thumbnail.py @@ -43,8 +43,6 @@ class Thumbnail(Object): File size. """ - __slots__ = ["file_id", "width", "height", "file_size"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/venue.py b/pyrogram/client/types/messages_and_media/venue.py index 45d9368f..419af318 100644 --- a/pyrogram/client/types/messages_and_media/venue.py +++ b/pyrogram/client/types/messages_and_media/venue.py @@ -44,8 +44,6 @@ class Venue(Object): """ - __slots__ = ["location", "title", "address", "foursquare_id", "foursquare_type"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/video.py b/pyrogram/client/types/messages_and_media/video.py index 0a7f47cd..d9c2c37f 100644 --- a/pyrogram/client/types/messages_and_media/video.py +++ b/pyrogram/client/types/messages_and_media/video.py @@ -61,11 +61,6 @@ class Video(Object): Video thumbnails. """ - __slots__ = [ - "file_id", "width", "height", "duration", "file_name", "mime_type", "supports_streaming", "file_size", "date", - "thumbs" - ] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/video_note.py b/pyrogram/client/types/messages_and_media/video_note.py index 54c9ec8d..e419d692 100644 --- a/pyrogram/client/types/messages_and_media/video_note.py +++ b/pyrogram/client/types/messages_and_media/video_note.py @@ -52,8 +52,6 @@ class VideoNote(Object): Video thumbnails. """ - __slots__ = ["file_id", "mime_type", "file_size", "date", "length", "duration", "thumbs"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/voice.py b/pyrogram/client/types/messages_and_media/voice.py index e4256197..0f480ad5 100644 --- a/pyrogram/client/types/messages_and_media/voice.py +++ b/pyrogram/client/types/messages_and_media/voice.py @@ -47,8 +47,6 @@ class Voice(Object): Date the voice was sent in Unix time. """ - __slots__ = ["file_id", "duration", "waveform", "mime_type", "file_size", "date"] - def __init__( self, *, diff --git a/pyrogram/client/types/messages_and_media/webpage.py b/pyrogram/client/types/messages_and_media/webpage.py index 9ddc7c6c..d65d34d8 100644 --- a/pyrogram/client/types/messages_and_media/webpage.py +++ b/pyrogram/client/types/messages_and_media/webpage.py @@ -83,12 +83,6 @@ class WebPage(Object): Author of the webpage, eg the Twitter user for a tweet, or the author in an article. """ - __slots__ = [ - "id", "url", "display_url", "type", "site_name", "title", "description", - "audio", "document", "photo", "animation", "video", - "embed_url", "embed_type", "embed_width", "embed_height", "duration", "author" - ] - def __init__( self, *, diff --git a/pyrogram/client/types/object.py b/pyrogram/client/types/object.py index f7fc413f..5978203f 100644 --- a/pyrogram/client/types/object.py +++ b/pyrogram/client/types/object.py @@ -29,8 +29,6 @@ class Meta(type, metaclass=type("", (type,), {"__str__": lambda _: "~hi"})): class Object(metaclass=Meta): - __slots__ = ["_client"] - def __init__(self, client: "pyrogram.BaseClient" = None): self._client = client @@ -50,7 +48,7 @@ class Object(metaclass=Meta): else (attr, str(datetime.fromtimestamp(getattr(obj, attr)))) if attr.endswith("date") else (attr, getattr(obj, attr)) - for attr in getattr(obj, "__slots__", []) + for attr in filter(lambda x: not x.startswith("_"), obj.__dict__) if getattr(obj, attr) is not None ] ) @@ -63,13 +61,13 @@ class Object(metaclass=Meta): self.__class__.__name__, ", ".join( "{}={}".format(attr, repr(getattr(self, attr))) - for attr in self.__slots__ + for attr in filter(lambda x: not x.startswith("_"), self.__dict__) if getattr(self, attr) is not None ) ) def __eq__(self, other: "Object") -> bool: - for attr in self.__slots__: + for attr in self.__dict__: try: if getattr(self, attr) != getattr(other, attr): return False diff --git a/pyrogram/client/types/update.py b/pyrogram/client/types/update.py index 48179ac0..2ec22f5a 100644 --- a/pyrogram/client/types/update.py +++ b/pyrogram/client/types/update.py @@ -26,8 +26,6 @@ class ContinuePropagation(StopIteration): class Update: - __slots__ = [] - def stop_propagation(self): raise StopPropagation diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 396831cc..cfed441f 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -95,12 +95,6 @@ class Chat(Object): Information about the chat default permissions, for groups and supergroups. """ - __slots__ = [ - "id", "type", "is_verified", "is_restricted", "is_scam", "is_support", "title", "username", "first_name", - "last_name", "photo", "description", "invite_link", "pinned_message", "sticker_set_name", "can_set_sticker_set", - "members_count", "restriction_reason", "permissions" - ] - def __init__( self, *, diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 7451012c..42eb08f3 100644 --- a/pyrogram/client/types/user_and_chats/chat_member.py +++ b/pyrogram/client/types/user_and_chats/chat_member.py @@ -54,8 +54,6 @@ class ChatMember(Object): Information about the member permissions. """ - __slots__ = ["user", "status", "date", "is_member", "invited_by", "promoted_by", "restricted_by", "permissions"] - def __init__( self, *, diff --git a/pyrogram/client/types/user_and_chats/chat_permissions.py b/pyrogram/client/types/user_and_chats/chat_permissions.py index 84099955..551dc667 100644 --- a/pyrogram/client/types/user_and_chats/chat_permissions.py +++ b/pyrogram/client/types/user_and_chats/chat_permissions.py @@ -94,13 +94,6 @@ class ChatPermissions(Object): True, if polls can be sent, implies can_send_media_messages. """ - __slots__ = [ - "until_date", "can_be_edited", "can_change_info", "can_post_messages", "can_edit_messages", - "can_delete_messages", "can_restrict_members", "can_invite_users", "can_pin_messages", "can_promote_members", - "can_send_messages", "can_send_media_messages", "can_send_other_messages", "can_add_web_page_previews", - "can_send_polls" - ] - def __init__( self, *, diff --git a/pyrogram/client/types/user_and_chats/chat_photo.py b/pyrogram/client/types/user_and_chats/chat_photo.py index 1584a286..70e114af 100644 --- a/pyrogram/client/types/user_and_chats/chat_photo.py +++ b/pyrogram/client/types/user_and_chats/chat_photo.py @@ -35,8 +35,6 @@ class ChatPhoto(Object): Unique file identifier of big (640x640) chat photo. This file_id can be used only for photo download. """ - __slots__ = ["small_file_id", "big_file_id"] - def __init__( self, *, diff --git a/pyrogram/client/types/user_and_chats/chat_preview.py b/pyrogram/client/types/user_and_chats/chat_preview.py index 781f85c8..10754170 100644 --- a/pyrogram/client/types/user_and_chats/chat_preview.py +++ b/pyrogram/client/types/user_and_chats/chat_preview.py @@ -45,8 +45,6 @@ class ChatPreview(Object): Preview of some of the chat members. """ - __slots__ = ["title", "type", "members_count", "photo", "members"] - def __init__( self, *, diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index a78e501b..471c4319 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -47,8 +47,6 @@ class Dialog(Object): True, if the dialog is pinned. """ - __slots__ = ["chat", "top_message", "unread_messages_count", "unread_mentions_count", "unread_mark", "is_pinned"] - def __init__( self, *, diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 43baca25..783c0566 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -106,12 +106,6 @@ class User(Object, Update): This field is available only in case *is_restricted* is True. """ - __slots__ = [ - "id", "is_self", "is_contact", "is_mutual_contact", "is_deleted", "is_bot", "is_verified", "is_restricted", - "is_scam", "is_support", "first_name", "last_name", "status", "last_online_date", "next_offline_date", - "username", "language_code", "dc_id", "phone_number", "photo", "restriction_reason" - ] - def __init__( self, *, From 64939e52892a860173c83fea7b28ec81833518b3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 2 Aug 2019 01:15:01 +0200 Subject: [PATCH 14/14] Update Document file ids to make them compatible again with the Bot API Telegram changed something server side on 29 July, 2019 starting exactly at 04:00 AM UTC+1 (DST), logs say. Looks like Document file ids, just like Photo-like ids, are going to change as well after all, if we want to keep them compatible with the Bot API --- pyrogram/client/ext/utils.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index fbee9ea8..cdc0684c 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -21,9 +21,8 @@ import struct from typing import List from typing import Union -from pyrogram.api.types import PeerUser, PeerChat, PeerChannel - import pyrogram +from pyrogram.api.types import PeerUser, PeerChat, PeerChannel from . import BaseClient from ...api import types @@ -32,10 +31,17 @@ def decode(s: str) -> bytes: s = base64.urlsafe_b64decode(s + "=" * (-len(s) % 4)) r = b"" - assert s[-1] == 2 + try: + assert s[-1] == 2 + skip = 1 + except AssertionError: + assert s[-2] == 22 + assert s[-1] == 4 + skip = 2 i = 0 - while i < len(s) - 1: + + while i < len(s) - skip: if s[i] != 0: r += bytes([s[i]]) else: @@ -51,7 +57,7 @@ def encode(s: bytes) -> str: r = b"" n = 0 - for i in s + bytes([2]): + for i in s + bytes([22]) + bytes([4]): if i == 0: n += 1 else: