From 4661fb035b3122e01522b0122ae994d9c5c91691 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 20:17:42 +0200 Subject: [PATCH 001/202] Refactor Poll types and methods to reflect Bot API 4.2 docs --- pyrogram/client/methods/messages/__init__.py | 4 +- .../client/methods/messages/retract_vote.py | 13 ++--- pyrogram/client/methods/messages/send_poll.py | 4 +- .../messages/{close_poll.py => stop_poll.py} | 28 ++++++---- pyrogram/client/methods/messages/vote_poll.py | 14 ++--- .../client/types/messages_and_media/poll.py | 54 ++++++++++--------- .../types/messages_and_media/poll_option.py | 21 ++++---- pyrogram/client/types/pyrogram_type.py | 2 +- 8 files changed, 74 insertions(+), 66 deletions(-) rename pyrogram/client/methods/messages/{close_poll.py => stop_poll.py} (71%) diff --git a/pyrogram/client/methods/messages/__init__.py b/pyrogram/client/methods/messages/__init__.py index dde50b7b..d26c51cc 100644 --- a/pyrogram/client/methods/messages/__init__.py +++ b/pyrogram/client/methods/messages/__init__.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .close_poll import ClosePoll +from .stop_poll import StopPoll from .delete_messages import DeleteMessages from .download_media import DownloadMedia from .edit_message_caption import EditMessageCaption @@ -72,7 +72,7 @@ class Messages( SendVoice, SendPoll, VotePoll, - ClosePoll, + StopPoll, RetractVote, DownloadMedia, IterHistory, diff --git a/pyrogram/client/methods/messages/retract_vote.py b/pyrogram/client/methods/messages/retract_vote.py index 8fa8996c..ce8a0140 100644 --- a/pyrogram/client/methods/messages/retract_vote.py +++ b/pyrogram/client/methods/messages/retract_vote.py @@ -18,6 +18,7 @@ from typing import Union +import pyrogram from pyrogram.api import functions from pyrogram.client.ext import BaseClient @@ -26,8 +27,8 @@ class RetractVote(BaseClient): def retract_vote( self, chat_id: Union[int, str], - message_id: id - ) -> bool: + message_id: int + ) -> "pyrogram.Poll": """Use this method to retract your vote in a poll. Args: @@ -37,15 +38,15 @@ class RetractVote(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). message_id (``int``): - Unique poll message identifier inside this chat. + Identifier of the original message with the poll. Returns: - On success, True is returned. + On success, the :obj:`Poll ` with the retracted vote is returned. Raises: :class:`RPCError ` in case of a Telegram RPC error. """ - self.send( + r = self.send( functions.messages.SendVote( peer=self.resolve_peer(chat_id), msg_id=message_id, @@ -53,4 +54,4 @@ class RetractVote(BaseClient): ) ) - return True + return pyrogram.Poll._parse(self, r.updates[0]) diff --git a/pyrogram/client/methods/messages/send_poll.py b/pyrogram/client/methods/messages/send_poll.py index 13e55b08..6b4e227a 100644 --- a/pyrogram/client/methods/messages/send_poll.py +++ b/pyrogram/client/methods/messages/send_poll.py @@ -47,10 +47,10 @@ class SendPoll(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). question (``str``): - The poll question, as string. + Poll question, 1-255 characters. options (List of ``str``): - The poll options, as list of strings (2 to 10 options are allowed). + List of answer options, 2-10 strings 1-100 characters each. disable_notification (``bool``, *optional*): Sends the message silently. diff --git a/pyrogram/client/methods/messages/close_poll.py b/pyrogram/client/methods/messages/stop_poll.py similarity index 71% rename from pyrogram/client/methods/messages/close_poll.py rename to pyrogram/client/methods/messages/stop_poll.py index 1b1164c2..a5a4ecc8 100644 --- a/pyrogram/client/methods/messages/close_poll.py +++ b/pyrogram/client/methods/messages/stop_poll.py @@ -18,19 +18,21 @@ from typing import Union +import pyrogram from pyrogram.api import functions, types from pyrogram.client.ext import BaseClient -class ClosePoll(BaseClient): - def close_poll( +class StopPoll(BaseClient): + def stop_poll( self, chat_id: Union[int, str], - message_id: id - ) -> bool: - """Use this method to close (stop) a poll. + message_id: int, + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> "pyrogram.Poll": + """Use this method to stop a poll which was sent by you. - Closed polls can't be reopened and nobody will be able to vote in it anymore. + Stopped polls can't be reopened and nobody will be able to vote in it anymore. Args: chat_id (``int`` | ``str``): @@ -39,17 +41,20 @@ class ClosePoll(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). message_id (``int``): - Unique poll message identifier inside this chat. + Identifier of the original message with the poll. + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. Returns: - On success, True is returned. + On success, the stopped :obj:`Poll ` with the final results is returned. Raises: :class:`RPCError ` in case of a Telegram RPC error. """ poll = self.get_messages(chat_id, message_id).poll - self.send( + r = self.send( functions.messages.EditMessage( peer=self.resolve_peer(chat_id), id=message_id, @@ -60,8 +65,9 @@ class ClosePoll(BaseClient): question="", answers=[] ) - ) + ), + reply_markup=reply_markup.write() if reply_markup else None ) ) - return True + return pyrogram.Poll._parse(self, r.updates[0]) diff --git a/pyrogram/client/methods/messages/vote_poll.py b/pyrogram/client/methods/messages/vote_poll.py index 2a9de874..58f21a6c 100644 --- a/pyrogram/client/methods/messages/vote_poll.py +++ b/pyrogram/client/methods/messages/vote_poll.py @@ -18,6 +18,7 @@ from typing import Union +import pyrogram from pyrogram.api import functions from pyrogram.client.ext import BaseClient @@ -28,7 +29,7 @@ class VotePoll(BaseClient): chat_id: Union[int, str], message_id: id, option: int - ) -> bool: + ) -> "pyrogram.Poll": """Use this method to vote a poll. Args: @@ -38,25 +39,26 @@ class VotePoll(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). message_id (``int``): - Unique poll message identifier inside this chat. + Identifier of the original message with the poll. option (``int``): Index of the poll option you want to vote for (0 to 9). Returns: - On success, True is returned. + On success, the :obj:`Poll ` with the chosen option is returned. Raises: :class:`RPCError ` in case of a Telegram RPC error. """ + poll = self.get_messages(chat_id, message_id).poll - self.send( + r = self.send( functions.messages.SendVote( peer=self.resolve_peer(chat_id), msg_id=message_id, - options=[poll.options[option].data] + options=[poll.options[option]._data] ) ) - return True + return pyrogram.Poll._parse(self, r.updates[0]) diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index 68667334..dfe7daa9 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -29,78 +29,80 @@ class Poll(PyrogramType): Args: id (``int``): - The poll id in this chat. - - closed (``bool``): - Whether the poll is closed or not. + Unique poll identifier. question (``str``): - Poll question. + Poll question, 1-255 characters. options (List of :obj:`PollOption`): - The available poll options. + List of poll options. + + is_closed (``bool``): + True, if the poll is closed. total_voters (``int``): - Total amount of voters for this poll. + Total count of voters for this poll. - option_chosen (``int``, *optional*): - The index of your chosen option (in case you voted already), None otherwise. + chosen_option (``int``, *optional*): + Index of your chosen option (0-9), None in case you haven't voted yet. """ - __slots__ = ["id", "closed", "question", "options", "total_voters", "option_chosen"] + __slots__ = ["id", "question", "options", "is_closed", "total_voters", "chosen_option"] def __init__( self, *, client: "pyrogram.client.ext.BaseClient", id: int, - closed: bool, question: str, options: List[PollOption], + is_closed: bool, total_voters: int, - option_chosen: int = None + chosen_option: int = None ): super().__init__(client) self.id = id - self.closed = closed self.question = question self.options = options + self.is_closed = is_closed self.total_voters = total_voters - self.option_chosen = option_chosen + self.chosen_option = chosen_option @staticmethod def _parse(client, media_poll: types.MessageMediaPoll) -> "Poll": poll = media_poll.poll results = media_poll.results.results total_voters = media_poll.results.total_voters - option_chosen = None + chosen_option = None options = [] for i, answer in enumerate(poll.answers): - voters = 0 + voter_count = 0 if results: result = results[i] - voters = result.voters + voter_count = result.voters if result.chosen: - option_chosen = i + chosen_option = i - options.append(PollOption( - text=answer.text, - voters=voters, - data=answer.option, - client=client - )) + options.append( + PollOption( + text=answer.text, + voter_count=voter_count, + data=answer.option, + client=client + ) + ) return Poll( id=poll.id, - closed=poll.closed, question=poll.question, options=options, + is_closed=poll.closed, total_voters=total_voters, - option_chosen=option_chosen, + chosen_option=chosen_option, client=client ) diff --git a/pyrogram/client/types/messages_and_media/poll_option.py b/pyrogram/client/types/messages_and_media/poll_option.py index c45c1db2..4b32623a 100644 --- a/pyrogram/client/types/messages_and_media/poll_option.py +++ b/pyrogram/client/types/messages_and_media/poll_option.py @@ -21,32 +21,29 @@ from ..pyrogram_type import PyrogramType class PollOption(PyrogramType): - """This object represents a Poll Option. + """This object contains information about one answer option in a poll. Args: text (``str``): - Text of the poll option. + Option text, 1-100 characters. - voters (``int``): - The number of users who voted this option. - It will be 0 until you vote for the poll. - - data (``bytes``): - Unique data that identifies this option among all the other options in a poll. + voter_count (``int``): + Number of users that voted for this option. + Equals to 0 until you vote. """ - __slots__ = ["text", "voters", "data"] + __slots__ = ["text", "voter_count", "_data"] def __init__( self, *, client: "pyrogram.client.ext.BaseClient", text: str, - voters: int, + voter_count: int, data: bytes ): super().__init__(client) self.text = text - self.voters = voters - self.data = data + self.voter_count = voter_count + self._data = data # Hidden diff --git a/pyrogram/client/types/pyrogram_type.py b/pyrogram/client/types/pyrogram_type.py index af828926..5f757d43 100644 --- a/pyrogram/client/types/pyrogram_type.py +++ b/pyrogram/client/types/pyrogram_type.py @@ -51,7 +51,7 @@ def default(o: PyrogramType): return remove_none( OrderedDict( [("_", "pyrogram." + o.__class__.__name__)] - + [i for i in content.items()] + + [i for i in content.items() if not i[0].startswith("_")] ) ) except AttributeError: From 22a7e338ff418f57d12ace8ca4f650a2e02c8f4c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 20:18:44 +0200 Subject: [PATCH 002/202] Fetch the pinned message in own chat (saved messages) --- pyrogram/client/types/user_and_chats/chat.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index a13f8a2b..1d4369d4 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -185,6 +185,12 @@ class Chat(PyrogramType): if isinstance(chat_full, types.UserFull): parsed_chat = Chat._parse_user_chat(client, chat_full.user) parsed_chat.description = chat_full.about + + if chat_full.pinned_msg_id: + parsed_chat.pinned_message = client.get_messages( + parsed_chat.id, + message_ids=chat_full.pinned_msg_id + ) else: full_chat = chat_full.full_chat chat = None From ebacefb6e039c4a16b0c2993c6cfb9da705328bf Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 20:33:45 +0200 Subject: [PATCH 003/202] Increase media thumbnail size limit --- pyrogram/client/methods/messages/send_animation.py | 2 +- pyrogram/client/methods/messages/send_audio.py | 2 +- pyrogram/client/methods/messages/send_document.py | 2 +- pyrogram/client/methods/messages/send_video.py | 2 +- pyrogram/client/methods/messages/send_video_note.py | 2 +- .../client/types/input_media/input_media_animation.py | 2 +- pyrogram/client/types/input_media/input_media_audio.py | 2 +- .../client/types/input_media/input_media_document.py | 2 +- pyrogram/client/types/input_media/input_media_video.py | 2 +- pyrogram/client/types/messages_and_media/message.py | 10 +++++----- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pyrogram/client/methods/messages/send_animation.py b/pyrogram/client/methods/messages/send_animation.py index 798d236d..c8da7297 100644 --- a/pyrogram/client/methods/messages/send_animation.py +++ b/pyrogram/client/methods/messages/send_animation.py @@ -83,7 +83,7 @@ class SendAnimation(BaseClient): thumb (``str``, *optional*): Thumbnail of the animation file sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. disable_notification (``bool``, *optional*): diff --git a/pyrogram/client/methods/messages/send_audio.py b/pyrogram/client/methods/messages/send_audio.py index d514b737..0ef2aef3 100644 --- a/pyrogram/client/methods/messages/send_audio.py +++ b/pyrogram/client/methods/messages/send_audio.py @@ -85,7 +85,7 @@ class SendAudio(BaseClient): thumb (``str``, *optional*): Thumbnail of the music file album cover. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. disable_notification (``bool``, *optional*): diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index a36a0fbb..ad47d38c 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -63,7 +63,7 @@ class SendDocument(BaseClient): thumb (``str``, *optional*): Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. caption (``str``, *optional*): diff --git a/pyrogram/client/methods/messages/send_video.py b/pyrogram/client/methods/messages/send_video.py index 08d8b7ab..c9456858 100644 --- a/pyrogram/client/methods/messages/send_video.py +++ b/pyrogram/client/methods/messages/send_video.py @@ -84,7 +84,7 @@ class SendVideo(BaseClient): thumb (``str``, *optional*): Thumbnail of the video sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. supports_streaming (``bool``, *optional*): diff --git a/pyrogram/client/methods/messages/send_video_note.py b/pyrogram/client/methods/messages/send_video_note.py index 4844dd65..19b35256 100644 --- a/pyrogram/client/methods/messages/send_video_note.py +++ b/pyrogram/client/methods/messages/send_video_note.py @@ -69,7 +69,7 @@ class SendVideoNote(BaseClient): thumb (``str``, *optional*): Thumbnail of the video sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. disable_notification (``bool``, *optional*): diff --git a/pyrogram/client/types/input_media/input_media_animation.py b/pyrogram/client/types/input_media/input_media_animation.py index e77499b5..6c06df7b 100644 --- a/pyrogram/client/types/input_media/input_media_animation.py +++ b/pyrogram/client/types/input_media/input_media_animation.py @@ -31,7 +31,7 @@ class InputMediaAnimation(InputMedia): thumb (``str``, *optional*): Thumbnail of the animation file sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. caption (``str``, *optional*): diff --git a/pyrogram/client/types/input_media/input_media_audio.py b/pyrogram/client/types/input_media/input_media_audio.py index e8f1c257..6b7659fe 100644 --- a/pyrogram/client/types/input_media/input_media_audio.py +++ b/pyrogram/client/types/input_media/input_media_audio.py @@ -32,7 +32,7 @@ class InputMediaAudio(InputMedia): thumb (``str``, *optional*): Thumbnail of the music file album cover. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. caption (``str``, *optional*): diff --git a/pyrogram/client/types/input_media/input_media_document.py b/pyrogram/client/types/input_media/input_media_document.py index 9391e7d8..a5d36261 100644 --- a/pyrogram/client/types/input_media/input_media_document.py +++ b/pyrogram/client/types/input_media/input_media_document.py @@ -31,7 +31,7 @@ class InputMediaDocument(InputMedia): thumb (``str``): Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. caption (``str``, *optional*): diff --git a/pyrogram/client/types/input_media/input_media_video.py b/pyrogram/client/types/input_media/input_media_video.py index 5c918f13..27d166bd 100644 --- a/pyrogram/client/types/input_media/input_media_video.py +++ b/pyrogram/client/types/input_media/input_media_video.py @@ -33,7 +33,7 @@ class InputMediaVideo(InputMedia): thumb (``str``): Thumbnail of the video sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. caption (``str``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index fc2cb8fb..1ad00a7f 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -795,7 +795,7 @@ class Message(PyrogramType, Update): thumb (``str``, *optional*): Thumbnail of the animation file sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. disable_notification (``bool``, *optional*): @@ -930,7 +930,7 @@ class Message(PyrogramType, Update): thumb (``str``, *optional*): Thumbnail of the music file album cover. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. disable_notification (``bool``, *optional*): @@ -1257,7 +1257,7 @@ class Message(PyrogramType, Update): thumb (``str``, *optional*): Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. caption (``str``, *optional*): @@ -2064,7 +2064,7 @@ class Message(PyrogramType, Update): thumb (``str``, *optional*): Thumbnail of the video sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. supports_streaming (``bool``, *optional*): @@ -2189,7 +2189,7 @@ class Message(PyrogramType, Update): thumb (``str``, *optional*): Thumbnail of the video sent. The thumbnail should be in JPEG format and less than 200 KB in size. - A thumbnail's width and height should not exceed 90 pixels. + A thumbnail's width and height should not exceed 320 pixels. Thumbnails can't be reused and can be only uploaded as a new file. disable_notification (``bool``, *optional*): From cbc938931dbe222e3b46e1289b298b36f02e1e3e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 20:34:46 +0200 Subject: [PATCH 004/202] Rename forward_from_name to forward_sender_name --- .../client/types/messages_and_media/message.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 1ad00a7f..de2f51b1 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -79,7 +79,7 @@ class Message(PyrogramType, Update): forward_from (:obj:`User `, *optional*): For forwarded messages, sender of the original message. - forward_from_name (``str``, *optional*): + forward_sender_name (``str``, *optional*): For messages forwarded from users who have hidden their accounts, name of the user. forward_from_chat (:obj:`Chat `, *optional*): @@ -267,7 +267,7 @@ class Message(PyrogramType, Update): # TODO: Add game missing field. Also invoice, successful_payment, connected_website __slots__ = [ - "message_id", "date", "chat", "from_user", "forward_from", "forward_from_name", "forward_from_chat", + "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", @@ -286,7 +286,7 @@ class Message(PyrogramType, Update): chat: Chat = None, from_user: User = None, forward_from: User = None, - forward_from_name: str = None, + forward_sender_name: str = None, forward_from_chat: Chat = None, forward_from_message_id: int = None, forward_signature: str = None, @@ -348,7 +348,7 @@ class Message(PyrogramType, Update): self.chat = chat self.from_user = from_user self.forward_from = forward_from - self.forward_from_name = forward_from_name + self.forward_sender_name = forward_sender_name self.forward_from_chat = forward_from_chat self.forward_from_message_id = forward_from_message_id self.forward_signature = forward_signature @@ -487,7 +487,7 @@ class Message(PyrogramType, Update): entities = list(filter(lambda x: x is not None, entities)) forward_from = None - forward_from_name = None + forward_sender_name = None forward_from_chat = None forward_from_message_id = None forward_signature = None @@ -501,7 +501,7 @@ class Message(PyrogramType, Update): if forward_header.from_id: forward_from = User._parse(client, users[forward_header.from_id]) elif forward_header.from_name: - forward_from_name = forward_header.from_name + forward_sender_name = forward_header.from_name else: forward_from_chat = Chat._parse_channel_chat(client, chats[forward_header.channel_id]) forward_from_message_id = forward_header.channel_post @@ -607,7 +607,7 @@ class Message(PyrogramType, Update): caption_entities=entities or None if media is not None else None, author_signature=message.post_author, forward_from=forward_from, - forward_from_name=forward_from_name, + forward_sender_name=forward_sender_name, forward_from_chat=forward_from_chat, forward_from_message_id=forward_from_message_id, forward_signature=forward_signature, From 5c638e707e0fe70e3b449ffdbdafd5be3ba8b36a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 20:48:25 +0200 Subject: [PATCH 005/202] Poll ids are now strings and not integers --- pyrogram/client/types/messages_and_media/poll.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index dfe7daa9..e0461bba 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -28,7 +28,7 @@ class Poll(PyrogramType): """This object represents a Poll. Args: - id (``int``): + id (``str``): Unique poll identifier. question (``str``): @@ -53,7 +53,7 @@ class Poll(PyrogramType): self, *, client: "pyrogram.client.ext.BaseClient", - id: int, + id: str, question: str, options: List[PollOption], is_closed: bool, @@ -98,7 +98,7 @@ class Poll(PyrogramType): ) return Poll( - id=poll.id, + id=str(poll.id), question=poll.question, options=options, is_closed=poll.closed, From 5905f761fa214a459aa66f63630c72b2cd408273 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 20:50:13 +0200 Subject: [PATCH 006/202] Add PollHandler type and on_poll decorator for handling Poll updates --- pyrogram/client/ext/dispatcher.py | 7 ++- pyrogram/client/handlers/__init__.py | 3 +- pyrogram/client/handlers/poll_handler.py | 48 +++++++++++++++ .../client/methods/decorators/__init__.py | 4 +- pyrogram/client/methods/decorators/on_poll.py | 59 +++++++++++++++++++ .../client/types/messages_and_media/poll.py | 3 +- 6 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 pyrogram/client/handlers/poll_handler.py create mode 100644 pyrogram/client/methods/decorators/on_poll.py diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 7552b034..46be47f7 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -26,7 +26,7 @@ import pyrogram from pyrogram.api import types from ..handlers import ( CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, - UserStatusHandler, RawUpdateHandler, InlineQueryHandler + UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler ) log = logging.getLogger(__name__) @@ -79,7 +79,10 @@ class Dispatcher: ), (types.UpdateBotInlineQuery,): - lambda upd, usr, cht: (pyrogram.InlineQuery._parse(self.client, upd, usr), InlineQueryHandler) + lambda upd, usr, cht: (pyrogram.InlineQuery._parse(self.client, upd, usr), InlineQueryHandler), + + (types.UpdateMessagePoll,): + lambda upd, usr, cht: (pyrogram.Poll._parse(self.client, upd), PollHandler) } self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple} diff --git a/pyrogram/client/handlers/__init__.py b/pyrogram/client/handlers/__init__.py index 5e392949..c88c12fe 100644 --- a/pyrogram/client/handlers/__init__.py +++ b/pyrogram/client/handlers/__init__.py @@ -21,10 +21,11 @@ from .deleted_messages_handler import DeletedMessagesHandler from .disconnect_handler import DisconnectHandler from .inline_query_handler import InlineQueryHandler from .message_handler import MessageHandler +from .poll_handler import PollHandler from .raw_update_handler import RawUpdateHandler from .user_status_handler import UserStatusHandler __all__ = [ "MessageHandler", "DeletedMessagesHandler", "CallbackQueryHandler", "RawUpdateHandler", "DisconnectHandler", - "UserStatusHandler", "InlineQueryHandler" + "UserStatusHandler", "InlineQueryHandler", "PollHandler" ] diff --git a/pyrogram/client/handlers/poll_handler.py b/pyrogram/client/handlers/poll_handler.py new file mode 100644 index 00000000..567fcec0 --- /dev/null +++ b/pyrogram/client/handlers/poll_handler.py @@ -0,0 +1,48 @@ +# 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 .handler import Handler + + +class PollHandler(Handler): + """The Poll handler class. Used to handle polls updates. + + It is intended to be used with :meth:`add_handler() ` + + For a nicer way to register this handler, have a look at the + :meth:`on_poll() ` decorator. + + Args: + callback (``callable``): + Pass a function that will be called when a new poll update arrives. It takes *(client, poll)* + as positional arguments (look at the section below for a detailed description). + + filters (:obj:`Filters `): + Pass one or more filters to allow only a subset of polls to be passed + in your callback function. + + Other parameters: + client (:obj:`Client `): + The Client itself, useful when you want to call other API methods inside the poll handler. + + poll (:obj:`Poll `): + The received poll. + """ + + def __init__(self, callback: callable, filters=None): + super().__init__(callback, filters) diff --git a/pyrogram/client/methods/decorators/__init__.py b/pyrogram/client/methods/decorators/__init__.py index 33f55a3d..2a2861ae 100644 --- a/pyrogram/client/methods/decorators/__init__.py +++ b/pyrogram/client/methods/decorators/__init__.py @@ -21,6 +21,7 @@ from .on_deleted_messages import OnDeletedMessages from .on_disconnect import OnDisconnect from .on_inline_query import OnInlineQuery from .on_message import OnMessage +from .on_poll import OnPoll from .on_raw_update import OnRawUpdate from .on_user_status import OnUserStatus @@ -32,6 +33,7 @@ class Decorators( OnRawUpdate, OnDisconnect, OnUserStatus, - OnInlineQuery + OnInlineQuery, + OnPoll ): pass diff --git a/pyrogram/client/methods/decorators/on_poll.py b/pyrogram/client/methods/decorators/on_poll.py new file mode 100644 index 00000000..56dcd757 --- /dev/null +++ b/pyrogram/client/methods/decorators/on_poll.py @@ -0,0 +1,59 @@ +# 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 typing import Tuple + +import pyrogram +from pyrogram.client.filters.filter import Filter +from pyrogram.client.handlers.handler import Handler +from ...ext import BaseClient + + +class OnPoll(BaseClient): + def on_poll( + self=None, + filters=None, + group: int = 0 + ) -> callable: + """Use this decorator to automatically register a function for handling poll updates. + This does the same thing as :meth:`add_handler` using the :class:`PollHandler`. + + Args: + filters (:obj:`Filters `): + Pass one or more filters to allow only a subset of polls to be passed + in your function. + + group (``int``, *optional*): + The group identifier, defaults to 0. + """ + + def decorator(func: callable) -> Tuple[Handler, int]: + if isinstance(func, tuple): + func = func[0].callback + + handler = pyrogram.PollHandler(func, filters) + + if isinstance(self, Filter): + return pyrogram.PollHandler(func, self), group if filters is None else filters + + if self is not None: + self.add_handler(handler, group) + + return handler, group + + return decorator diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index e0461bba..acaf8697 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -22,9 +22,10 @@ import pyrogram from pyrogram.api import types from .poll_option import PollOption from ..pyrogram_type import PyrogramType +from ..update import Update -class Poll(PyrogramType): +class Poll(PyrogramType, Update): """This object represents a Poll. Args: From d6d2923e34381a90e62a3779e82532fc7923ef21 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 20:52:00 +0200 Subject: [PATCH 007/202] Add missing Poll docstrings in Message --- pyrogram/client/types/messages_and_media/message.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index de2f51b1..8dc05661 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -186,6 +186,9 @@ class Message(PyrogramType, Update): web page preview. In future versions this property could turn into a full web page object that contains more details. + poll (:obj:`Poll `, *optional*): + Message is a native poll, information about the poll. + new_chat_members (List of :obj:`User `, *optional*): New members that were added to the group or supergroup and information about them (the bot itself may be one of these members). From bcef74c574d799aa07d75f39ece5d271b21c6477 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 21:00:19 +0200 Subject: [PATCH 008/202] Update .gitignore to ignore the generated RPC error classes The "errors" package has been moved to make it simpler to import --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bfc2fb83..0b1a0699 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ config.ini # Pyrogram generated code -pyrogram/api/errors/exceptions/ +pyrogram/errors/exceptions/ pyrogram/api/functions/ pyrogram/api/types/ pyrogram/api/all.py From b056aa8d7f1f484aaffffc966a52b48094f8cfbe Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 21:04:34 +0200 Subject: [PATCH 009/202] Add the field is_member to the ChatMember type This can be used to find whether a restricted user is a member of the chat at the moment of the request. --- .../types/user_and_chats/chat_member.py | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 35911210..9ccf9314 100644 --- a/pyrogram/client/types/user_and_chats/chat_member.py +++ b/pyrogram/client/types/user_and_chats/chat_member.py @@ -36,6 +36,9 @@ class ChatMember(PyrogramType): date (``int``, *optional*): Date when the user joined, unix time. Not available for creator. + is_member (``bool``, *optional*): + Restricted only. True, if the user is a member of the chat at the moment of the request. + invited_by (:obj:`User `, *optional*): Administrators and self member only. Information about the user who invited this member. In case the user joined by himself this will be the same as "user". @@ -51,7 +54,7 @@ class ChatMember(PyrogramType): Information about the member permissions. """ - __slots__ = ["user", "status", "date", "invited_by", "promoted_by", "restricted_by", "permissions"] + __slots__ = ["user", "status", "date", "is_member", "invited_by", "promoted_by", "restricted_by", "permissions"] def __init__( self, @@ -60,6 +63,7 @@ class ChatMember(PyrogramType): user: "pyrogram.User", status: str, date: int = None, + is_member: bool = None, invited_by: "pyrogram.User" = None, promoted_by: "pyrogram.User" = None, restricted_by: "pyrogram.User" = None, @@ -70,6 +74,7 @@ class ChatMember(PyrogramType): self.user = user self.status = status self.date = date + self.is_member = is_member self.invited_by = invited_by self.promoted_by = promoted_by self.restricted_by = restricted_by @@ -121,14 +126,17 @@ class ChatMember(PyrogramType): ) if isinstance(member, types.ChannelParticipantBanned): + status = ( + "kicked" if member.banned_rights.view_messages + else "left" if member.left + else "restricted" + ) + return ChatMember( user=user, - status=( - "kicked" if member.banned_rights.view_messages - else "left" if member.left - else "restricted" - ), + status=status, date=member.date, + is_member=not member.left if status == "restricted" else None, restricted_by=pyrogram.User._parse(client, users[member.kicked_by]), permissions=pyrogram.ChatPermissions._parse(member), client=client From 57be97566d9a182e10e39f4e55c99f7c1e2c67a3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Apr 2019 22:34:05 +0200 Subject: [PATCH 010/202] Make delete_messages return False when it fails to delete This is because there will be no exception raised, because Telegram is not sending any RPCError when you try to delete a message you don't have rights on to. --- pyrogram/client/methods/messages/delete_messages.py | 10 ++++++---- pyrogram/client/types/messages_and_media/message.py | 6 ++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyrogram/client/methods/messages/delete_messages.py b/pyrogram/client/methods/messages/delete_messages.py index bbd838ee..4076be22 100644 --- a/pyrogram/client/methods/messages/delete_messages.py +++ b/pyrogram/client/methods/messages/delete_messages.py @@ -48,7 +48,7 @@ class DeleteMessages(BaseClient): Defaults to True. Returns: - True on success. + True on success, False otherwise. Raises: :class:`RPCError ` in case of a Telegram RPC error. @@ -57,18 +57,20 @@ class DeleteMessages(BaseClient): message_ids = list(message_ids) if not isinstance(message_ids, int) else [message_ids] if isinstance(peer, types.InputPeerChannel): - self.send( + r = self.send( functions.channels.DeleteMessages( channel=peer, id=message_ids ) ) else: - self.send( + r = self.send( functions.messages.DeleteMessages( id=message_ids, revoke=revoke or None ) ) - return True + # Deleting messages you don't have right onto, won't raise any error. + # Check for pts_count, which is 0 in case deletes fail. + return bool(r.pts_count) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index fc2cb8fb..727b6330 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -2729,19 +2729,17 @@ class Message(PyrogramType, Update): Defaults to True. Returns: - True on success. + True on success, False otherwise. Raises: :class:`RPCError ` """ - self._client.delete_messages( + return self._client.delete_messages( chat_id=self.chat.id, message_ids=self.message_id, revoke=revoke ) - return True - def click(self, x: int or str, y: int = None, quote: bool = None): """Bound method *click* of :obj:`Message `. From 63d76a7f13bd28e5cfda7b0db684b09c64886991 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 20 Apr 2019 17:59:42 +0200 Subject: [PATCH 011/202] Bring back automatic mime type detection for new uploads (fixes #239) - Add mime.types file to contain a good database of type -> ext mappings from svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types - Load mime.type at BaseClient creation and add two convenience methods for guessing mime types from filenames and extensions from mime types, guess_mime_type and guess_extension - Make all send_* method as well as download_media use the new mime type database via guess_mime_type and guess_extension methods --- pyrogram/client/client.py | 34 +- pyrogram/client/ext/base_client.py | 21 + pyrogram/client/ext/mime.types | 1855 +++++++++++++++++ .../methods/messages/edit_message_media.py | 8 +- .../client/methods/messages/send_animation.py | 2 +- .../client/methods/messages/send_audio.py | 2 +- .../client/methods/messages/send_document.py | 2 +- .../methods/messages/send_media_group.py | 2 +- .../client/methods/messages/send_sticker.py | 2 +- .../client/methods/messages/send_video.py | 2 +- .../methods/messages/send_video_note.py | 2 +- .../client/methods/messages/send_voice.py | 2 +- 12 files changed, 1911 insertions(+), 23 deletions(-) create mode 100644 pyrogram/client/ext/mime.types diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 44aef5df..ec47c448 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -861,18 +861,20 @@ class Client(Methods, BaseClient): file_name = file_name or getattr(media, "file_name", None) if not file_name: - if media_type == 3: - extension = ".ogg" - elif media_type in (4, 10, 13): - extension = mimetypes.guess_extension(media.mime_type) or ".mp4" - elif media_type == 5: - extension = mimetypes.guess_extension(media.mime_type) or ".unknown" - elif media_type == 8: - extension = ".webp" - elif media_type == 9: - extension = mimetypes.guess_extension(media.mime_type) or ".mp3" - elif media_type in (0, 1, 2): + guessed_extension = self.guess_extension(media.mime_type) + + if media_type in (0, 1, 2): extension = ".jpg" + elif media_type == 3: + extension = guessed_extension or ".ogg" + elif media_type in (4, 10, 13): + extension = guessed_extension or ".mp4" + elif media_type == 5: + extension = guessed_extension or ".zip" + elif media_type == 8: + extension = guessed_extension or ".webp" + elif media_type == 9: + extension = guessed_extension or ".mp3" else: continue @@ -1708,3 +1710,13 @@ class Client(Methods, BaseClient): return "" else: return file_name + + def guess_mime_type(self, filename: str): + extension = os.path.splitext(filename)[1] + return self.extensions_to_mime_types.get(extension) + + def guess_extension(self, mime_type: str): + extensions = self.mime_types_to_extensions.get(mime_type) + + if extensions: + return extensions.split(" ")[0] diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index fcd746ce..b4bfbd6b 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +import os import platform import re from queue import Queue @@ -67,6 +68,20 @@ class BaseClient: 13: "video_note" } + mime_types_to_extensions = {} + extensions_to_mime_types = {} + + with open("{}/mime.types".format(os.path.dirname(__file__)), "r", encoding="UTF-8") as f: + for match in re.finditer(r"^([^#\s]+)\s+(.+)$", f.read(), flags=re.M): + mime_type, extensions = match.groups() + + extensions = [".{}".format(ext) for ext in extensions.split(" ")] + + for ext in extensions: + extensions_to_mime_types[ext] = mime_type + + mime_types_to_extensions[mime_type] = " ".join(extensions) + def __init__(self): self.is_bot = None self.dc_id = None @@ -132,3 +147,9 @@ class BaseClient: def answer_inline_query(self, *args, **kwargs): pass + + def guess_mime_type(self, *args, **kwargs): + pass + + def guess_extension(self, *args, **kwargs): + pass diff --git a/pyrogram/client/ext/mime.types b/pyrogram/client/ext/mime.types new file mode 100644 index 00000000..4db43cae --- /dev/null +++ b/pyrogram/client/ext/mime.types @@ -0,0 +1,1855 @@ +# This file maps Internet media types to unique file extension(s). +# Although created for httpd, this file is used by many software systems +# and has been placed in the public domain for unlimited redisribution. +# +# The table below contains both registered and (common) unregistered types. +# A type that has no unique extension can be ignored -- they are listed +# here to guide configurations toward known types and to make it easier to +# identify "new" types. File extensions are also commonly used to indicate +# content languages and encodings, so choose them carefully. +# +# Internet media types should be registered as described in RFC 4288. +# The registry is at . +# +# MIME type (lowercased) Extensions +# ============================================ ========== +# application/1d-interleaved-parityfec +# application/3gpdash-qoe-report+xml +# application/3gpp-ims+xml +# application/a2l +# application/activemessage +# application/alto-costmap+json +# application/alto-costmapfilter+json +# application/alto-directory+json +# application/alto-endpointcost+json +# application/alto-endpointcostparams+json +# application/alto-endpointprop+json +# application/alto-endpointpropparams+json +# application/alto-error+json +# application/alto-networkmap+json +# application/alto-networkmapfilter+json +# application/aml +application/andrew-inset ez +# application/applefile +application/applixware aw +# application/atf +# application/atfx +application/atom+xml atom +application/atomcat+xml atomcat +# application/atomdeleted+xml +# application/atomicmail +application/atomsvc+xml atomsvc +# application/atxml +# application/auth-policy+xml +# application/bacnet-xdd+zip +# application/batch-smtp +# application/beep+xml +# application/calendar+json +# application/calendar+xml +# application/call-completion +# application/cals-1840 +# application/cbor +# application/ccmp+xml +application/ccxml+xml ccxml +# application/cdfx+xml +application/cdmi-capability cdmia +application/cdmi-container cdmic +application/cdmi-domain cdmid +application/cdmi-object cdmio +application/cdmi-queue cdmiq +# application/cdni +# application/cea +# application/cea-2018+xml +# application/cellml+xml +# application/cfw +# application/cms +# application/cnrp+xml +# application/coap-group+json +# application/commonground +# application/conference-info+xml +# application/cpl+xml +# application/csrattrs +# application/csta+xml +# application/cstadata+xml +# application/csvm+json +application/cu-seeme cu +# application/cybercash +# application/dash+xml +# application/dashdelta +application/davmount+xml davmount +# application/dca-rft +# application/dcd +# application/dec-dx +# application/dialog-info+xml +# application/dicom +# application/dii +# application/dit +# application/dns +application/docbook+xml dbk +# application/dskpp+xml +application/dssc+der dssc +application/dssc+xml xdssc +# application/dvcs +application/ecmascript ecma +# application/edi-consent +# application/edi-x12 +# application/edifact +# application/efi +# application/emergencycalldata.comment+xml +# application/emergencycalldata.deviceinfo+xml +# application/emergencycalldata.providerinfo+xml +# application/emergencycalldata.serviceinfo+xml +# application/emergencycalldata.subscriberinfo+xml +application/emma+xml emma +# application/emotionml+xml +# application/encaprtp +# application/epp+xml +application/epub+zip epub +# application/eshop +# application/example +application/exi exi +# application/fastinfoset +# application/fastsoap +# application/fdt+xml +# application/fits +application/font-tdpfr pfr +# application/framework-attributes+xml +# application/geo+json +application/gml+xml gml +application/gpx+xml gpx +application/gxf gxf +# application/gzip +# application/h224 +# application/held+xml +# application/http +application/hyperstudio stk +# application/ibe-key-request+xml +# application/ibe-pkg-reply+xml +# application/ibe-pp-data +# application/iges +# application/im-iscomposing+xml +# application/index +# application/index.cmd +# application/index.obj +# application/index.response +# application/index.vnd +application/inkml+xml ink inkml +# application/iotp +application/ipfix ipfix +# application/ipp +# application/isup +# application/its+xml +application/java-archive jar +application/java-serialized-object ser +application/java-vm class +application/javascript js +# application/jose +# application/jose+json +# application/jrd+json +application/json json +# application/json-patch+json +# application/json-seq +application/jsonml+json jsonml +# application/jwk+json +# application/jwk-set+json +# application/jwt +# application/kpml-request+xml +# application/kpml-response+xml +# application/ld+json +# application/lgr+xml +# application/link-format +# application/load-control+xml +application/lost+xml lostxml +# application/lostsync+xml +# application/lxf +application/mac-binhex40 hqx +application/mac-compactpro cpt +# application/macwriteii +application/mads+xml mads +application/marc mrc +application/marcxml+xml mrcx +application/mathematica ma nb mb +application/mathml+xml mathml +# application/mathml-content+xml +# application/mathml-presentation+xml +# application/mbms-associated-procedure-description+xml +# application/mbms-deregister+xml +# application/mbms-envelope+xml +# application/mbms-msk+xml +# application/mbms-msk-response+xml +# application/mbms-protection-description+xml +# application/mbms-reception-report+xml +# application/mbms-register+xml +# application/mbms-register-response+xml +# application/mbms-schedule+xml +# application/mbms-user-service-description+xml +application/mbox mbox +# application/media-policy-dataset+xml +# application/media_control+xml +application/mediaservercontrol+xml mscml +# application/merge-patch+json +application/metalink+xml metalink +application/metalink4+xml meta4 +application/mets+xml mets +# application/mf4 +# application/mikey +application/mods+xml mods +# application/moss-keys +# application/moss-signature +# application/mosskey-data +# application/mosskey-request +application/mp21 m21 mp21 +application/mp4 mp4s +# application/mpeg4-generic +# application/mpeg4-iod +# application/mpeg4-iod-xmt +# application/mrb-consumer+xml +# application/mrb-publish+xml +# application/msc-ivr+xml +# application/msc-mixer+xml +application/msword doc dot +application/mxf mxf +# application/nasdata +# application/news-checkgroups +# application/news-groupinfo +# application/news-transmission +# application/nlsml+xml +# application/nss +# application/ocsp-request +# application/ocsp-response +application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy +application/oda oda +# application/odx +application/oebps-package+xml opf +application/ogg ogx +application/omdoc+xml omdoc +application/onenote onetoc onetoc2 onetmp onepkg +application/oxps oxps +# application/p2p-overlay+xml +# application/parityfec +application/patch-ops-error+xml xer +application/pdf pdf +# application/pdx +application/pgp-encrypted pgp +# application/pgp-keys +application/pgp-signature asc sig +application/pics-rules prf +# application/pidf+xml +# application/pidf-diff+xml +application/pkcs10 p10 +# application/pkcs12 +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkcs8 p8 +application/pkix-attr-cert ac +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +# application/poc-settings+xml +application/postscript ai eps ps +# application/ppsp-tracker+json +# application/problem+json +# application/problem+xml +# application/provenance+xml +# application/prs.alvestrand.titrax-sheet +application/prs.cww cww +# application/prs.hpub+zip +# application/prs.nprend +# application/prs.plucker +# application/prs.rdf-xml-crypt +# application/prs.xsf+xml +application/pskc+xml pskcxml +# application/qsig +# application/raptorfec +# application/rdap+json +application/rdf+xml rdf +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +# application/remote-printing +# application/reputon+json +application/resource-lists+xml rl +application/resource-lists-diff+xml rld +# application/rfc+xml +# application/riscos +# application/rlmi+xml +application/rls-services+xml rs +application/rpki-ghostbusters gbr +application/rpki-manifest mft +application/rpki-roa roa +# application/rpki-updown +application/rsd+xml rsd +application/rss+xml rss +application/rtf rtf +# application/rtploopback +# application/rtx +# application/samlassertion+xml +# application/samlmetadata+xml +application/sbml+xml sbml +# application/scaip+xml +# application/scim+json +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +# application/sep+xml +# application/sep-exi +# application/session-info +# application/set-payment +application/set-payment-initiation setpay +# application/set-registration +application/set-registration-initiation setreg +# application/sgml +# application/sgml-open-catalog +application/shf+xml shf +# application/sieve +# application/simple-filter+xml +# application/simple-message-summary +# application/simplesymbolcontainer +# application/slate +# application/smil +application/smil+xml smi smil +# application/smpte336m +# application/soap+fastinfoset +# application/soap+xml +application/sparql-query rq +application/sparql-results+xml srx +# application/spirits-event+xml +# application/sql +application/srgs gram +application/srgs+xml grxml +application/sru+xml sru +application/ssdl+xml ssdl +application/ssml+xml ssml +# application/tamp-apex-update +# application/tamp-apex-update-confirm +# application/tamp-community-update +# application/tamp-community-update-confirm +# application/tamp-error +# application/tamp-sequence-adjust +# application/tamp-sequence-adjust-confirm +# application/tamp-status-query +# application/tamp-status-response +# application/tamp-update +# application/tamp-update-confirm +application/tei+xml tei teicorpus +application/thraud+xml tfi +# application/timestamp-query +# application/timestamp-reply +application/timestamped-data tsd +# application/ttml+xml +# application/tve-trigger +# application/ulpfec +# application/urc-grpsheet+xml +# application/urc-ressheet+xml +# application/urc-targetdesc+xml +# application/urc-uisocketdesc+xml +# application/vcard+json +# application/vcard+xml +# application/vemmi +# application/vividence.scriptfile +# application/vnd.3gpp-prose+xml +# application/vnd.3gpp-prose-pc3ch+xml +# application/vnd.3gpp.access-transfer-events+xml +# application/vnd.3gpp.bsf+xml +# application/vnd.3gpp.mid-call+xml +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +# application/vnd.3gpp.sms +# application/vnd.3gpp.sms+xml +# application/vnd.3gpp.srvcc-ext+xml +# application/vnd.3gpp.srvcc-info+xml +# application/vnd.3gpp.state-and-event-info+xml +# application/vnd.3gpp.ussd+xml +# application/vnd.3gpp2.bcmcsinfo+xml +# application/vnd.3gpp2.sms +application/vnd.3gpp2.tcap tcap +# application/vnd.3lightssoftware.imagescal +application/vnd.3m.post-it-notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.air-application-installer-package+zip air +# application/vnd.adobe.flash.movie +application/vnd.adobe.formscentral.fcdt fcdt +application/vnd.adobe.fxp fxp fxpl +# application/vnd.adobe.partial-upload +application/vnd.adobe.xdp+xml xdp +application/vnd.adobe.xfdf xfdf +# application/vnd.aether.imp +# application/vnd.ah-barcode +application/vnd.ahead.space ahead +application/vnd.airzip.filesecure.azf azf +application/vnd.airzip.filesecure.azs azs +application/vnd.amazon.ebook azw +# application/vnd.amazon.mobi8-ebook +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +# application/vnd.amundsen.maze+xml +application/vnd.android.package-archive apk +# application/vnd.anki +application/vnd.anser-web-certificate-issue-initiation cii +application/vnd.anser-web-funds-transfer-initiation fti +application/vnd.antix.game-component atx +# application/vnd.apache.thrift.binary +# application/vnd.apache.thrift.compact +# application/vnd.apache.thrift.json +# application/vnd.api+json +application/vnd.apple.installer+xml mpkg +application/vnd.apple.mpegurl m3u8 +# application/vnd.arastra.swi +application/vnd.aristanetworks.swi swi +# application/vnd.artsquare +application/vnd.astraea-software.iota iota +application/vnd.audiograph aep +# application/vnd.autopackage +# application/vnd.avistar+xml +# application/vnd.balsamiq.bmml+xml +# application/vnd.balsamiq.bmpr +# application/vnd.bekitzur-stech+json +# application/vnd.biopax.rdf+xml +application/vnd.blueice.multipass mpm +# application/vnd.bluetooth.ep.oob +# application/vnd.bluetooth.le.oob +application/vnd.bmi bmi +application/vnd.businessobjects rep +# application/vnd.cab-jscript +# application/vnd.canon-cpdl +# application/vnd.canon-lips +# application/vnd.cendio.thinlinc.clientconf +# application/vnd.century-systems.tcp_stream +application/vnd.chemdraw+xml cdxml +# application/vnd.chess-pgn +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.cinderella cdy +# application/vnd.cirpack.isdn-ext +# application/vnd.citationstyles.style+xml +application/vnd.claymore cla +application/vnd.cloanto.rp9 rp9 +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.cluetrust.cartomobile-config c11amc +application/vnd.cluetrust.cartomobile-config-pkg c11amz +# application/vnd.coffeescript +# application/vnd.collection+json +# application/vnd.collection.doc+json +# application/vnd.collection.next+json +# application/vnd.comicbook+zip +# application/vnd.commerce-battelle +application/vnd.commonspace csp +application/vnd.contact.cmsg cdbcmsg +# application/vnd.coreos.ignition+json +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.ctc-posml pml +# application/vnd.ctct.ws+xml +# application/vnd.cups-pdf +# application/vnd.cups-postscript +application/vnd.cups-ppd ppd +# application/vnd.cups-raster +# application/vnd.cups-raw +# application/vnd.curl +application/vnd.curl.car car +application/vnd.curl.pcurl pcurl +# application/vnd.cyan.dean.root+xml +# application/vnd.cybank +application/vnd.dart dart +application/vnd.data-vision.rdz rdz +# application/vnd.debian.binary-package +application/vnd.dece.data uvf uvvf uvd uvvd +application/vnd.dece.ttml+xml uvt uvvt +application/vnd.dece.unspecified uvx uvvx +application/vnd.dece.zip uvz uvvz +application/vnd.denovo.fcselayout-link fe_launch +# application/vnd.desmume.movie +# application/vnd.dir-bi.plate-dl-nosuffix +# application/vnd.dm.delegation+xml +application/vnd.dna dna +# application/vnd.document+json +application/vnd.dolby.mlp mlp +# application/vnd.dolby.mobile.1 +# application/vnd.dolby.mobile.2 +# application/vnd.doremir.scorecloud-binary-document +application/vnd.dpgraph dpg +application/vnd.dreamfactory dfac +# application/vnd.drive+json +application/vnd.ds-keypoint kpxx +# application/vnd.dtg.local +# application/vnd.dtg.local.flash +# application/vnd.dtg.local.html +application/vnd.dvb.ait ait +# application/vnd.dvb.dvbj +# application/vnd.dvb.esgcontainer +# application/vnd.dvb.ipdcdftnotifaccess +# application/vnd.dvb.ipdcesgaccess +# application/vnd.dvb.ipdcesgaccess2 +# application/vnd.dvb.ipdcesgpdd +# application/vnd.dvb.ipdcroaming +# application/vnd.dvb.iptv.alfec-base +# application/vnd.dvb.iptv.alfec-enhancement +# application/vnd.dvb.notif-aggregate-root+xml +# application/vnd.dvb.notif-container+xml +# application/vnd.dvb.notif-generic+xml +# application/vnd.dvb.notif-ia-msglist+xml +# application/vnd.dvb.notif-ia-registration-request+xml +# application/vnd.dvb.notif-ia-registration-response+xml +# application/vnd.dvb.notif-init+xml +# application/vnd.dvb.pfr +application/vnd.dvb.service svc +# application/vnd.dxr +application/vnd.dynageo geo +# application/vnd.dzr +# application/vnd.easykaraoke.cdgdownload +# application/vnd.ecdis-update +application/vnd.ecowin.chart mag +# application/vnd.ecowin.filerequest +# application/vnd.ecowin.fileupdate +# application/vnd.ecowin.series +# application/vnd.ecowin.seriesrequest +# application/vnd.ecowin.seriesupdate +# application/vnd.emclient.accessrequest+xml +application/vnd.enliven nml +# application/vnd.enphase.envoy +# application/vnd.eprints.data+xml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +# application/vnd.ericsson.quickcall +application/vnd.eszigno3+xml es3 et3 +# application/vnd.etsi.aoc+xml +# application/vnd.etsi.asic-e+zip +# application/vnd.etsi.asic-s+zip +# application/vnd.etsi.cug+xml +# application/vnd.etsi.iptvcommand+xml +# application/vnd.etsi.iptvdiscovery+xml +# application/vnd.etsi.iptvprofile+xml +# application/vnd.etsi.iptvsad-bc+xml +# application/vnd.etsi.iptvsad-cod+xml +# application/vnd.etsi.iptvsad-npvr+xml +# application/vnd.etsi.iptvservice+xml +# application/vnd.etsi.iptvsync+xml +# application/vnd.etsi.iptvueprofile+xml +# application/vnd.etsi.mcid+xml +# application/vnd.etsi.mheg5 +# application/vnd.etsi.overload-control-policy-dataset+xml +# application/vnd.etsi.pstn+xml +# application/vnd.etsi.sci+xml +# application/vnd.etsi.simservs+xml +# application/vnd.etsi.timestamp-token +# application/vnd.etsi.tsl+xml +# application/vnd.etsi.tsl.der +# application/vnd.eudora.data +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +# application/vnd.f-secure.mobile +# application/vnd.fastcopy-disk-image +application/vnd.fdf fdf +application/vnd.fdsn.mseed mseed +application/vnd.fdsn.seed seed dataless +# application/vnd.ffsns +# application/vnd.filmit.zfc +# application/vnd.fints +# application/vnd.firemonkeys.cloudcell +application/vnd.flographit gph +application/vnd.fluxtime.clip ftc +# application/vnd.font-fontforge-sfd +application/vnd.framemaker fm frame maker book +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +# application/vnd.fujixerox.art-ex +# application/vnd.fujixerox.art4 +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +# application/vnd.fujixerox.docuworks.container +# application/vnd.fujixerox.hbpl +# application/vnd.fut-misnet +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +# application/vnd.geo+json +# application/vnd.geocube+xml +application/vnd.geogebra.file ggb +application/vnd.geogebra.tool ggt +application/vnd.geometry-explorer gex gre +application/vnd.geonext gxt +application/vnd.geoplan g2w +application/vnd.geospace g3w +# application/vnd.gerber +# application/vnd.globalplatform.card-content-mgt +# application/vnd.globalplatform.card-content-mgt-response +application/vnd.gmx gmx +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +# application/vnd.gov.sk.e-form+xml +# application/vnd.gov.sk.e-form+zip +# application/vnd.gov.sk.xmldatacontainer+xml +application/vnd.grafeq gqf gqs +# application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +# application/vnd.hal+json +application/vnd.hal+xml hal +application/vnd.handheld-entertainment+xml zmm +application/vnd.hbci hbci +# application/vnd.hcl-bireports +# application/vnd.hdt +# application/vnd.heroku+json +application/vnd.hhe.lesson-player les +application/vnd.hp-hpgl hpgl +application/vnd.hp-hpid hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-pcl pcl +application/vnd.hp-pclxl pclxl +# application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +# application/vnd.hyperdrive+json +# application/vnd.hzn-3d-crossword +# application/vnd.ibm.afplinedata +# application/vnd.ibm.electronic-media +application/vnd.ibm.minipay mpy +application/vnd.ibm.modcap afp listafp list3820 +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +# application/vnd.ieee.1905 +application/vnd.igloader igl +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +# application/vnd.ims.imsccv1p1 +# application/vnd.ims.imsccv1p2 +# application/vnd.ims.imsccv1p3 +# application/vnd.ims.lis.v2.result+json +# application/vnd.ims.lti.v2.toolconsumerprofile+json +# application/vnd.ims.lti.v2.toolproxy+json +# application/vnd.ims.lti.v2.toolproxy.id+json +# application/vnd.ims.lti.v2.toolsettings+json +# application/vnd.ims.lti.v2.toolsettings.simple+json +# application/vnd.informedcontrol.rms+xml +# application/vnd.informix-visionary +# application/vnd.infotech.project +# application/vnd.infotech.project+xml +# application/vnd.innopath.wamp.notification +application/vnd.insors.igm igm +application/vnd.intercon.formnet xpw xpx +application/vnd.intergeo i2g +# application/vnd.intertrust.digibox +# application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +# application/vnd.iptc.g2.catalogitem+xml +# application/vnd.iptc.g2.conceptitem+xml +# application/vnd.iptc.g2.knowledgeitem+xml +# application/vnd.iptc.g2.newsitem+xml +# application/vnd.iptc.g2.newsmessage+xml +# application/vnd.iptc.g2.packageitem+xml +# application/vnd.iptc.g2.planningitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.isac.fcs fcs +application/vnd.jam jam +# application/vnd.japannet-directory-service +# application/vnd.japannet-jpnstore-wakeup +# application/vnd.japannet-payment-wakeup +# application/vnd.japannet-registration +# application/vnd.japannet-registration-wakeup +# application/vnd.japannet-setstore-wakeup +# application/vnd.japannet-verification +# application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +# application/vnd.jsk.isdn-ngn +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.kinar kne knp +application/vnd.koan skp skd skt skm +application/vnd.kodak-descriptor sse +application/vnd.las.las+xml lasxml +# application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.lotus-1-2-3 123 +application/vnd.lotus-approach apr +application/vnd.lotus-freelance pre +application/vnd.lotus-notes nsf +application/vnd.lotus-organizer org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp +application/vnd.macports.portpkg portpkg +# application/vnd.mapbox-vector-tile +# application/vnd.marlin.drm.actiontoken+xml +# application/vnd.marlin.drm.conftoken+xml +# application/vnd.marlin.drm.license+xml +# application/vnd.marlin.drm.mdcf +# application/vnd.mason+json +# application/vnd.maxmind.maxmind-db +application/vnd.mcd mcd +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +# application/vnd.meridian-slingshot +application/vnd.mfer mwf +application/vnd.mfmp mfm +# application/vnd.micro+json +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +# application/vnd.microsoft.portable-executable +# application/vnd.miele+json +application/vnd.mif mif +# application/vnd.minisoft-hp3000-save +# application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf daf +application/vnd.mobius.dis dis +application/vnd.mobius.mbk mbk +application/vnd.mobius.mqy mqy +application/vnd.mobius.msl msl +application/vnd.mobius.plc plc +application/vnd.mobius.txf txf +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +# application/vnd.motorola.flexsuite +# application/vnd.motorola.flexsuite.adsi +# application/vnd.motorola.flexsuite.fis +# application/vnd.motorola.flexsuite.gotap +# application/vnd.motorola.flexsuite.kmr +# application/vnd.motorola.flexsuite.ttc +# application/vnd.motorola.flexsuite.wem +# application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +# application/vnd.ms-3mfdocument +application/vnd.ms-artgalry cil +# application/vnd.ms-asf +application/vnd.ms-cab-compressed cab +# application/vnd.ms-color.iccprofile +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-excel.addin.macroenabled.12 xlam +application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb +application/vnd.ms-excel.sheet.macroenabled.12 xlsm +application/vnd.ms-excel.template.macroenabled.12 xltm +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +# application/vnd.ms-office.activex+xml +application/vnd.ms-officetheme thmx +# application/vnd.ms-opentype +# application/vnd.ms-package.obfuscated-opentype +application/vnd.ms-pki.seccat cat +application/vnd.ms-pki.stl stl +# application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-powerpoint.addin.macroenabled.12 ppam +application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm +application/vnd.ms-powerpoint.slide.macroenabled.12 sldm +application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm +application/vnd.ms-powerpoint.template.macroenabled.12 potm +# application/vnd.ms-printdevicecapabilities+xml +# application/vnd.ms-printing.printticket+xml +# application/vnd.ms-printschematicket+xml +application/vnd.ms-project mpp mpt +# application/vnd.ms-tnef +# application/vnd.ms-windows.devicepairing +# application/vnd.ms-windows.nwprinting.oob +# application/vnd.ms-windows.printerpairing +# application/vnd.ms-windows.wsd.oob +# application/vnd.ms-wmdrm.lic-chlg-req +# application/vnd.ms-wmdrm.lic-resp +# application/vnd.ms-wmdrm.meter-chlg-req +# application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-word.document.macroenabled.12 docm +application/vnd.ms-word.template.macroenabled.12 dotm +application/vnd.ms-works wps wks wcm wdb +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +# application/vnd.msa-disk-image +application/vnd.mseq mseq +# application/vnd.msign +# application/vnd.multiad.creator +# application/vnd.multiad.creator.cif +# application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +application/vnd.mynfc taglet +# application/vnd.ncd.control +# application/vnd.ncd.reference +# application/vnd.nervana +# application/vnd.netfpx +application/vnd.neurolanguage.nlu nlu +# application/vnd.nintendo.nitro.rom +# application/vnd.nintendo.snes.rom +application/vnd.nitf ntf nitf +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +# application/vnd.nokia.catalogs +# application/vnd.nokia.conml+wbxml +# application/vnd.nokia.conml+xml +# application/vnd.nokia.iptv.config+xml +# application/vnd.nokia.isds-radio-presets +# application/vnd.nokia.landmark+wbxml +# application/vnd.nokia.landmark+xml +# application/vnd.nokia.landmarkcollection+xml +# application/vnd.nokia.n-gage.ac+xml +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +# application/vnd.nokia.ncd +# application/vnd.nokia.pcd+wbxml +# application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.edm edm +application/vnd.novadigm.edx edx +application/vnd.novadigm.ext ext +# application/vnd.ntt-local.content-share +# application/vnd.ntt-local.file-transfer +# application/vnd.ntt-local.ogw_remote-access +# application/vnd.ntt-local.sip-ta_remote +# application/vnd.ntt-local.sip-ta_tcp_stream +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +application/vnd.oasis.opendocument.database odb +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.formula-template odft +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +# application/vnd.obn +# application/vnd.oftn.l10n+json +# application/vnd.oipf.contentaccessdownload+xml +# application/vnd.oipf.contentaccessstreaming+xml +# application/vnd.oipf.cspg-hexbinary +# application/vnd.oipf.dae.svg+xml +# application/vnd.oipf.dae.xhtml+xml +# application/vnd.oipf.mippvcontrolmessage+xml +# application/vnd.oipf.pae.gem +# application/vnd.oipf.spdiscovery+xml +# application/vnd.oipf.spdlist+xml +# application/vnd.oipf.ueprofile+xml +# application/vnd.oipf.userprofile+xml +application/vnd.olpc-sugar xo +# application/vnd.oma-scws-config +# application/vnd.oma-scws-http-request +# application/vnd.oma-scws-http-response +# application/vnd.oma.bcast.associated-procedure-parameter+xml +# application/vnd.oma.bcast.drm-trigger+xml +# application/vnd.oma.bcast.imd+xml +# application/vnd.oma.bcast.ltkm +# application/vnd.oma.bcast.notification+xml +# application/vnd.oma.bcast.provisioningtrigger +# application/vnd.oma.bcast.sgboot +# application/vnd.oma.bcast.sgdd+xml +# application/vnd.oma.bcast.sgdu +# application/vnd.oma.bcast.simple-symbol-container +# application/vnd.oma.bcast.smartcard-trigger+xml +# application/vnd.oma.bcast.sprov+xml +# application/vnd.oma.bcast.stkm +# application/vnd.oma.cab-address-book+xml +# application/vnd.oma.cab-feature-handler+xml +# application/vnd.oma.cab-pcc+xml +# application/vnd.oma.cab-subs-invite+xml +# application/vnd.oma.cab-user-prefs+xml +# application/vnd.oma.dcd +# application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +# application/vnd.oma.drm.risd+xml +# application/vnd.oma.group-usage-list+xml +# application/vnd.oma.lwm2m+json +# application/vnd.oma.lwm2m+tlv +# application/vnd.oma.pal+xml +# application/vnd.oma.poc.detailed-progress-report+xml +# application/vnd.oma.poc.final-report+xml +# application/vnd.oma.poc.groups+xml +# application/vnd.oma.poc.invocation-descriptor+xml +# application/vnd.oma.poc.optimized-progress-report+xml +# application/vnd.oma.push +# application/vnd.oma.scidm.messages+xml +# application/vnd.oma.xcap-directory+xml +# application/vnd.omads-email+xml +# application/vnd.omads-file+xml +# application/vnd.omads-folder+xml +# application/vnd.omaloc-supl-init +# application/vnd.onepager +# application/vnd.openblox.game+xml +# application/vnd.openblox.game-binary +# application/vnd.openeye.oeb +application/vnd.openofficeorg.extension oxt +# application/vnd.openxmlformats-officedocument.custom-properties+xml +# application/vnd.openxmlformats-officedocument.customxmlproperties+xml +# application/vnd.openxmlformats-officedocument.drawing+xml +# application/vnd.openxmlformats-officedocument.drawingml.chart+xml +# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml +# application/vnd.openxmlformats-officedocument.extended-properties+xml +# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml +# application/vnd.openxmlformats-officedocument.presentationml.comments+xml +# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml +application/vnd.openxmlformats-officedocument.presentationml.presentation pptx +# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml +application/vnd.openxmlformats-officedocument.presentationml.slide sldx +# application/vnd.openxmlformats-officedocument.presentationml.slide+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml +application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx +# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml +# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml +# application/vnd.openxmlformats-officedocument.presentationml.tags+xml +application/vnd.openxmlformats-officedocument.presentationml.template potx +# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx +# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml +# application/vnd.openxmlformats-officedocument.theme+xml +# application/vnd.openxmlformats-officedocument.themeoverride+xml +# application/vnd.openxmlformats-officedocument.vmldrawing +# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document docx +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx +# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml +# application/vnd.openxmlformats-package.core-properties+xml +# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml +# application/vnd.openxmlformats-package.relationships+xml +# application/vnd.oracle.resource+json +# application/vnd.orange.indata +# application/vnd.osa.netdeploy +application/vnd.osgeo.mapguide.package mgp +# application/vnd.osgi.bundle +application/vnd.osgi.dp dp +application/vnd.osgi.subsystem esa +# application/vnd.otps.ct-kip+xml +# application/vnd.oxli.countgraph +# application/vnd.pagerduty+json +application/vnd.palm pdb pqa oprc +# application/vnd.panoply +# application/vnd.paos.xml +application/vnd.pawaafile paw +# application/vnd.pcos +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +# application/vnd.piaccess.application-licence +application/vnd.picsel efif +application/vnd.pmi.widget wg +# application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +# application/vnd.powerbuilder6-s +# application/vnd.powerbuilder7 +# application/vnd.powerbuilder7-s +# application/vnd.powerbuilder75 +# application/vnd.powerbuilder75-s +# application/vnd.preminet +application/vnd.previewsystems.box box +application/vnd.proteus.magazine mgz +application/vnd.publishare-delta-tree qps +application/vnd.pvi.ptid1 ptid +# application/vnd.pwg-multiplexed +# application/vnd.pwg-xhtml-print+xml +# application/vnd.qualcomm.brew-app-res +# application/vnd.quarantainenet +application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb +# application/vnd.quobject-quoxdocument +# application/vnd.radisys.moml+xml +# application/vnd.radisys.msml+xml +# application/vnd.radisys.msml-audit+xml +# application/vnd.radisys.msml-audit-conf+xml +# application/vnd.radisys.msml-audit-conn+xml +# application/vnd.radisys.msml-audit-dialog+xml +# application/vnd.radisys.msml-audit-stream+xml +# application/vnd.radisys.msml-conf+xml +# application/vnd.radisys.msml-dialog+xml +# application/vnd.radisys.msml-dialog-base+xml +# application/vnd.radisys.msml-dialog-fax-detect+xml +# application/vnd.radisys.msml-dialog-fax-sendrecv+xml +# application/vnd.radisys.msml-dialog-group+xml +# application/vnd.radisys.msml-dialog-speech+xml +# application/vnd.radisys.msml-dialog-transform+xml +# application/vnd.rainstor.data +# application/vnd.rapid +# application/vnd.rar +application/vnd.realvnc.bed bed +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml musicxml +# application/vnd.renlearn.rlprint +application/vnd.rig.cryptonote cryptonote +application/vnd.rim.cod cod +application/vnd.rn-realmedia rm +application/vnd.rn-realmedia-vbr rmvb +application/vnd.route66.link66+xml link66 +# application/vnd.rs-274x +# application/vnd.ruckus.download +# application/vnd.s3sms +application/vnd.sailingtracker.track st +# application/vnd.sbm.cid +# application/vnd.sbm.mid2 +# application/vnd.scribus +# application/vnd.sealed.3df +# application/vnd.sealed.csf +# application/vnd.sealed.doc +# application/vnd.sealed.eml +# application/vnd.sealed.mht +# application/vnd.sealed.net +# application/vnd.sealed.ppt +# application/vnd.sealed.tiff +# application/vnd.sealed.xls +# application/vnd.sealedmedia.softseal.html +# application/vnd.sealedmedia.softseal.pdf +application/vnd.seemail see +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.simtech-mindmapper twd twds +# application/vnd.siren+json +application/vnd.smaf mmf +# application/vnd.smart.notebook +application/vnd.smart.teacher teacher +# application/vnd.software602.filler.form+xml +# application/vnd.software602.filler.form-xml-zip +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +# application/vnd.sss-cod +# application/vnd.sss-dtf +# application/vnd.sss-ntf +application/vnd.stardivision.calc sdc +application/vnd.stardivision.draw sda +application/vnd.stardivision.impress sdd +application/vnd.stardivision.math smf +application/vnd.stardivision.writer sdw vor +application/vnd.stardivision.writer-global sgl +application/vnd.stepmania.package smzip +application/vnd.stepmania.stepchart sm +# application/vnd.street-stream +# application/vnd.sun.wadl+xml +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +application/vnd.sus-calendar sus susp +application/vnd.svd svd +# application/vnd.swiftview-ics +application/vnd.symbian.install sis sisx +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +# application/vnd.syncml.dm.notification +# application/vnd.syncml.dmddf+wbxml +# application/vnd.syncml.dmddf+xml +# application/vnd.syncml.dmtnds+wbxml +# application/vnd.syncml.dmtnds+xml +# application/vnd.syncml.ds.notification +application/vnd.tao.intent-module-archive tao +application/vnd.tcpdump.pcap pcap cap dmp +# application/vnd.tmd.mediaflex.api+xml +# application/vnd.tml +application/vnd.tmobile-livetv tmo +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +# application/vnd.truedoc +# application/vnd.ubisoft.webplayer +application/vnd.ufdl ufd ufdl +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml +# application/vnd.uplanet.alert +# application/vnd.uplanet.alert-wbxml +# application/vnd.uplanet.bearer-choice +# application/vnd.uplanet.bearer-choice-wbxml +# application/vnd.uplanet.cacheop +# application/vnd.uplanet.cacheop-wbxml +# application/vnd.uplanet.channel +# application/vnd.uplanet.channel-wbxml +# application/vnd.uplanet.list +# application/vnd.uplanet.list-wbxml +# application/vnd.uplanet.listcmd +# application/vnd.uplanet.listcmd-wbxml +# application/vnd.uplanet.signal +# application/vnd.uri-map +# application/vnd.valve.source.material +application/vnd.vcx vcx +# application/vnd.vd-study +# application/vnd.vectorworks +# application/vnd.vel+json +# application/vnd.verimatrix.vcas +# application/vnd.vidsoft.vidconference +application/vnd.visio vsd vst vss vsw +application/vnd.visionary vis +# application/vnd.vividence.scriptfile +application/vnd.vsf vsf +# application/vnd.wap.sic +# application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo wtb +# application/vnd.wfa.p2p +# application/vnd.wfa.wsc +# application/vnd.windows.devicepairing +# application/vnd.wmc +# application/vnd.wmf.bootstrap +# application/vnd.wolfram.mathematica +# application/vnd.wolfram.mathematica.package +application/vnd.wolfram.player nbp +application/vnd.wordperfect wpd +application/vnd.wqd wqd +# application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +# application/vnd.wv.csp+wbxml +# application/vnd.wv.csp+xml +# application/vnd.wv.ssp+xml +# application/vnd.xacml+json +application/vnd.xara xar +application/vnd.xfdl xfdl +# application/vnd.xfdl.webform +# application/vnd.xmi+xml +# application/vnd.xmpie.cpkg +# application/vnd.xmpie.dpkg +# application/vnd.xmpie.plan +# application/vnd.xmpie.ppkg +# application/vnd.xmpie.xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.openscoreformat osf +application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg +# application/vnd.yamaha.remote-setup +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +# application/vnd.yamaha.through-ngn +# application/vnd.yamaha.tunnel-udpencap +# application/vnd.yaoweme +application/vnd.yellowriver-custom-menu cmp +application/vnd.zul zir zirz +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +# application/vq-rtcpxr +# application/watcherinfo+xml +# application/whoispp-query +# application/whoispp-response +application/widget wgt +application/winhlp hlp +# application/wita +# application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +application/x-7z-compressed 7z +application/x-abiword abw +application/x-ace-compressed ace +# application/x-amf +application/x-apple-diskimage dmg +application/x-authorware-bin aab x32 u32 vox +application/x-authorware-map aam +application/x-authorware-seg aas +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-blorb blb blorb +application/x-bzip bz +application/x-bzip2 bz2 boz +application/x-cbr cbr cba cbt cbz cb7 +application/x-cdlink vcd +application/x-cfs-compressed cfs +application/x-chat chat +application/x-chess-pgn pgn +# application/x-compress +application/x-conference nsc +application/x-cpio cpio +application/x-csh csh +application/x-debian-package deb udeb +application/x-dgc-compressed dgc +application/x-director dir dcr dxr cst cct cxt w3d fgd swa +application/x-doom wad +application/x-dtbncx+xml ncx +application/x-dtbook+xml dtb +application/x-dtbresource+xml res +application/x-dvi dvi +application/x-envoy evy +application/x-eva eva +application/x-font-bdf bdf +# application/x-font-dos +# application/x-font-framemaker +application/x-font-ghostscript gsf +# application/x-font-libgrx +application/x-font-linux-psf psf +application/x-font-pcf pcf +application/x-font-snf snf +# application/x-font-speedo +# application/x-font-sunos-news +application/x-font-type1 pfa pfb pfm afm +# application/x-font-vfont +application/x-freearc arc +application/x-futuresplash spl +application/x-gca-compressed gca +application/x-glulx ulx +application/x-gnumeric gnumeric +application/x-gramps-xml gramps +application/x-gtar gtar +# application/x-gzip +application/x-hdf hdf +application/x-install-instructions install +application/x-iso9660-image iso +application/x-java-jnlp-file jnlp +application/x-latex latex +application/x-lzh-compressed lzh lha +application/x-mie mie +application/x-mobipocket-ebook prc mobi +application/x-ms-application application +application/x-ms-shortcut lnk +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-ms-xbap xbap +application/x-msaccess mdb +application/x-msbinder obd +application/x-mscardfile crd +application/x-msclip clp +application/x-msdownload exe dll com bat msi +application/x-msmediaview mvb m13 m14 +application/x-msmetafile wmf wmz emf emz +application/x-msmoney mny +application/x-mspublisher pub +application/x-msschedule scd +application/x-msterminal trm +application/x-mswrite wri +application/x-netcdf nc cdf +application/x-nzb nzb +application/x-pkcs12 p12 pfx +application/x-pkcs7-certificates p7b spc +application/x-pkcs7-certreqresp p7r +application/x-rar-compressed rar +application/x-research-info-systems ris +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-silverlight-app xap +application/x-sql sql +application/x-stuffit sit +application/x-stuffitx sitx +application/x-subrip srt +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-t3vm-image t3 +application/x-tads gam +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-tex-tfm tfm +application/x-texinfo texinfo texi +application/x-tgif obj +application/x-ustar ustar +application/x-wais-source src +# application/x-www-form-urlencoded +application/x-x509-ca-cert der crt +application/x-xfig fig +application/x-xliff+xml xlf +application/x-xpinstall xpi +application/x-xz xz +application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8 +# application/x400-bp +# application/xacml+xml +application/xaml+xml xaml +# application/xcap-att+xml +# application/xcap-caps+xml +application/xcap-diff+xml xdf +# application/xcap-el+xml +# application/xcap-error+xml +# application/xcap-ns+xml +# application/xcon-conference-info+xml +# application/xcon-conference-info-diff+xml +application/xenc+xml xenc +application/xhtml+xml xhtml xht +# application/xhtml-voice+xml +application/xml xml xsl +application/xml-dtd dtd +# application/xml-external-parsed-entity +# application/xml-patch+xml +# application/xmpp+xml +application/xop+xml xop +application/xproc+xml xpl +application/xslt+xml xslt +application/xspf+xml xspf +application/xv+xml mxml xhvml xvml xvm +application/yang yang +application/yin+xml yin +application/zip zip +# application/zlib +# audio/1d-interleaved-parityfec +# audio/32kadpcm +# audio/3gpp +# audio/3gpp2 +# audio/ac3 +audio/adpcm adp +# audio/amr +# audio/amr-wb +# audio/amr-wb+ +# audio/aptx +# audio/asc +# audio/atrac-advanced-lossless +# audio/atrac-x +# audio/atrac3 +audio/basic au snd +# audio/bv16 +# audio/bv32 +# audio/clearmode +# audio/cn +# audio/dat12 +# audio/dls +# audio/dsr-es201108 +# audio/dsr-es202050 +# audio/dsr-es202211 +# audio/dsr-es202212 +# audio/dv +# audio/dvi4 +# audio/eac3 +# audio/encaprtp +# audio/evrc +# audio/evrc-qcp +# audio/evrc0 +# audio/evrc1 +# audio/evrcb +# audio/evrcb0 +# audio/evrcb1 +# audio/evrcnw +# audio/evrcnw0 +# audio/evrcnw1 +# audio/evrcwb +# audio/evrcwb0 +# audio/evrcwb1 +# audio/evs +# audio/example +# audio/fwdred +# audio/g711-0 +# audio/g719 +# audio/g722 +# audio/g7221 +# audio/g723 +# audio/g726-16 +# audio/g726-24 +# audio/g726-32 +# audio/g726-40 +# audio/g728 +# audio/g729 +# audio/g7291 +# audio/g729d +# audio/g729e +# audio/gsm +# audio/gsm-efr +# audio/gsm-hr-08 +# audio/ilbc +# audio/ip-mr_v2.5 +# audio/isac +# audio/l16 +# audio/l20 +# audio/l24 +# audio/l8 +# audio/lpc +audio/midi mid midi kar rmi +# audio/mobile-xmf +audio/mp4 m4a mp4a +# audio/mp4a-latm +# audio/mpa +# audio/mpa-robust +audio/mpeg mp3 mpga mp2 mp2a m2a m3a +# audio/mpeg4-generic +# audio/musepack +audio/ogg ogg oga spx +# audio/opus +# audio/parityfec +# audio/pcma +# audio/pcma-wb +# audio/pcmu +# audio/pcmu-wb +# audio/prs.sid +# audio/qcelp +# audio/raptorfec +# audio/red +# audio/rtp-enc-aescm128 +# audio/rtp-midi +# audio/rtploopback +# audio/rtx +audio/s3m s3m +audio/silk sil +# audio/smv +# audio/smv-qcp +# audio/smv0 +# audio/sp-midi +# audio/speex +# audio/t140c +# audio/t38 +# audio/telephone-event +# audio/tone +# audio/uemclip +# audio/ulpfec +# audio/vdvi +# audio/vmr-wb +# audio/vnd.3gpp.iufp +# audio/vnd.4sb +# audio/vnd.audiokoz +# audio/vnd.celp +# audio/vnd.cisco.nse +# audio/vnd.cmles.radio-events +# audio/vnd.cns.anp1 +# audio/vnd.cns.inf1 +audio/vnd.dece.audio uva uvva +audio/vnd.digital-winds eol +# audio/vnd.dlna.adts +# audio/vnd.dolby.heaac.1 +# audio/vnd.dolby.heaac.2 +# audio/vnd.dolby.mlp +# audio/vnd.dolby.mps +# audio/vnd.dolby.pl2 +# audio/vnd.dolby.pl2x +# audio/vnd.dolby.pl2z +# audio/vnd.dolby.pulse.1 +audio/vnd.dra dra +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +# audio/vnd.dvb.file +# audio/vnd.everad.plj +# audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +# audio/vnd.nokia.mobile-xmf +# audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +# audio/vnd.octel.sbc +# audio/vnd.qcelp +# audio/vnd.rhetorex.32kadpcm +audio/vnd.rip rip +# audio/vnd.sealedmedia.softseal.mpeg +# audio/vnd.vmx.cvsd +# audio/vorbis +# audio/vorbis-config +audio/webm weba +audio/x-aac aac +audio/x-aiff aif aiff aifc +audio/x-caf caf +audio/x-flac flac +audio/x-matroska mka +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin rmp +# audio/x-tta +audio/x-wav wav +audio/xm xm +chemical/x-cdx cdx +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-csml csml +# chemical/x-pdb +chemical/x-xyz xyz +font/collection ttc +font/otf otf +# font/sfnt +font/ttf ttf +font/woff woff +font/woff2 woff2 +image/bmp bmp +image/cgm cgm +# image/dicom-rle +# image/emf +# image/example +# image/fits +image/g3fax g3 +image/gif gif +image/ief ief +# image/jls +# image/jp2 +image/jpeg jpg jpeg jpe +# image/jpm +# image/jpx +image/ktx ktx +# image/naplps +image/png png +image/prs.btif btif +# image/prs.pti +# image/pwg-raster +image/sgi sgi +image/svg+xml svg svgz +# image/t38 +image/tiff tiff tif +# image/tiff-fx +image/vnd.adobe.photoshop psd +# image/vnd.airzip.accelerator.azv +# image/vnd.cns.inf2 +image/vnd.dece.graphic uvi uvvi uvg uvvg +image/vnd.djvu djvu djv +image/vnd.dvb.subtitle sub +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +# image/vnd.globalgraphics.pgb +# image/vnd.microsoft.icon +# image/vnd.mix +# image/vnd.mozilla.apng +image/vnd.ms-modi mdi +image/vnd.ms-photo wdp +image/vnd.net-fpx npx +# image/vnd.radiance +# image/vnd.sealed.png +# image/vnd.sealedmedia.softseal.gif +# image/vnd.sealedmedia.softseal.jpg +# image/vnd.svf +# image/vnd.tencent.tap +# image/vnd.valve.source.texture +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +# image/vnd.zbrush.pcx +image/webp webp +# image/wmf +image/x-3ds 3ds +image/x-cmu-raster ras +image/x-cmx cmx +image/x-freehand fh fhc fh4 fh5 fh7 +image/x-icon ico +image/x-mrsid-image sid +image/x-pcx pcx +image/x-pict pic pct +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-tga tga +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +# message/cpim +# message/delivery-status +# message/disposition-notification +# message/example +# message/external-body +# message/feedback-report +# message/global +# message/global-delivery-status +# message/global-disposition-notification +# message/global-headers +# message/http +# message/imdn+xml +# message/news +# message/partial +message/rfc822 eml mime +# message/s-http +# message/sip +# message/sipfrag +# message/tracking-status +# message/vnd.si.simp +# message/vnd.wfa.wsc +# model/example +# model/gltf+json +model/iges igs iges +model/mesh msh mesh silo +model/vnd.collada+xml dae +model/vnd.dwf dwf +# model/vnd.flatland.3dml +model/vnd.gdl gdl +# model/vnd.gs-gdl +# model/vnd.gs.gdl +model/vnd.gtw gtw +# model/vnd.moml+xml +model/vnd.mts mts +# model/vnd.opengex +# model/vnd.parasolid.transmit.binary +# model/vnd.parasolid.transmit.text +# model/vnd.rosette.annotated-data-model +# model/vnd.valve.source.compiled-map +model/vnd.vtu vtu +model/vrml wrl vrml +model/x3d+binary x3db x3dbz +# model/x3d+fastinfoset +model/x3d+vrml x3dv x3dvz +model/x3d+xml x3d x3dz +# model/x3d-vrml +# multipart/alternative +# multipart/appledouble +# multipart/byteranges +# multipart/digest +# multipart/encrypted +# multipart/example +# multipart/form-data +# multipart/header-set +# multipart/mixed +# multipart/parallel +# multipart/related +# multipart/report +# multipart/signed +# multipart/voice-message +# multipart/x-mixed-replace +# text/1d-interleaved-parityfec +text/cache-manifest appcache +text/calendar ics ifb +text/css css +text/csv csv +# text/csv-schema +# text/directory +# text/dns +# text/ecmascript +# text/encaprtp +# text/enriched +# text/example +# text/fwdred +# text/grammar-ref-list +text/html html htm +# text/javascript +# text/jcr-cnd +# text/markdown +# text/mizar +text/n3 n3 +# text/parameters +# text/parityfec +text/plain txt text conf def list log in +# text/provenance-notation +# text/prs.fallenstein.rst +text/prs.lines.tag dsc +# text/prs.prop.logic +# text/raptorfec +# text/red +# text/rfc822-headers +text/richtext rtx +# text/rtf +# text/rtp-enc-aescm128 +# text/rtploopback +# text/rtx +text/sgml sgml sgm +# text/t140 +text/tab-separated-values tsv +text/troff t tr roff man me ms +text/turtle ttl +# text/ulpfec +text/uri-list uri uris urls +text/vcard vcard +# text/vnd.a +# text/vnd.abc +text/vnd.curl curl +text/vnd.curl.dcurl dcurl +text/vnd.curl.mcurl mcurl +text/vnd.curl.scurl scurl +# text/vnd.debian.copyright +# text/vnd.dmclientscript +text/vnd.dvb.subtitle sub +# text/vnd.esmertec.theme-descriptor +text/vnd.fly fly +text/vnd.fmi.flexstor flx +text/vnd.graphviz gv +text/vnd.in3d.3dml 3dml +text/vnd.in3d.spot spot +# text/vnd.iptc.newsml +# text/vnd.iptc.nitf +# text/vnd.latex-z +# text/vnd.motorola.reflex +# text/vnd.ms-mediapackage +# text/vnd.net2phone.commcenter.command +# text/vnd.radisys.msml-basic-layout +# text/vnd.si.uricatalogue +text/vnd.sun.j2me.app-descriptor jad +# text/vnd.trolltech.linguist +# text/vnd.wap.si +# text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-asm s asm +text/x-c c cc cxx cpp h hh dic +text/x-fortran f for f77 f90 +text/x-java-source java +text/x-nfo nfo +text/x-opml opml +text/x-pascal p pas +text/x-setext etx +text/x-sfv sfv +text/x-uuencode uu +text/x-vcalendar vcs +text/x-vcard vcf +# text/xml +# text/xml-external-parsed-entity +# video/1d-interleaved-parityfec +video/3gpp 3gp +# video/3gpp-tt +video/3gpp2 3g2 +# video/bmpeg +# video/bt656 +# video/celb +# video/dv +# video/encaprtp +# video/example +video/h261 h261 +video/h263 h263 +# video/h263-1998 +# video/h263-2000 +video/h264 h264 +# video/h264-rcdo +# video/h264-svc +# video/h265 +# video/iso.segment +video/jpeg jpgv +# video/jpeg2000 +video/jpm jpm jpgm +video/mj2 mj2 mjp2 +# video/mp1s +# video/mp2p +# video/mp2t +video/mp4 mp4 mp4v mpg4 +# video/mp4v-es +video/mpeg mpeg mpg mpe m1v m2v +# video/mpeg4-generic +# video/mpv +# video/nv +video/ogg ogv +# video/parityfec +# video/pointer +video/quicktime qt mov +# video/raptorfec +# video/raw +# video/rtp-enc-aescm128 +# video/rtploopback +# video/rtx +# video/smpte292m +# video/ulpfec +# video/vc1 +# video/vnd.cctv +video/vnd.dece.hd uvh uvvh +video/vnd.dece.mobile uvm uvvm +# video/vnd.dece.mp4 +video/vnd.dece.pd uvp uvvp +video/vnd.dece.sd uvs uvvs +video/vnd.dece.video uvv uvvv +# video/vnd.directv.mpeg +# video/vnd.directv.mpeg-tts +# video/vnd.dlna.mpeg-tts +video/vnd.dvb.file dvb +video/vnd.fvt fvt +# video/vnd.hns.video +# video/vnd.iptvforum.1dparityfec-1010 +# video/vnd.iptvforum.1dparityfec-2005 +# video/vnd.iptvforum.2dparityfec-1010 +# video/vnd.iptvforum.2dparityfec-2005 +# video/vnd.iptvforum.ttsavc +# video/vnd.iptvforum.ttsmpeg2 +# video/vnd.motorola.video +# video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +# video/vnd.nokia.interleaved-multimedia +# video/vnd.nokia.videovoip +# video/vnd.objectvideo +# video/vnd.radgamettools.bink +# video/vnd.radgamettools.smacker +# video/vnd.sealed.mpeg1 +# video/vnd.sealed.mpeg4 +# video/vnd.sealed.swf +# video/vnd.sealedmedia.softseal.mov +video/vnd.uvvu.mp4 uvu uvvu +video/vnd.vivo viv +# video/vp8 +video/webm webm +video/x-f4v f4v +video/x-fli fli +video/x-flv flv +video/x-m4v m4v +video/x-matroska mkv mk3d mks +video/x-mng mng +video/x-ms-asf asf asx +video/x-ms-vob vob +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +video/x-smv smv +x-conference/x-cooltalk ice \ No newline at end of file diff --git a/pyrogram/client/methods/messages/edit_message_media.py b/pyrogram/client/methods/messages/edit_message_media.py index ea5870fc..69693384 100644 --- a/pyrogram/client/methods/messages/edit_message_media.py +++ b/pyrogram/client/methods/messages/edit_message_media.py @@ -123,7 +123,7 @@ class EditMessageMedia(BaseClient): functions.messages.UploadMedia( peer=self.resolve_peer(chat_id), media=types.InputMediaUploadedDocument( - mime_type="video/mp4", + mime_type=self.guess_mime_type(media.media) or "video/mp4", thumb=None if media.thumb is None else self.save_file(media.thumb), file=self.save_file(media.media), attributes=[ @@ -182,7 +182,7 @@ class EditMessageMedia(BaseClient): functions.messages.UploadMedia( peer=self.resolve_peer(chat_id), media=types.InputMediaUploadedDocument( - mime_type="audio/mpeg", + mime_type=self.guess_mime_type(media.media) or "audio/mpeg", thumb=None if media.thumb is None else self.save_file(media.thumb), file=self.save_file(media.media), attributes=[ @@ -240,7 +240,7 @@ class EditMessageMedia(BaseClient): functions.messages.UploadMedia( peer=self.resolve_peer(chat_id), media=types.InputMediaUploadedDocument( - mime_type="video/mp4", + mime_type=self.guess_mime_type(media.media) or "video/mp4", thumb=None if media.thumb is None else self.save_file(media.thumb), file=self.save_file(media.media), attributes=[ @@ -300,7 +300,7 @@ class EditMessageMedia(BaseClient): functions.messages.UploadMedia( peer=self.resolve_peer(chat_id), media=types.InputMediaUploadedDocument( - mime_type="application/zip", + mime_type=self.guess_mime_type(media.media) or "application/zip", thumb=None if media.thumb is None else self.save_file(media.thumb), file=self.save_file(media.media), attributes=[ diff --git a/pyrogram/client/methods/messages/send_animation.py b/pyrogram/client/methods/messages/send_animation.py index 798d236d..2ef67a4e 100644 --- a/pyrogram/client/methods/messages/send_animation.py +++ b/pyrogram/client/methods/messages/send_animation.py @@ -135,7 +135,7 @@ class SendAnimation(BaseClient): thumb = None if thumb is None else self.save_file(thumb) file = self.save_file(animation, progress=progress, progress_args=progress_args) media = types.InputMediaUploadedDocument( - mime_type="video/mp4", + mime_type=self.guess_mime_type(animation) or "video/mp4", file=file, thumb=thumb, attributes=[ diff --git a/pyrogram/client/methods/messages/send_audio.py b/pyrogram/client/methods/messages/send_audio.py index d514b737..ee9cd305 100644 --- a/pyrogram/client/methods/messages/send_audio.py +++ b/pyrogram/client/methods/messages/send_audio.py @@ -137,7 +137,7 @@ class SendAudio(BaseClient): thumb = None if thumb is None else self.save_file(thumb) file = self.save_file(audio, progress=progress, progress_args=progress_args) media = types.InputMediaUploadedDocument( - mime_type="audio/mpeg", + mime_type=self.guess_mime_type(audio) or "audio/mpeg", file=file, thumb=thumb, attributes=[ diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index a36a0fbb..a71c79e6 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -123,7 +123,7 @@ class SendDocument(BaseClient): thumb = None if thumb is None else self.save_file(thumb) file = self.save_file(document, progress=progress, progress_args=progress_args) media = types.InputMediaUploadedDocument( - mime_type="application/zip", + mime_type=self.guess_mime_type(document) or "application/zip", file=file, thumb=thumb, attributes=[ diff --git a/pyrogram/client/methods/messages/send_media_group.py b/pyrogram/client/methods/messages/send_media_group.py index 4fdc1132..f40401b0 100644 --- a/pyrogram/client/methods/messages/send_media_group.py +++ b/pyrogram/client/methods/messages/send_media_group.py @@ -129,7 +129,7 @@ class SendMediaGroup(BaseClient): media=types.InputMediaUploadedDocument( file=self.save_file(i.media), thumb=None if i.thumb is None else self.save_file(i.thumb), - mime_type="video/mp4", + mime_type=self.guess_mime_type(i.media) or "video/mp4", attributes=[ types.DocumentAttributeVideo( supports_streaming=i.supports_streaming or None, diff --git a/pyrogram/client/methods/messages/send_sticker.py b/pyrogram/client/methods/messages/send_sticker.py index e556aae3..a10f3b74 100644 --- a/pyrogram/client/methods/messages/send_sticker.py +++ b/pyrogram/client/methods/messages/send_sticker.py @@ -104,7 +104,7 @@ class SendSticker(BaseClient): if os.path.exists(sticker): file = self.save_file(sticker, progress=progress, progress_args=progress_args) media = types.InputMediaUploadedDocument( - mime_type="image/webp", + mime_type=self.guess_mime_type(sticker) or "image/webp", file=file, attributes=[ types.DocumentAttributeFilename(file_name=os.path.basename(sticker)) diff --git a/pyrogram/client/methods/messages/send_video.py b/pyrogram/client/methods/messages/send_video.py index 08d8b7ab..0faf8e38 100644 --- a/pyrogram/client/methods/messages/send_video.py +++ b/pyrogram/client/methods/messages/send_video.py @@ -139,7 +139,7 @@ class SendVideo(BaseClient): thumb = None if thumb is None else self.save_file(thumb) file = self.save_file(video, progress=progress, progress_args=progress_args) media = types.InputMediaUploadedDocument( - mime_type="video/mp4", + mime_type=self.guess_mime_type(video) or "video/mp4", file=file, thumb=thumb, attributes=[ diff --git a/pyrogram/client/methods/messages/send_video_note.py b/pyrogram/client/methods/messages/send_video_note.py index 4844dd65..b2547d04 100644 --- a/pyrogram/client/methods/messages/send_video_note.py +++ b/pyrogram/client/methods/messages/send_video_note.py @@ -120,7 +120,7 @@ class SendVideoNote(BaseClient): thumb = None if thumb is None else self.save_file(thumb) file = self.save_file(video_note, progress=progress, progress_args=progress_args) media = types.InputMediaUploadedDocument( - mime_type="video/mp4", + mime_type=self.guess_mime_type(video_note) or "video/mp4", file=file, thumb=thumb, attributes=[ diff --git a/pyrogram/client/methods/messages/send_voice.py b/pyrogram/client/methods/messages/send_voice.py index 110b0704..44e998b6 100644 --- a/pyrogram/client/methods/messages/send_voice.py +++ b/pyrogram/client/methods/messages/send_voice.py @@ -119,7 +119,7 @@ class SendVoice(BaseClient): if os.path.exists(voice): file = self.save_file(voice, progress=progress, progress_args=progress_args) media = types.InputMediaUploadedDocument( - mime_type="audio/mpeg", + mime_type=self.guess_mime_type(voice) or "audio/mpeg", file=file, attributes=[ types.DocumentAttributeAudio( From cec43bf568c97c520a966e1510f7b4bc8273f2d1 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 20 Apr 2019 18:57:07 +0200 Subject: [PATCH 012/202] Update develop version --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 44dbe231..bf688797 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -24,7 +24,7 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]: # Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one. sys.modules["typing"] = typing -__version__ = "0.12.0" +__version__ = "0.13.0.develop" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __copyright__ = "Copyright (C) 2017-2019 Dan Tès ".replace( "\xe8", "e" if sys.getfilesystemencoding() != "utf-8" else "\xe8" From e7258a341ba905cfa86264c22040654db732ec1c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 20 Apr 2019 22:51:54 +0200 Subject: [PATCH 013/202] Add mime.types in MANIFEST.in --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index f818e13a..80c061ff 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ ## Include include COPYING COPYING.lesser NOTICE requirements.txt recursive-include compiler *.py *.tl *.tsv *.txt +recursive-include pyrogram mime.types ## Exclude prune pyrogram/api/errors/exceptions From 94574efe2c6c5001ec444e4a219337cc72f7c833 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 10:33:11 +0200 Subject: [PATCH 014/202] Remove unneeded method --- pyrogram/client/handlers/inline_query_handler.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pyrogram/client/handlers/inline_query_handler.py b/pyrogram/client/handlers/inline_query_handler.py index e59514c0..c64d49c8 100644 --- a/pyrogram/client/handlers/inline_query_handler.py +++ b/pyrogram/client/handlers/inline_query_handler.py @@ -45,10 +45,3 @@ class InlineQueryHandler(Handler): def __init__(self, callback: callable, filters=None): super().__init__(callback, filters) - - def check(self, callback_query): - return ( - self.filters(callback_query) - if callable(self.filters) - else True - ) From 16d3b2d56e751570358edf60ae90d143dd7f0534 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 10:45:27 +0200 Subject: [PATCH 015/202] Make sure mime.types actually gets installed --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index cba41b78..ef02c428 100644 --- a/setup.py +++ b/setup.py @@ -171,6 +171,9 @@ setup( }, python_requires="~=3.4", packages=find_packages(exclude=["compiler*"]), + package_data={ + "pyrogram.client.ext": ["mime.types"] + }, zip_safe=False, install_requires=read("requirements.txt"), extras_require={ From 2aad59856d27aa36bfe5ebd25a4408580b03929f Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 11:04:37 +0200 Subject: [PATCH 016/202] Fix export_chat_invite_link broken because of Layer update Fixes #244 --- .../client/methods/chats/export_chat_invite_link.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pyrogram/client/methods/chats/export_chat_invite_link.py b/pyrogram/client/methods/chats/export_chat_invite_link.py index b84b1d3c..c9c7ca41 100644 --- a/pyrogram/client/methods/chats/export_chat_invite_link.py +++ b/pyrogram/client/methods/chats/export_chat_invite_link.py @@ -44,15 +44,11 @@ class ExportChatInviteLink(BaseClient): """ peer = self.resolve_peer(chat_id) - if isinstance(peer, types.InputPeerChat): + if isinstance(peer, (types.InputPeerChat, types.InputPeerChannel)): return self.send( functions.messages.ExportChatInvite( - peer=peer.chat_id - ) - ).link - elif isinstance(peer, types.InputPeerChannel): - return self.send( - functions.channels.ExportInvite( - channel=peer + peer=peer ) ).link + else: + raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) From d83a2a951d72b8b9cfbc67a166ac953851774a88 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 11:22:23 +0200 Subject: [PATCH 017/202] Revert "Fix export_chat_invite_link broken because of Layer update Fixes #244" This reverts commit 2aad5985 --- .../client/methods/chats/export_chat_invite_link.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pyrogram/client/methods/chats/export_chat_invite_link.py b/pyrogram/client/methods/chats/export_chat_invite_link.py index c9c7ca41..b84b1d3c 100644 --- a/pyrogram/client/methods/chats/export_chat_invite_link.py +++ b/pyrogram/client/methods/chats/export_chat_invite_link.py @@ -44,11 +44,15 @@ class ExportChatInviteLink(BaseClient): """ peer = self.resolve_peer(chat_id) - if isinstance(peer, (types.InputPeerChat, types.InputPeerChannel)): + if isinstance(peer, types.InputPeerChat): return self.send( functions.messages.ExportChatInvite( - peer=peer + peer=peer.chat_id + ) + ).link + elif isinstance(peer, types.InputPeerChannel): + return self.send( + functions.channels.ExportInvite( + channel=peer ) ).link - else: - raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) From 881f3e479aaf310f927fe4504bdaddd7306580b4 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 11:23:31 +0200 Subject: [PATCH 018/202] Bring the old, but working, channels.exportInvite method back We keep this until the server decides to enable the new methods for bots --- compiler/api/source/main_api.tl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/api/source/main_api.tl b/compiler/api/source/main_api.tl index 581427b5..61c9faf6 100644 --- a/compiler/api/source/main_api.tl +++ b/compiler/api/source/main_api.tl @@ -1313,3 +1313,6 @@ langpack.getLanguages#42c6978f lang_pack:string = Vector; langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage; // LAYER 97 + +// Ports +channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite; \ No newline at end of file From cc9bc56391cbe4add6915846d1669c045e100a8a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 11:29:54 +0200 Subject: [PATCH 019/202] Add important note to export_chat_invite_link --- pyrogram/client/methods/chats/export_chat_invite_link.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyrogram/client/methods/chats/export_chat_invite_link.py b/pyrogram/client/methods/chats/export_chat_invite_link.py index b84b1d3c..16f5bc01 100644 --- a/pyrogram/client/methods/chats/export_chat_invite_link.py +++ b/pyrogram/client/methods/chats/export_chat_invite_link.py @@ -31,6 +31,13 @@ class ExportChatInviteLink(BaseClient): You must be an administrator in the chat for this to work and have the appropriate admin rights. + .. note :: + + Each administrator in a chat generates their own invite links. Bots can't use invite links generated by + other administrators. If you want your bot to work with invite links, it will need to generate its own link + using this method – after this the link will become available to the bot via the :meth:`get_chat` method. + If your bot needs to generate a new invite link replacing its previous one, use this method again. + Args: chat_id (``int`` | ``str``): Unique identifier for the target chat or username of the target channel/supergroup From d30cad1a2dccfca1fc2b8386732b35711a937a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joscha=20G=C3=B6tzer?= Date: Tue, 30 Apr 2019 11:49:18 +0200 Subject: [PATCH 020/202] Use str or bytes for callback_data and CallbackQuery.data (#241) --- pyrogram/client/types/bots/callback_query.py | 2 +- pyrogram/client/types/bots/inline_keyboard_button.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/types/bots/callback_query.py b/pyrogram/client/types/bots/callback_query.py index 4497747e..ac58338a 100644 --- a/pyrogram/client/types/bots/callback_query.py +++ b/pyrogram/client/types/bots/callback_query.py @@ -79,7 +79,7 @@ class CallbackQuery(PyrogramType, Update): self.chat_instance = chat_instance self.message = message self.inline_message_id = inline_message_id - self.data = data + self.data = str(data, "utf-8") self.game_short_name = game_short_name @staticmethod diff --git a/pyrogram/client/types/bots/inline_keyboard_button.py b/pyrogram/client/types/bots/inline_keyboard_button.py index c0c3eb8c..a26d6ca6 100644 --- a/pyrogram/client/types/bots/inline_keyboard_button.py +++ b/pyrogram/client/types/bots/inline_keyboard_button.py @@ -16,6 +16,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from typing import Union + from pyrogram.api.types import ( KeyboardButtonUrl, KeyboardButtonCallback, KeyboardButtonSwitchInline, KeyboardButtonGame @@ -61,7 +63,7 @@ class InlineKeyboardButton(PyrogramType): def __init__( self, text: str, - callback_data: bytes = None, + callback_data: Union[str, bytes] = None, url: str = None, switch_inline_query: str = None, switch_inline_query_current_chat: str = None, @@ -71,7 +73,7 @@ class InlineKeyboardButton(PyrogramType): self.text = str(text) self.url = url - self.callback_data = callback_data + self.callback_data = bytes(callback_data, "utf-8") if isinstance(callback_data, str) else callback_data self.switch_inline_query = switch_inline_query self.switch_inline_query_current_chat = switch_inline_query_current_chat self.callback_game = callback_game From 80081a29b48e24d3bf9dd261bc3594b931f513e6 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 30 Apr 2019 14:43:57 +0200 Subject: [PATCH 021/202] Add supports_streaming attribute to the Video type --- .../client/types/messages_and_media/video.py | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/video.py b/pyrogram/client/types/messages_and_media/video.py index caf34ce9..a45a8f8d 100644 --- a/pyrogram/client/types/messages_and_media/video.py +++ b/pyrogram/client/types/messages_and_media/video.py @@ -50,6 +50,9 @@ class Video(PyrogramType): mime_type (``str``, *optional*): Mime type of a file as defined by sender. + supports_streaming (``bool``, *optional*): + True, if the video was uploaded with streaming support. + file_size (``int``, *optional*): File size. @@ -57,7 +60,10 @@ class Video(PyrogramType): Date the video was sent in Unix time. """ - __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date", "width", "height", "duration"] + __slots__ = [ + "file_id", "width", "height", "duration", "thumb", "file_name", "mime_type", "supports_streaming", "file_size", + "date" + ] def __init__( self, @@ -70,20 +76,22 @@ class Video(PyrogramType): thumb: PhotoSize = None, file_name: str = None, mime_type: str = None, + supports_streaming: bool = None, file_size: int = None, date: int = None ): super().__init__(client) self.file_id = file_id - self.thumb = thumb - self.file_name = file_name - self.mime_type = mime_type - self.file_size = file_size - self.date = date self.width = width self.height = height self.duration = duration + self.thumb = thumb + self.file_name = file_name + self.mime_type = mime_type + self.supports_streaming = supports_streaming + self.file_size = file_size + self.date = date @staticmethod def _parse(client, video: types.Document, video_attributes: types.DocumentAttributeVideo, @@ -102,9 +110,10 @@ class Video(PyrogramType): height=video_attributes.h, duration=video_attributes.duration, thumb=PhotoSize._parse(client, video.thumbs), - mime_type=video.mime_type, - file_size=video.size, file_name=file_name, + mime_type=video.mime_type, + supports_streaming=video_attributes.supports_streaming, + file_size=video.size, date=video.date, client=client ) From 58482919ba826b36d5e7b60e8e9203c4f715093a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 5 May 2019 12:21:20 +0200 Subject: [PATCH 022/202] Make is_member field actually working --- pyrogram/client/types/user_and_chats/chat_member.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 9ccf9314..046d2ebc 100644 --- a/pyrogram/client/types/user_and_chats/chat_member.py +++ b/pyrogram/client/types/user_and_chats/chat_member.py @@ -126,17 +126,11 @@ class ChatMember(PyrogramType): ) if isinstance(member, types.ChannelParticipantBanned): - status = ( - "kicked" if member.banned_rights.view_messages - else "left" if member.left - else "restricted" - ) - return ChatMember( user=user, - status=status, + status="kicked" if member.banned_rights.view_messages else "restricted", date=member.date, - is_member=not member.left if status == "restricted" else None, + is_member=not member.left, restricted_by=pyrogram.User._parse(client, users[member.kicked_by]), permissions=pyrogram.ChatPermissions._parse(member), client=client From bfda5852b6ba587709b24c9b0423ec77cb498db3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 5 May 2019 15:44:28 +0200 Subject: [PATCH 023/202] Hint the return type of get_history --- pyrogram/client/methods/messages/get_history.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/methods/messages/get_history.py b/pyrogram/client/methods/messages/get_history.py index fda8f11f..1953fabc 100644 --- a/pyrogram/client/methods/messages/get_history.py +++ b/pyrogram/client/methods/messages/get_history.py @@ -37,7 +37,7 @@ class GetHistory(BaseClient): offset_id: int = 0, offset_date: int = 0, reverse: bool = False - ): + ) -> "pyrogram.Messages": """Use this method to retrieve a chunk of the history of a chat. You can get up to 100 messages at once. From 6f2c625cd1c3c769b5db2b2af519e7515a8fd930 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 5 May 2019 15:44:53 +0200 Subject: [PATCH 024/202] Handle minified poll updates --- pyrogram/client/ext/dispatcher.py | 2 +- .../client/types/messages_and_media/poll.py | 37 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 46be47f7..1004095b 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -82,7 +82,7 @@ class Dispatcher: lambda upd, usr, cht: (pyrogram.InlineQuery._parse(self.client, upd, usr), InlineQueryHandler), (types.UpdateMessagePoll,): - lambda upd, usr, cht: (pyrogram.Poll._parse(self.client, upd), PollHandler) + lambda upd, usr, cht: (pyrogram.Poll._parse_update(self.client, upd), PollHandler) } self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple} diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index acaf8697..fa68f669 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import List +from typing import List, Union import pyrogram from pyrogram.api import types @@ -71,12 +71,11 @@ class Poll(PyrogramType, Update): self.chosen_option = chosen_option @staticmethod - def _parse(client, media_poll: types.MessageMediaPoll) -> "Poll": + def _parse(client, media_poll: Union[types.MessageMediaPoll, types.UpdateMessagePoll]) -> "Poll": poll = media_poll.poll results = media_poll.results.results total_voters = media_poll.results.total_voters chosen_option = None - options = [] for i, answer in enumerate(poll.answers): @@ -107,3 +106,35 @@ class Poll(PyrogramType, Update): chosen_option=chosen_option, client=client ) + + @staticmethod + def _parse_update(client, update: types.UpdateMessagePoll): + if update.poll is not None: + return Poll._parse(client, update) + + results = update.results.results + chosen_option = None + options = [] + + for i, result in enumerate(results): + if result.chosen: + chosen_option = i + + options.append( + PollOption( + text="", + voter_count=result.voters, + data=result.option, + client=client + ) + ) + + return Poll( + id=str(update.poll_id), + question="", + options=options, + is_closed=False, + total_voters=update.results.total_voters, + chosen_option=chosen_option, + client=client + ) From 01f0af6bb033fa8468bc495d5afb4b3009288037 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 16:36:57 +0200 Subject: [PATCH 025/202] Increase OFFLINE_SLEEP to 15 minutes This avoid frequent dialogs fetch while debugging with user accounts --- pyrogram/client/ext/base_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index b4bfbd6b..ee7b2c24 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -50,7 +50,7 @@ class BaseClient: DIALOGS_AT_ONCE = 100 UPDATES_WORKERS = 1 DOWNLOAD_WORKERS = 1 - OFFLINE_SLEEP = 300 + OFFLINE_SLEEP = 900 WORKERS = 4 WORKDIR = "." CONFIG_FILE = "./config.ini" From 95ef9a64deb01ea4ca523a42f9d674079387b96c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 16:40:07 +0200 Subject: [PATCH 026/202] Fix small typos --- docs/source/pyrogram/Client.rst | 2 +- pyrogram/client/types/user_and_chats/dialog.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index dcf8bb79..3a7c231f 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -69,7 +69,7 @@ Messages iter_history send_poll vote_poll - close_poll + stop_poll retract_vote download_media diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index 1bbd3b4b..d406d783 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -34,7 +34,7 @@ class Dialog(PyrogramType): The last message sent in the dialog at this time. unread_messages_count (``int``): - Amount of unread messages in this dialogs. + Amount of unread messages in this dialog. unread_mentions_count (``int``): Amount of unread messages containing a mention in this dialog. From e80eebc23494ecd558a4067fd0b6e3176cbc0261 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 16:44:50 +0200 Subject: [PATCH 027/202] Add get_history_count method --- docs/source/pyrogram/Client.rst | 1 + pyrogram/client/methods/messages/__init__.py | 6 +- .../methods/messages/get_history_count.py | 84 +++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 pyrogram/client/methods/messages/get_history_count.py diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index 3a7c231f..59293273 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -66,6 +66,7 @@ Messages delete_messages get_messages get_history + get_history_count iter_history send_poll vote_poll diff --git a/pyrogram/client/methods/messages/__init__.py b/pyrogram/client/methods/messages/__init__.py index d26c51cc..e843aa7c 100644 --- a/pyrogram/client/methods/messages/__init__.py +++ b/pyrogram/client/methods/messages/__init__.py @@ -16,7 +16,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .stop_poll import StopPoll from .delete_messages import DeleteMessages from .download_media import DownloadMedia from .edit_message_caption import EditMessageCaption @@ -25,6 +24,7 @@ from .edit_message_reply_markup import EditMessageReplyMarkup from .edit_message_text import EditMessageText from .forward_messages import ForwardMessages from .get_history import GetHistory +from .get_history_count import GetHistoryCount from .get_messages import GetMessages from .iter_history import IterHistory from .retract_vote import RetractVote @@ -44,6 +44,7 @@ from .send_venue import SendVenue from .send_video import SendVideo from .send_video_note import SendVideoNote from .send_voice import SendVoice +from .stop_poll import StopPoll from .vote_poll import VotePoll @@ -76,6 +77,7 @@ class Messages( RetractVote, DownloadMedia, IterHistory, - SendCachedMedia + SendCachedMedia, + GetHistoryCount ): pass diff --git a/pyrogram/client/methods/messages/get_history_count.py b/pyrogram/client/methods/messages/get_history_count.py new file mode 100644 index 00000000..046ec095 --- /dev/null +++ b/pyrogram/client/methods/messages/get_history_count.py @@ -0,0 +1,84 @@ +# 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 . + +import logging +import time +from typing import Union + +from pyrogram.api import types, functions +from pyrogram.client.ext import BaseClient +from pyrogram.errors import FloodWait + +log = logging.getLogger(__name__) + + +class GetHistoryCount(BaseClient): + def get_history_count( + self, + chat_id: Union[int, str] + ) -> int: + """Use this method to get the total count of messages in a chat. + + .. note:: + + Due to Telegram latest internal changes, the server can't reliably find anymore the total count of messages + a **private** or a **basic group** chat has with a single method call. To overcome this limitation, Pyrogram + has to iterate over all the messages. Channels and supergroups are not affected by this limitation. + + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + + Returns: + On success, an integer is returned. + + Raises: + :class:`RPCError ` in case of a Telegram RPC error. + """ + + peer = self.resolve_peer(chat_id) + + if not isinstance(peer, types.InputPeerChannel): + offset = 0 + limit = 100 + + while True: + try: + r = self.send( + functions.messages.GetHistory( + peer=peer, + offset_id=1, + offset_date=0, + add_offset=-offset - limit, + limit=limit, + max_id=0, + min_id=0, + hash=0 + ) + ) + except FloodWait as e: + log.warning("Sleeping for {}s".format(e.x)) + time.sleep(e.x) + continue + + if not r.messages: + return offset + + offset += len(r.messages) + + return self.get_history(chat_id=chat_id, limit=1).total_count From 4e77ead18171d6c692d57737c88dbf2f00ea007b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 16:54:50 +0200 Subject: [PATCH 028/202] Add get_dialogs_count method --- docs/source/pyrogram/Client.rst | 1 + pyrogram/client/methods/chats/__init__.py | 4 +- .../client/methods/chats/get_dialogs_count.py | 51 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 pyrogram/client/methods/chats/get_dialogs_count.py diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index 59293273..e704cc1e 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -101,6 +101,7 @@ Chats iter_chat_members get_dialogs iter_dialogs + get_dialogs_count restrict_chat update_chat_username diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index c708453f..8db44abe 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -39,6 +39,7 @@ from .set_chat_title import SetChatTitle from .unban_chat_member import UnbanChatMember from .unpin_chat_message import UnpinChatMessage from .update_chat_username import UpdateChatUsername +from .get_dialogs_count import GetDialogsCount class Chats( @@ -64,6 +65,7 @@ class Chats( IterDialogs, IterChatMembers, UpdateChatUsername, - RestrictChat + RestrictChat, + GetDialogsCount ): pass diff --git a/pyrogram/client/methods/chats/get_dialogs_count.py b/pyrogram/client/methods/chats/get_dialogs_count.py new file mode 100644 index 00000000..1ba6895f --- /dev/null +++ b/pyrogram/client/methods/chats/get_dialogs_count.py @@ -0,0 +1,51 @@ +# 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 pyrogram.api import functions, types +from ...ext import BaseClient + + +class GetDialogsCount(BaseClient): + def get_dialogs_count(self, pinned_only: bool = False) -> int: + """Use this method to get the total count of your dialogs. + + pinned_only (``bool``, *optional*): + Pass True if you want to count only pinned dialogs. + Defaults to False. + + Returns: + On success, an integer is returned. + + Raises: + :class:`RPCError ` in case of a Telegram RPC error. + """ + + if pinned_only: + return len(self.send(functions.messages.GetPinnedDialogs()).dialogs) + else: + r = self.send( + functions.messages.GetDialogs( + offset_date=0, + offset_id=0, + offset_peer=types.InputPeerEmpty(), + limit=1, + hash=0 + ) + ) + + return r.count From e8e0c16daf1b4f30370b02969d6620d1e6a60317 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 17:00:09 +0200 Subject: [PATCH 029/202] Add get_contacts_count method --- docs/source/pyrogram/Client.rst | 1 + pyrogram/client/methods/contacts/__init__.py | 4 ++- .../methods/contacts/get_contacts_count.py | 34 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 pyrogram/client/methods/contacts/get_contacts_count.py diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index e704cc1e..e3ef2d69 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -126,6 +126,7 @@ Contacts add_contacts get_contacts + get_contacts_count delete_contacts Password diff --git a/pyrogram/client/methods/contacts/__init__.py b/pyrogram/client/methods/contacts/__init__.py index ab9ae6ef..a966d10a 100644 --- a/pyrogram/client/methods/contacts/__init__.py +++ b/pyrogram/client/methods/contacts/__init__.py @@ -19,11 +19,13 @@ from .add_contacts import AddContacts from .delete_contacts import DeleteContacts from .get_contacts import GetContacts +from .get_contacts_count import GetContactsCount class Contacts( GetContacts, DeleteContacts, - AddContacts + AddContacts, + GetContactsCount ): pass diff --git a/pyrogram/client/methods/contacts/get_contacts_count.py b/pyrogram/client/methods/contacts/get_contacts_count.py new file mode 100644 index 00000000..b41b27b8 --- /dev/null +++ b/pyrogram/client/methods/contacts/get_contacts_count.py @@ -0,0 +1,34 @@ +# 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 pyrogram.api import functions +from ...ext import BaseClient + + +class GetContactsCount(BaseClient): + def get_contacts_count(self) -> int: + """Use this method to get the total count of contacts from your Telegram address book. + + Returns: + On success, an integer is returned. + + Raises: + :class:`RPCError ` in case of a Telegram RPC error. + """ + + return len(self.send(functions.contacts.GetContacts(hash=0)).contacts) From 08554633ce90a01b29931156c555760bd3567a9b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 17:07:41 +0200 Subject: [PATCH 030/202] Add get_user_profile_photos_count method --- docs/source/pyrogram/Client.rst | 1 + pyrogram/client/methods/users/__init__.py | 4 +- .../users/get_user_profile_photos_count.py | 54 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 pyrogram/client/methods/users/get_user_profile_photos_count.py diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index e3ef2d69..5adf4956 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -114,6 +114,7 @@ Users get_me get_users get_user_profile_photos + get_user_profile_photos_count set_user_profile_photo delete_user_profile_photos update_username diff --git a/pyrogram/client/methods/users/__init__.py b/pyrogram/client/methods/users/__init__.py index f8c39650..d67a18bd 100644 --- a/pyrogram/client/methods/users/__init__.py +++ b/pyrogram/client/methods/users/__init__.py @@ -19,6 +19,7 @@ from .delete_user_profile_photos import DeleteUserProfilePhotos from .get_me import GetMe from .get_user_profile_photos import GetUserProfilePhotos +from .get_user_profile_photos_count import GetUserProfilePhotosCount from .get_users import GetUsers from .set_user_profile_photo import SetUserProfilePhoto from .update_username import UpdateUsername @@ -30,6 +31,7 @@ class Users( DeleteUserProfilePhotos, GetUsers, GetMe, - UpdateUsername + UpdateUsername, + GetUserProfilePhotosCount ): pass diff --git a/pyrogram/client/methods/users/get_user_profile_photos_count.py b/pyrogram/client/methods/users/get_user_profile_photos_count.py new file mode 100644 index 00000000..fdb81790 --- /dev/null +++ b/pyrogram/client/methods/users/get_user_profile_photos_count.py @@ -0,0 +1,54 @@ +# 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 typing import Union + +from pyrogram.api import functions, types +from ...ext import BaseClient + + +class GetUserProfilePhotosCount(BaseClient): + def get_user_profile_photos_count(self, user_id: Union[int, str]) -> int: + """Use this method to get the total count of profile pictures for a user. + + Args: + user_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For your personal cloud (Saved Messages) you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + Returns: + On success, an integer is returned. + + Raises: + :class:`RPCError ` in case of a Telegram RPC error. + """ + + r = self.send( + functions.photos.GetUserPhotos( + user_id=self.resolve_peer(user_id), + offset=0, + max_id=0, + limit=1 + ) + ) + + if isinstance(r, types.photos.Photos): + return len(r.photos) + else: + return r.count From 692073c856837e1e5e71f174cd4b866d12dd0f90 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 17:09:44 +0200 Subject: [PATCH 031/202] Fix get_dialogs_count breaking in case of less than 200 dialogs --- pyrogram/client/methods/chats/get_dialogs_count.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/methods/chats/get_dialogs_count.py b/pyrogram/client/methods/chats/get_dialogs_count.py index 1ba6895f..bf1754ee 100644 --- a/pyrogram/client/methods/chats/get_dialogs_count.py +++ b/pyrogram/client/methods/chats/get_dialogs_count.py @@ -48,4 +48,7 @@ class GetDialogsCount(BaseClient): ) ) - return r.count + if isinstance(r, types.messages.Dialogs): + return len(r.dialogs) + else: + return r.count From 591499121f5a68baefb12743d8af2c79b7c103c8 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 6 May 2019 17:39:57 +0200 Subject: [PATCH 032/202] Add an hint about which client is loading the plugins --- pyrogram/client/client.py | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index ec47c448..8d706084 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -1176,8 +1176,8 @@ class Client(Methods, BaseClient): if isinstance(handler, Handler) and isinstance(group, int): self.add_handler(handler, group) - log.info('[LOAD] {}("{}") in group {} from "{}"'.format( - type(handler).__name__, name, group, module_path)) + log.info('[{}] [LOAD] {}("{}") in group {} from "{}"'.format( + self.session_name, type(handler).__name__, name, group, module_path)) count += 1 except Exception: @@ -1190,11 +1190,13 @@ class Client(Methods, BaseClient): try: module = import_module(module_path) except ImportError: - log.warning('[LOAD] Ignoring non-existent module "{}"'.format(module_path)) + log.warning('[{}] [LOAD] Ignoring non-existent module "{}"'.format( + self.session_name, module_path)) continue if "__path__" in dir(module): - log.warning('[LOAD] Ignoring namespace "{}"'.format(module_path)) + log.warning('[{}] [LOAD] Ignoring namespace "{}"'.format( + self.session_name, module_path)) continue if handlers is None: @@ -1209,14 +1211,14 @@ class Client(Methods, BaseClient): if isinstance(handler, Handler) and isinstance(group, int): self.add_handler(handler, group) - log.info('[LOAD] {}("{}") in group {} from "{}"'.format( - type(handler).__name__, name, group, module_path)) + log.info('[{}] [LOAD] {}("{}") in group {} from "{}"'.format( + self.session_name, type(handler).__name__, name, group, module_path)) count += 1 except Exception: if warn_non_existent_functions: - log.warning('[LOAD] Ignoring non-existent function "{}" from "{}"'.format( - name, module_path)) + log.warning('[{}] [LOAD] Ignoring non-existent function "{}" from "{}"'.format( + self.session_name, name, module_path)) if exclude is not None: for path, handlers in exclude: @@ -1226,11 +1228,13 @@ class Client(Methods, BaseClient): try: module = import_module(module_path) except ImportError: - log.warning('[UNLOAD] Ignoring non-existent module "{}"'.format(module_path)) + log.warning('[{}] [UNLOAD] Ignoring non-existent module "{}"'.format( + self.session_name, module_path)) continue if "__path__" in dir(module): - log.warning('[UNLOAD] Ignoring namespace "{}"'.format(module_path)) + log.warning('[{}] [UNLOAD] Ignoring namespace "{}"'.format( + self.session_name, module_path)) continue if handlers is None: @@ -1245,19 +1249,21 @@ class Client(Methods, BaseClient): if isinstance(handler, Handler) and isinstance(group, int): self.remove_handler(handler, group) - log.info('[UNLOAD] {}("{}") from group {} in "{}"'.format( - type(handler).__name__, name, group, module_path)) + log.info('[{}] [UNLOAD] {}("{}") from group {} in "{}"'.format( + self.session_name, type(handler).__name__, name, group, module_path)) count -= 1 except Exception: if warn_non_existent_functions: - log.warning('[UNLOAD] Ignoring non-existent function "{}" from "{}"'.format( - name, module_path)) + log.warning('[{}] [UNLOAD] Ignoring non-existent function "{}" from "{}"'.format( + self.session_name, name, module_path)) if count > 0: - log.warning('Successfully loaded {} plugin{} from "{}"'.format(count, "s" if count > 1 else "", root)) + log.warning('[{}] Successfully loaded {} plugin{} from "{}"'.format( + self.session_name, count, "s" if count > 1 else "", root)) else: - log.warning('No plugin loaded from "{}"'.format(root)) + log.warning('[{}] No plugin loaded from "{}"'.format( + self.session_name, root)) def save_session(self): auth_key = base64.b64encode(self.auth_key).decode() From bd9bb83df5eee03a3708bfbeaa6a56188c6256c3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 7 May 2019 18:26:27 +0200 Subject: [PATCH 033/202] Reword some methods' docstring --- pyrogram/client/client.py | 98 +++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 8d706084..610a0d0c 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -261,8 +261,7 @@ class Client(Methods, BaseClient): self._proxy.update(value) def start(self): - """Use this method to start the Client after creating it. - Requires no parameters. + """Use this method to start the Client. Raises: :class:`RPCError ` in case of a Telegram RPC error. @@ -355,8 +354,7 @@ class Client(Methods, BaseClient): return self def stop(self): - """Use this method to manually stop the Client. - Requires no parameters. + """Use this method to stop the Client. Raises: ``ConnectionError`` in case you try to stop an already stopped Client. @@ -399,7 +397,6 @@ class Client(Methods, BaseClient): def restart(self): """Use this method to restart the Client. - Requires no parameters. Raises: ``ConnectionError`` in case you try to restart a stopped Client. @@ -408,8 +405,16 @@ class Client(Methods, BaseClient): self.start() def idle(self, stop_signals: tuple = (SIGINT, SIGTERM, SIGABRT)): - """Blocks the program execution until one of the signals are received, - then gently stop the Client by closing the underlying connection. + """Use this method to block the main script execution until a signal (e.g.: from CTRL+C) is received. + Once the signal is received, the client will automatically stop and the main script will continue its execution. + + This is used after starting one or more clients and is useful for event-driven applications only, that are, + applications which react upon incoming Telegram updates through handlers, rather than executing a set of methods + sequentially. + + The way Pyrogram works, will keep your handlers in a pool of workers, which are executed concurrently outside + the main script; calling idle() will ensure the client(s) will be kept alive by not letting the main script to + end, until you decide to quit. Args: stop_signals (``tuple``, *optional*): @@ -417,6 +422,8 @@ class Client(Methods, BaseClient): Defaults to (SIGINT, SIGTERM, SIGABRT). """ + # TODO: Maybe make this method static and don't automatically stop + def signal_handler(*args): self.is_idle = False @@ -431,8 +438,11 @@ class Client(Methods, BaseClient): self.stop() def run(self): - """Use this method to automatically start and idle a Client. - Requires no parameters. + """Use this method as a convenience shortcut to automatically start the Client and idle the main script. + + This is a convenience method that literally just calls :meth:`start` and :meth:`idle`. It makes running a client + less verbose, but is not suitable in case you want to run more than one client in a single main script, + since :meth:`idle` will block. Raises: :class:`RPCError ` in case of a Telegram RPC error. @@ -465,7 +475,7 @@ class Client(Methods, BaseClient): return handler, group def remove_handler(self, handler: Handler, group: int = 0): - """Removes a previously-added update handler. + """Use this method to remove a previously-registered update handler. Make sure to provide the right group that the handler was added in. You can use the return value of the :meth:`add_handler` method, a tuple of (handler, group), and @@ -752,9 +762,16 @@ class Client(Methods, BaseClient): print("Logged in successfully as {}".format(r.user.first_name)) - def fetch_peers(self, entities: List[Union[types.User, - types.Chat, types.ChatForbidden, - types.Channel, types.ChannelForbidden]]): + def fetch_peers( + self, + entities: List[ + Union[ + types.User, + types.Chat, types.ChatForbidden, + types.Channel, types.ChannelForbidden + ] + ] + ): for entity in entities: if isinstance(entity, types.User): user_id = entity.id @@ -1018,16 +1035,19 @@ class Client(Methods, BaseClient): log.debug("{} stopped".format(name)) - def send(self, - data: Object, - retries: int = Session.MAX_RETRIES, - timeout: float = Session.WAIT_TIMEOUT): - """Use this method to send Raw Function queries. + def send(self, data: Object, retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT): + """Use this method to send raw Telegram queries. - This method makes possible to manually call every single Telegram API method in a low-level manner. + This method makes it possible to manually call every single Telegram API method in a low-level manner. Available functions are listed in the :obj:`functions ` package and may accept compound data types from :obj:`types ` as well as bare types such as ``int``, ``str``, etc... + .. note:: + + This is a utility method intended to be used **only** when working with raw + :obj:`functions ` (i.e: a Telegram API method you wish to use which is not + available yet in the Client class as an easy-to-use method). + Args: data (``Object``): The API Schema function filled with proper arguments. @@ -1285,8 +1305,7 @@ class Client(Methods, BaseClient): indent=4 ) - def get_initial_dialogs_chunk(self, - offset_date: int = 0): + def get_initial_dialogs_chunk(self, offset_date: int = 0): while True: try: r = self.send( @@ -1318,13 +1337,15 @@ class Client(Methods, BaseClient): self.get_initial_dialogs_chunk() - def resolve_peer(self, - peer_id: Union[int, str]): - """Use this method to get the InputPeer of a known peer_id. + def resolve_peer(self, peer_id: Union[int, str]): + """Use this method to get the InputPeer of a known peer id. + Useful whenever an InputPeer type is required. - This is a utility method intended to be used **only** when working with Raw Functions (i.e: a Telegram API - method you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an - InputPeer type is required. + .. note:: + + This is a utility method intended to be used **only** when working with raw + :obj:`functions ` (i.e: a Telegram API method you wish to use which is not + available yet in the Client class as an easy-to-use method). Args: peer_id (``int`` | ``str``): @@ -1391,17 +1412,22 @@ class Client(Methods, BaseClient): except KeyError: raise PeerIdInvalid - def save_file(self, - path: str, - file_id: int = None, - file_part: int = 0, - progress: callable = None, - progress_args: tuple = ()): + def save_file( + self, + path: str, + file_id: int = None, + file_part: int = 0, + progress: callable = None, + progress_args: tuple = () + ): """Use this method to upload a file onto Telegram servers, without actually sending the message to anyone. + Useful whenever an InputFile type is required. - This is a utility method intended to be used **only** when working with Raw Functions (i.e: a Telegram API - method you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an - InputFile type is required. + .. note:: + + This is a utility method intended to be used **only** when working with raw + :obj:`functions ` (i.e: a Telegram API method you wish to use which is not + available yet in the Client class as an easy-to-use method). Args: path (``str``): From 692befe038e924354aad74a0706b8e0890e7ce3d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 8 May 2019 15:40:36 +0200 Subject: [PATCH 034/202] Allow getting more than one reply via get_messages and replies param Just for fun (and for consistency with the code logic, since this part is implemented recursively), not really useful and might lead to frequent flood waits --- pyrogram/client/types/messages_and_media/messages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py index da1a2676..4f78277c 100644 --- a/pyrogram/client/types/messages_and_media/messages.py +++ b/pyrogram/client/types/messages_and_media/messages.py @@ -75,7 +75,7 @@ class Messages(PyrogramType, Update): reply_messages = client.get_messages( parsed_messages[0].chat.id, reply_to_message_ids=reply_message_ids, - replies=0 + replies=replies - 1 ).messages for message in parsed_messages: From 920f8ff911d47a8d1a403305bdc4d97892927e34 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 8 May 2019 16:01:03 +0200 Subject: [PATCH 035/202] Allow unlimited replies to be fetched with get_messages --- pyrogram/client/methods/messages/get_messages.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/methods/messages/get_messages.py b/pyrogram/client/methods/messages/get_messages.py index c018a9eb..f03cac93 100644 --- a/pyrogram/client/methods/messages/get_messages.py +++ b/pyrogram/client/methods/messages/get_messages.py @@ -55,7 +55,9 @@ class GetMessages(BaseClient): If *message_ids* is set, this argument will be ignored. replies (``int``, *optional*): - The number of subsequent replies to get for each message. Defaults to 1. + The number of subsequent replies to get for each message. + Pass 0 for no reply at all or -1 for unlimited replies. + Defaults to 1. Returns: On success and in case *message_ids* or *reply_to_message_ids* was an iterable, the returned value will be a @@ -80,6 +82,9 @@ class GetMessages(BaseClient): ids = list(ids) if is_iterable else [ids] ids = [ids_type(id=i) for i in ids] + if replies < 0: + replies = (1 << 31) - 1 + if isinstance(peer, types.InputPeerChannel): rpc = functions.channels.GetMessages(channel=peer, id=ids) else: From ee91e6daa1e051cc6fd6cf9e676e19465fd39f46 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 8 May 2019 19:52:21 +0200 Subject: [PATCH 036/202] Rename bots folder to keyboards --- pyrogram/client/filters/filters.py | 2 +- pyrogram/client/types/__init__.py | 2 +- pyrogram/client/types/{bots => keyboards}/__init__.py | 0 pyrogram/client/types/{bots => keyboards}/callback_game.py | 0 pyrogram/client/types/{bots => keyboards}/callback_query.py | 0 pyrogram/client/types/{bots => keyboards}/force_reply.py | 0 pyrogram/client/types/{bots => keyboards}/game_high_score.py | 0 pyrogram/client/types/{bots => keyboards}/game_high_scores.py | 0 .../client/types/{bots => keyboards}/inline_keyboard_button.py | 0 .../client/types/{bots => keyboards}/inline_keyboard_markup.py | 0 pyrogram/client/types/{bots => keyboards}/keyboard_button.py | 0 .../client/types/{bots => keyboards}/reply_keyboard_markup.py | 0 .../client/types/{bots => keyboards}/reply_keyboard_remove.py | 0 13 files changed, 2 insertions(+), 2 deletions(-) rename pyrogram/client/types/{bots => keyboards}/__init__.py (100%) rename pyrogram/client/types/{bots => keyboards}/callback_game.py (100%) rename pyrogram/client/types/{bots => keyboards}/callback_query.py (100%) rename pyrogram/client/types/{bots => keyboards}/force_reply.py (100%) rename pyrogram/client/types/{bots => keyboards}/game_high_score.py (100%) rename pyrogram/client/types/{bots => keyboards}/game_high_scores.py (100%) rename pyrogram/client/types/{bots => keyboards}/inline_keyboard_button.py (100%) rename pyrogram/client/types/{bots => keyboards}/inline_keyboard_markup.py (100%) rename pyrogram/client/types/{bots => keyboards}/keyboard_button.py (100%) rename pyrogram/client/types/{bots => keyboards}/reply_keyboard_markup.py (100%) rename pyrogram/client/types/{bots => keyboards}/reply_keyboard_remove.py (100%) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 4c6f0ce3..8f5b9164 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -19,7 +19,7 @@ import re from .filter import Filter -from ..types.bots import InlineKeyboardMarkup, ReplyKeyboardMarkup +from ..types.keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup def create(name: str, func: callable, **kwargs) -> type: diff --git a/pyrogram/client/types/__init__.py b/pyrogram/client/types/__init__.py index 120c7ff5..3d430c44 100644 --- a/pyrogram/client/types/__init__.py +++ b/pyrogram/client/types/__init__.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .bots import * +from .keyboards import * from .inline_mode import * from .input_media import * from .input_message_content import * diff --git a/pyrogram/client/types/bots/__init__.py b/pyrogram/client/types/keyboards/__init__.py similarity index 100% rename from pyrogram/client/types/bots/__init__.py rename to pyrogram/client/types/keyboards/__init__.py diff --git a/pyrogram/client/types/bots/callback_game.py b/pyrogram/client/types/keyboards/callback_game.py similarity index 100% rename from pyrogram/client/types/bots/callback_game.py rename to pyrogram/client/types/keyboards/callback_game.py diff --git a/pyrogram/client/types/bots/callback_query.py b/pyrogram/client/types/keyboards/callback_query.py similarity index 100% rename from pyrogram/client/types/bots/callback_query.py rename to pyrogram/client/types/keyboards/callback_query.py diff --git a/pyrogram/client/types/bots/force_reply.py b/pyrogram/client/types/keyboards/force_reply.py similarity index 100% rename from pyrogram/client/types/bots/force_reply.py rename to pyrogram/client/types/keyboards/force_reply.py diff --git a/pyrogram/client/types/bots/game_high_score.py b/pyrogram/client/types/keyboards/game_high_score.py similarity index 100% rename from pyrogram/client/types/bots/game_high_score.py rename to pyrogram/client/types/keyboards/game_high_score.py diff --git a/pyrogram/client/types/bots/game_high_scores.py b/pyrogram/client/types/keyboards/game_high_scores.py similarity index 100% rename from pyrogram/client/types/bots/game_high_scores.py rename to pyrogram/client/types/keyboards/game_high_scores.py diff --git a/pyrogram/client/types/bots/inline_keyboard_button.py b/pyrogram/client/types/keyboards/inline_keyboard_button.py similarity index 100% rename from pyrogram/client/types/bots/inline_keyboard_button.py rename to pyrogram/client/types/keyboards/inline_keyboard_button.py diff --git a/pyrogram/client/types/bots/inline_keyboard_markup.py b/pyrogram/client/types/keyboards/inline_keyboard_markup.py similarity index 100% rename from pyrogram/client/types/bots/inline_keyboard_markup.py rename to pyrogram/client/types/keyboards/inline_keyboard_markup.py diff --git a/pyrogram/client/types/bots/keyboard_button.py b/pyrogram/client/types/keyboards/keyboard_button.py similarity index 100% rename from pyrogram/client/types/bots/keyboard_button.py rename to pyrogram/client/types/keyboards/keyboard_button.py diff --git a/pyrogram/client/types/bots/reply_keyboard_markup.py b/pyrogram/client/types/keyboards/reply_keyboard_markup.py similarity index 100% rename from pyrogram/client/types/bots/reply_keyboard_markup.py rename to pyrogram/client/types/keyboards/reply_keyboard_markup.py diff --git a/pyrogram/client/types/bots/reply_keyboard_remove.py b/pyrogram/client/types/keyboards/reply_keyboard_remove.py similarity index 100% rename from pyrogram/client/types/bots/reply_keyboard_remove.py rename to pyrogram/client/types/keyboards/reply_keyboard_remove.py From 1737ba5f49b1c53945edb82c5b8f0624e03a7a87 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 9 May 2019 04:28:46 +0200 Subject: [PATCH 037/202] Revamp docs about the main Pyrogram package --- compiler/api/compiler.py | 5 +- docs/source/conf.py | 4 +- docs/source/pyrogram/Client.rst | 162 --------- docs/source/pyrogram/Decorators.rst | 47 +++ docs/source/pyrogram/Errors.rst | 28 ++ docs/source/pyrogram/Handlers.rst | 37 +- docs/source/pyrogram/Methods.rst | 270 +++++++++++++++ docs/source/pyrogram/ParseMode.rst | 6 - docs/source/pyrogram/RPCError.rst | 15 - docs/source/pyrogram/Types.rst | 127 +++---- docs/source/pyrogram/index.rst | 11 +- pyrogram/client/client.py | 45 +-- pyrogram/client/filters/filters.py | 48 +-- .../client/handlers/callback_query_handler.py | 6 +- .../handlers/deleted_messages_handler.py | 8 +- .../client/handlers/disconnect_handler.py | 4 +- .../client/handlers/inline_query_handler.py | 8 +- pyrogram/client/handlers/message_handler.py | 8 +- pyrogram/client/handlers/poll_handler.py | 2 +- .../client/handlers/raw_update_handler.py | 4 +- .../client/handlers/user_status_handler.py | 8 +- .../methods/bots/answer_callback_query.py | 6 +- .../methods/bots/answer_inline_query.py | 7 +- .../methods/bots/get_game_high_scores.py | 8 +- .../methods/bots/get_inline_bot_results.py | 8 +- .../methods/bots/request_callback_answer.py | 6 +- pyrogram/client/methods/bots/send_game.py | 6 +- .../methods/bots/send_inline_bot_result.py | 4 +- .../client/methods/bots/set_game_score.py | 7 +- .../client/methods/chats/delete_chat_photo.py | 6 +- .../methods/chats/export_chat_invite_link.py | 6 +- pyrogram/client/methods/chats/get_chat.py | 8 +- .../client/methods/chats/get_chat_member.py | 6 +- .../client/methods/chats/get_chat_members.py | 8 +- .../methods/chats/get_chat_members_count.py | 6 +- .../client/methods/chats/get_chat_preview.py | 10 +- pyrogram/client/methods/chats/get_dialogs.py | 6 +- .../client/methods/chats/get_dialogs_count.py | 4 +- .../client/methods/chats/iter_chat_members.py | 6 +- pyrogram/client/methods/chats/iter_dialogs.py | 6 +- pyrogram/client/methods/chats/join_chat.py | 6 +- .../client/methods/chats/kick_chat_member.py | 8 +- pyrogram/client/methods/chats/leave_chat.py | 4 +- .../client/methods/chats/pin_chat_message.py | 6 +- .../methods/chats/promote_chat_member.py | 6 +- .../client/methods/chats/restrict_chat.py | 6 +- .../methods/chats/restrict_chat_member.py | 6 +- .../methods/chats/set_chat_description.py | 6 +- .../client/methods/chats/set_chat_photo.py | 6 +- .../client/methods/chats/set_chat_title.py | 8 +- .../client/methods/chats/unban_chat_member.py | 6 +- .../methods/chats/unpin_chat_message.py | 6 +- .../methods/chats/update_chat_username.py | 8 +- .../client/methods/contacts/add_contacts.py | 9 +- .../methods/contacts/delete_contacts.py | 6 +- .../client/methods/contacts/get_contacts.py | 7 +- .../methods/contacts/get_contacts_count.py | 4 +- .../methods/decorators/on_callback_query.py | 4 +- .../methods/decorators/on_deleted_messages.py | 4 +- .../methods/decorators/on_inline_query.py | 2 +- .../client/methods/decorators/on_message.py | 4 +- pyrogram/client/methods/decorators/on_poll.py | 2 +- .../methods/decorators/on_raw_update.py | 2 +- .../methods/decorators/on_user_status.py | 4 +- .../methods/messages/delete_messages.py | 6 +- .../client/methods/messages/download_media.py | 13 +- .../methods/messages/edit_message_caption.py | 11 +- .../methods/messages/edit_message_media.py | 6 +- .../messages/edit_message_reply_markup.py | 9 +- .../methods/messages/edit_message_text.py | 11 +- .../methods/messages/forward_messages.py | 13 +- .../client/methods/messages/get_history.py | 6 +- .../methods/messages/get_history_count.py | 6 +- .../client/methods/messages/get_messages.py | 12 +- .../client/methods/messages/iter_history.py | 6 +- .../client/methods/messages/retract_vote.py | 6 +- .../client/methods/messages/send_animation.py | 16 +- .../client/methods/messages/send_audio.py | 16 +- .../methods/messages/send_cached_media.py | 11 +- .../methods/messages/send_chat_action.py | 12 +- .../client/methods/messages/send_contact.py | 6 +- .../client/methods/messages/send_document.py | 16 +- .../client/methods/messages/send_location.py | 6 +- .../methods/messages/send_media_group.py | 7 +- .../client/methods/messages/send_message.py | 11 +- .../client/methods/messages/send_photo.py | 16 +- pyrogram/client/methods/messages/send_poll.py | 6 +- .../client/methods/messages/send_sticker.py | 11 +- .../client/methods/messages/send_venue.py | 6 +- .../client/methods/messages/send_video.py | 16 +- .../methods/messages/send_video_note.py | 11 +- .../client/methods/messages/send_voice.py | 16 +- pyrogram/client/methods/messages/stop_poll.py | 6 +- pyrogram/client/methods/messages/vote_poll.py | 6 +- .../methods/password/change_cloud_password.py | 8 +- .../methods/password/enable_cloud_password.py | 8 +- .../methods/password/remove_cloud_password.py | 8 +- .../users/delete_user_profile_photos.py | 8 +- pyrogram/client/methods/users/get_me.py | 4 +- .../methods/users/get_user_profile_photos.py | 6 +- .../users/get_user_profile_photos_count.py | 6 +- pyrogram/client/methods/users/get_users.py | 10 +- .../methods/users/set_user_profile_photo.py | 6 +- .../client/methods/users/update_username.py | 8 +- .../client/types/inline_mode/inline_query.py | 8 +- .../inline_query_result_article.py | 2 +- .../todo/inline_query_result_audio.py | 2 +- .../todo/inline_query_result_cached_audio.py | 2 +- .../inline_query_result_cached_document.py | 2 +- .../todo/inline_query_result_cached_gif.py | 2 +- .../inline_query_result_cached_mpeg4_gif.py | 4 +- .../todo/inline_query_result_cached_photo.py | 2 +- .../inline_query_result_cached_sticker.py | 2 +- .../todo/inline_query_result_cached_video.py | 2 +- .../todo/inline_query_result_cached_voice.py | 2 +- .../todo/inline_query_result_contact.py | 2 +- .../todo/inline_query_result_document.py | 2 +- .../todo/inline_query_result_game.py | 2 +- .../todo/inline_query_result_gif.py | 2 +- .../todo/inline_query_result_location.py | 2 +- .../todo/inline_query_result_mpeg4_gif.py | 2 +- .../todo/inline_query_result_photo.py | 2 +- .../todo/inline_query_result_venue.py | 2 +- .../todo/inline_query_result_video.py | 2 +- .../todo/inline_query_result_voice.py | 2 +- .../client/types/input_media/input_media.py | 10 +- .../input_media/input_media_animation.py | 7 +- .../types/input_media/input_media_audio.py | 7 +- .../types/input_media/input_media_document.py | 7 +- .../types/input_media/input_media_photo.py | 7 +- .../types/input_media/input_media_video.py | 7 +- .../types/input_media/input_phone_contact.py | 2 +- .../input_text_message_content.py | 7 +- .../client/types/keyboards/callback_query.py | 10 +- .../client/types/keyboards/force_reply.py | 2 +- .../client/types/keyboards/game_high_score.py | 2 +- .../types/keyboards/game_high_scores.py | 4 +- .../types/keyboards/inline_keyboard_button.py | 2 +- .../types/keyboards/inline_keyboard_markup.py | 4 +- .../client/types/keyboards/keyboard_button.py | 2 +- .../types/keyboards/reply_keyboard_markup.py | 4 +- .../types/keyboards/reply_keyboard_remove.py | 2 +- .../types/messages_and_media/animation.py | 2 +- .../client/types/messages_and_media/audio.py | 4 +- .../types/messages_and_media/contact.py | 2 +- .../types/messages_and_media/document.py | 4 +- .../client/types/messages_and_media/game.py | 6 +- .../types/messages_and_media/location.py | 2 +- .../types/messages_and_media/message.py | 316 +++++++++--------- .../messages_and_media/message_entity.py | 4 +- .../types/messages_and_media/messages.py | 12 +- .../client/types/messages_and_media/photo.py | 4 +- .../types/messages_and_media/photo_size.py | 2 +- .../client/types/messages_and_media/poll.py | 2 +- .../types/messages_and_media/poll_option.py | 2 +- .../types/messages_and_media/sticker.py | 4 +- .../messages_and_media/user_profile_photos.py | 4 +- .../client/types/messages_and_media/venue.py | 4 +- .../client/types/messages_and_media/video.py | 4 +- .../types/messages_and_media/video_note.py | 4 +- .../client/types/messages_and_media/voice.py | 2 +- pyrogram/client/types/user_and_chats/chat.py | 4 +- .../types/user_and_chats/chat_member.py | 12 +- .../types/user_and_chats/chat_members.py | 2 +- .../types/user_and_chats/chat_permissions.py | 2 +- .../client/types/user_and_chats/chat_photo.py | 2 +- .../types/user_and_chats/chat_preview.py | 2 +- .../client/types/user_and_chats/dialog.py | 4 +- .../client/types/user_and_chats/dialogs.py | 4 +- pyrogram/client/types/user_and_chats/user.py | 2 +- .../types/user_and_chats/user_status.py | 2 +- 171 files changed, 1116 insertions(+), 919 deletions(-) delete mode 100644 docs/source/pyrogram/Client.rst create mode 100644 docs/source/pyrogram/Decorators.rst create mode 100644 docs/source/pyrogram/Errors.rst create mode 100644 docs/source/pyrogram/Methods.rst delete mode 100644 docs/source/pyrogram/ParseMode.rst delete mode 100644 docs/source/pyrogram/RPCError.rst diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 6be16ba5..992548fd 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -328,15 +328,16 @@ def start(): ) if docstring_args: - docstring_args = "Args:\n " + "\n ".join(docstring_args) + docstring_args = "Parameters:\n " + "\n ".join(docstring_args) else: docstring_args = "No parameters required." docstring_args = "Attributes:\n ID: ``{}``\n\n ".format(c.id) + docstring_args if c.section == "functions": - docstring_args += "\n\n Raises:\n :obj:`RPCError `" docstring_args += "\n\n Returns:\n " + get_docstring_arg_type(c.return_type) + docstring_args += "\n\n Raises:\n RPCError: In case of a Telegram RPC error." + else: references = get_references(".".join(filter(None, [c.namespace, c.name]))) diff --git a/docs/source/conf.py b/docs/source/conf.py index 8acfde42..e08298ef 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -44,6 +44,8 @@ extensions = [ 'sphinx.ext.autosummary' ] +napoleon_use_rtype = False + # Don't show source files on docs html_show_sourcelink = True @@ -112,7 +114,7 @@ html_theme = 'sphinx_rtd_theme' # html_theme_options = { 'canonical_url': "https://docs.pyrogram.ml/", - 'collapse_navigation': False, + 'collapse_navigation': True, 'sticky_navigation': False, 'logo_only': True, 'display_version': True diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst deleted file mode 100644 index 5adf4956..00000000 --- a/docs/source/pyrogram/Client.rst +++ /dev/null @@ -1,162 +0,0 @@ -Client -====== - -.. currentmodule:: pyrogram.Client - -.. autoclass:: pyrogram.Client - -Utilities ---------- - -.. autosummary:: - :nosignatures: - - start - stop - restart - idle - run - add_handler - remove_handler - send - resolve_peer - save_file - stop_transmission - -Decorators ----------- - -.. autosummary:: - :nosignatures: - - on_message - on_callback_query - on_inline_query - on_deleted_messages - on_user_status - on_disconnect - on_raw_update - -Messages --------- - -.. autosummary:: - :nosignatures: - - send_message - forward_messages - send_photo - send_audio - send_document - send_sticker - send_video - send_animation - send_voice - send_video_note - send_media_group - send_location - send_venue - send_contact - send_cached_media - send_chat_action - edit_message_text - edit_message_caption - edit_message_reply_markup - edit_message_media - delete_messages - get_messages - get_history - get_history_count - iter_history - send_poll - vote_poll - stop_poll - retract_vote - download_media - -Chats ------ - -.. autosummary:: - :nosignatures: - - join_chat - leave_chat - kick_chat_member - unban_chat_member - restrict_chat_member - promote_chat_member - export_chat_invite_link - set_chat_photo - delete_chat_photo - set_chat_title - set_chat_description - pin_chat_message - unpin_chat_message - get_chat - get_chat_preview - get_chat_member - get_chat_members - get_chat_members_count - iter_chat_members - get_dialogs - iter_dialogs - get_dialogs_count - restrict_chat - update_chat_username - -Users ------ - -.. autosummary:: - :nosignatures: - - get_me - get_users - get_user_profile_photos - get_user_profile_photos_count - set_user_profile_photo - delete_user_profile_photos - update_username - -Contacts --------- - -.. autosummary:: - :nosignatures: - - add_contacts - get_contacts - get_contacts_count - delete_contacts - -Password --------- - -.. autosummary:: - :nosignatures: - - enable_cloud_password - change_cloud_password - remove_cloud_password - -Bots ----- - -.. autosummary:: - :nosignatures: - - get_inline_bot_results - send_inline_bot_result - answer_callback_query - answer_inline_query - request_callback_answer - send_game - set_game_score - get_game_high_scores - answer_inline_query - - -.. autoclass:: pyrogram.Client - :inherited-members: - :members: diff --git a/docs/source/pyrogram/Decorators.rst b/docs/source/pyrogram/Decorators.rst new file mode 100644 index 00000000..a9cd70c7 --- /dev/null +++ b/docs/source/pyrogram/Decorators.rst @@ -0,0 +1,47 @@ +Decorators +========== + +While still being methods bound to the :obj:`Client` class, decorators are of a special kind and thus deserve a +dedicated page. + +Decorators are able to register callback functions for handling updates in a much easier and cleaner way compared to +`Handlers `_; they do so by instantiating the correct handler and calling +:meth:`add_handler() `, automatically. All you need to do is adding the decorators on top +of your functions. + +**Example:** + +.. code-block:: python + + from pyrogram import Client + + app = Client(...) + + + @app.on_message() + def log(client, message): + print(message) + + + app.run() + +.. currentmodule:: pyrogram.Client + +.. autosummary:: + :nosignatures: + + on_message + on_callback_query + on_inline_query + on_deleted_messages + on_user_status + on_disconnect + on_raw_update + +.. automethod:: pyrogram.Client.on_message() +.. automethod:: pyrogram.Client.on_callback_query() +.. automethod:: pyrogram.Client.on_inline_query() +.. automethod:: pyrogram.Client.on_deleted_messages() +.. automethod:: pyrogram.Client.on_user_status() +.. automethod:: pyrogram.Client.on_disconnect() +.. automethod:: pyrogram.Client.on_raw_update() \ No newline at end of file diff --git a/docs/source/pyrogram/Errors.rst b/docs/source/pyrogram/Errors.rst new file mode 100644 index 00000000..6c816a72 --- /dev/null +++ b/docs/source/pyrogram/Errors.rst @@ -0,0 +1,28 @@ +Errors +====== + +All the Pyrogram errors listed here live inside the ``errors`` sub-package. + +**Example:** + +.. code-block:: python + + from pyrogram.errors import RPCError + + try: + ... + except RPCError: + ... + +.. autoexception:: pyrogram.RPCError() + :members: + +.. toctree:: + ../errors/SeeOther + ../errors/BadRequest + ../errors/Unauthorized + ../errors/Forbidden + ../errors/NotAcceptable + ../errors/Flood + ../errors/InternalServerError + ../errors/UnknownError diff --git a/docs/source/pyrogram/Handlers.rst b/docs/source/pyrogram/Handlers.rst index 1bb16ece..7140897b 100644 --- a/docs/source/pyrogram/Handlers.rst +++ b/docs/source/pyrogram/Handlers.rst @@ -1,6 +1,29 @@ Handlers ======== +Handlers are used to instruct Pyrogram about which kind of updates you'd like to handle with your callback functions. + +For a much more convenient way of registering callback functions have a look at `Decorators `_ instead. +In case you decided to manually create an handler, use :meth:`add_handler() ` to register +it. + +**Example:** + +.. code-block:: python + + from pyrogram import Client, MessageHandler + + app = Client(...) + + + def dump(client, message): + print(message) + + + app.add_handler(MessageHandler(dump)) + + app.run() + .. currentmodule:: pyrogram .. autosummary:: @@ -14,24 +37,24 @@ Handlers DisconnectHandler RawUpdateHandler -.. autoclass:: MessageHandler +.. autoclass:: MessageHandler() :members: -.. autoclass:: DeletedMessagesHandler +.. autoclass:: DeletedMessagesHandler() :members: -.. autoclass:: CallbackQueryHandler +.. autoclass:: CallbackQueryHandler() :members: -.. autoclass:: InlineQueryHandler +.. autoclass:: InlineQueryHandler() :members: -.. autoclass:: UserStatusHandler +.. autoclass:: UserStatusHandler() :members: -.. autoclass:: DisconnectHandler +.. autoclass:: DisconnectHandler() :members: -.. autoclass:: RawUpdateHandler +.. autoclass:: RawUpdateHandler() :members: diff --git a/docs/source/pyrogram/Methods.rst b/docs/source/pyrogram/Methods.rst new file mode 100644 index 00000000..d0387790 --- /dev/null +++ b/docs/source/pyrogram/Methods.rst @@ -0,0 +1,270 @@ +Methods +======= + +All Pyrogram methods listed here are bound to a :obj:`Client ` instance. + +**Example:** + +.. code-block:: python + + from pyrogram import Client + + app = Client(...) + + with app: + app.send_message("haskell", "hi") + +.. currentmodule:: pyrogram.Client + +Utilities +--------- + +.. autosummary:: + :nosignatures: + + start + stop + restart + idle + run + add_handler + remove_handler + send + resolve_peer + save_file + stop_transmission + +Messages +-------- + +.. autosummary:: + :nosignatures: + + send_message + forward_messages + send_photo + send_audio + send_document + send_sticker + send_video + send_animation + send_voice + send_video_note + send_media_group + send_location + send_venue + send_contact + send_cached_media + send_chat_action + edit_message_text + edit_message_caption + edit_message_reply_markup + edit_message_media + delete_messages + get_messages + get_history + get_history_count + iter_history + send_poll + vote_poll + stop_poll + retract_vote + download_media + +Chats +----- + +.. autosummary:: + :nosignatures: + + join_chat + leave_chat + kick_chat_member + unban_chat_member + restrict_chat_member + promote_chat_member + export_chat_invite_link + set_chat_photo + delete_chat_photo + set_chat_title + set_chat_description + pin_chat_message + unpin_chat_message + get_chat + get_chat_preview + get_chat_member + get_chat_members + get_chat_members_count + iter_chat_members + get_dialogs + iter_dialogs + get_dialogs_count + restrict_chat + update_chat_username + +Users +----- + +.. autosummary:: + :nosignatures: + + get_me + get_users + get_user_profile_photos + get_user_profile_photos_count + set_user_profile_photo + delete_user_profile_photos + update_username + +Contacts +-------- + +.. autosummary:: + :nosignatures: + + add_contacts + get_contacts + get_contacts_count + delete_contacts + +Password +-------- + +.. autosummary:: + :nosignatures: + + enable_cloud_password + change_cloud_password + remove_cloud_password + +Bots +---- + +.. autosummary:: + :nosignatures: + + get_inline_bot_results + send_inline_bot_result + answer_callback_query + answer_inline_query + request_callback_answer + send_game + set_game_score + get_game_high_scores + answer_inline_query + +.. Utilities + --------- + +.. automethod:: pyrogram.Client.start() +.. automethod:: pyrogram.Client.stop() +.. automethod:: pyrogram.Client.restart() +.. automethod:: pyrogram.Client.idle() +.. automethod:: pyrogram.Client.run() +.. automethod:: pyrogram.Client.add_handler() +.. automethod:: pyrogram.Client.remove_handler() +.. automethod:: pyrogram.Client.send() +.. automethod:: pyrogram.Client.resolve_peer() +.. automethod:: pyrogram.Client.save_file() +.. automethod:: pyrogram.Client.stop_transmission() + +.. Messages + -------- + +.. automethod:: pyrogram.Client.send_message() +.. automethod:: pyrogram.Client.forward_messages() +.. automethod:: pyrogram.Client.send_photo() +.. automethod:: pyrogram.Client.send_audio() +.. automethod:: pyrogram.Client.send_document() +.. automethod:: pyrogram.Client.send_sticker() +.. automethod:: pyrogram.Client.send_video() +.. automethod:: pyrogram.Client.send_animation() +.. automethod:: pyrogram.Client.send_voice() +.. automethod:: pyrogram.Client.send_video_note() +.. automethod:: pyrogram.Client.send_media_group() +.. automethod:: pyrogram.Client.send_location() +.. automethod:: pyrogram.Client.send_venue() +.. automethod:: pyrogram.Client.send_contact() +.. automethod:: pyrogram.Client.send_cached_media() +.. automethod:: pyrogram.Client.send_chat_action() +.. automethod:: pyrogram.Client.edit_message_text() +.. automethod:: pyrogram.Client.edit_message_caption() +.. automethod:: pyrogram.Client.edit_message_reply_markup() +.. automethod:: pyrogram.Client.edit_message_media() +.. automethod:: pyrogram.Client.delete_messages() +.. automethod:: pyrogram.Client.get_messages() +.. automethod:: pyrogram.Client.get_history() +.. automethod:: pyrogram.Client.get_history_count() +.. automethod:: pyrogram.Client.iter_history() +.. automethod:: pyrogram.Client.send_poll() +.. automethod:: pyrogram.Client.vote_poll() +.. automethod:: pyrogram.Client.stop_poll() +.. automethod:: pyrogram.Client.retract_vote() +.. automethod:: pyrogram.Client.download_media() + +.. Chats + ----- + +.. automethod:: pyrogram.Client.join_chat() +.. automethod:: pyrogram.Client.leave_chat() +.. automethod:: pyrogram.Client.kick_chat_member() +.. automethod:: pyrogram.Client.unban_chat_member() +.. automethod:: pyrogram.Client.restrict_chat_member() +.. automethod:: pyrogram.Client.promote_chat_member() +.. automethod:: pyrogram.Client.export_chat_invite_link() +.. automethod:: pyrogram.Client.set_chat_photo() +.. automethod:: pyrogram.Client.delete_chat_photo() +.. automethod:: pyrogram.Client.set_chat_title() +.. automethod:: pyrogram.Client.set_chat_description() +.. automethod:: pyrogram.Client.pin_chat_message() +.. automethod:: pyrogram.Client.unpin_chat_message() +.. automethod:: pyrogram.Client.get_chat() +.. automethod:: pyrogram.Client.get_chat_preview() +.. automethod:: pyrogram.Client.get_chat_member() +.. automethod:: pyrogram.Client.get_chat_members() +.. automethod:: pyrogram.Client.get_chat_members_count() +.. automethod:: pyrogram.Client.iter_chat_members() +.. automethod:: pyrogram.Client.get_dialogs() +.. automethod:: pyrogram.Client.iter_dialogs() +.. automethod:: pyrogram.Client.get_dialogs_count() +.. automethod:: pyrogram.Client.restrict_chat() +.. automethod:: pyrogram.Client.update_chat_username() + +.. Users + ----- + +.. automethod:: pyrogram.Client.get_me() +.. automethod:: pyrogram.Client.get_users() +.. automethod:: pyrogram.Client.get_user_profile_photos() +.. automethod:: pyrogram.Client.get_user_profile_photos_count() +.. automethod:: pyrogram.Client.set_user_profile_photo() +.. automethod:: pyrogram.Client.delete_user_profile_photos() +.. automethod:: pyrogram.Client.update_username() + +.. Contacts + -------- + +.. automethod:: pyrogram.Client.add_contacts() +.. automethod:: pyrogram.Client.get_contacts() +.. automethod:: pyrogram.Client.get_contacts_count() +.. automethod:: pyrogram.Client.delete_contacts() + +.. Password + -------- + +.. automethod:: pyrogram.Client.enable_cloud_password() +.. automethod:: pyrogram.Client.change_cloud_password() +.. automethod:: pyrogram.Client.remove_cloud_password() + +.. Bots + ---- + +.. automethod:: pyrogram.Client.get_inline_bot_results() +.. automethod:: pyrogram.Client.send_inline_bot_result() +.. automethod:: pyrogram.Client.answer_callback_query() +.. automethod:: pyrogram.Client.answer_inline_query() +.. automethod:: pyrogram.Client.request_callback_answer() +.. automethod:: pyrogram.Client.send_game() +.. automethod:: pyrogram.Client.set_game_score() +.. automethod:: pyrogram.Client.get_game_high_scores() +.. automethod:: pyrogram.Client.answer_inline_query() \ No newline at end of file diff --git a/docs/source/pyrogram/ParseMode.rst b/docs/source/pyrogram/ParseMode.rst deleted file mode 100644 index 6a4e0bbb..00000000 --- a/docs/source/pyrogram/ParseMode.rst +++ /dev/null @@ -1,6 +0,0 @@ -ParseMode -========= - -.. autoclass:: pyrogram.ParseMode - :members: - :undoc-members: diff --git a/docs/source/pyrogram/RPCError.rst b/docs/source/pyrogram/RPCError.rst deleted file mode 100644 index a47c9b9c..00000000 --- a/docs/source/pyrogram/RPCError.rst +++ /dev/null @@ -1,15 +0,0 @@ -RPCError -======== - -.. autoexception:: pyrogram.RPCError - :members: - -.. toctree:: - ../errors/SeeOther - ../errors/BadRequest - ../errors/Unauthorized - ../errors/Forbidden - ../errors/NotAcceptable - ../errors/Flood - ../errors/InternalServerError - ../errors/UnknownError diff --git a/docs/source/pyrogram/Types.rst b/docs/source/pyrogram/Types.rst index 5deb58b2..52e97107 100644 --- a/docs/source/pyrogram/Types.rst +++ b/docs/source/pyrogram/Types.rst @@ -1,6 +1,19 @@ Types ===== +All Pyrogram types listed here are accessible through the main package directly. + +**Example:** + +.. code-block:: python + + from pyrogram import User, Message, ... + +.. note:: + + **Optional** fields may not exist when irrelevant -- i.e.: they will contain the value of ``None`` and aren't shown + when, for example, using ``print()``. + .. currentmodule:: pyrogram Users & Chats @@ -42,11 +55,12 @@ Messages & Media Location Venue Sticker + Game Poll PollOption -Bots ----- +Keyboards +--------- .. autosummary:: :nosignatures: @@ -58,7 +72,8 @@ Bots InlineKeyboardButton ForceReply CallbackQuery - Game + GameHighScore + CallbackGame Input Media ----------- @@ -96,168 +111,168 @@ InputMessageContent .. User & Chats ------------ -.. autoclass:: User +.. autoclass:: User() :members: -.. autoclass:: UserStatus +.. autoclass:: UserStatus() :members: -.. autoclass:: Chat +.. autoclass:: Chat() :members: -.. autoclass:: ChatPreview +.. autoclass:: ChatPreview() :members: -.. autoclass:: ChatPhoto +.. autoclass:: ChatPhoto() :members: -.. autoclass:: ChatMember +.. autoclass:: ChatMember() :members: -.. autoclass:: ChatMembers +.. autoclass:: ChatMembers() :members: -.. autoclass:: ChatPermissions +.. autoclass:: ChatPermissions() :members: -.. autoclass:: Dialog +.. autoclass:: Dialog() :members: -.. autoclass:: Dialogs +.. autoclass:: Dialogs() :members: .. Messages & Media ---------------- -.. autoclass:: Message +.. autoclass:: Message() :members: -.. autoclass:: Messages +.. autoclass:: Messages() :members: -.. autoclass:: MessageEntity +.. autoclass:: MessageEntity() :members: -.. autoclass:: Photo +.. autoclass:: Photo() :members: -.. autoclass:: PhotoSize +.. autoclass:: PhotoSize() :members: -.. autoclass:: UserProfilePhotos +.. autoclass:: UserProfilePhotos() :members: -.. autoclass:: Audio +.. autoclass:: Audio() :members: -.. autoclass:: Document +.. autoclass:: Document() :members: -.. autoclass:: Animation +.. autoclass:: Animation() :members: -.. autoclass:: Video +.. autoclass:: Video() :members: -.. autoclass:: Voice +.. autoclass:: Voice() :members: -.. autoclass:: VideoNote +.. autoclass:: VideoNote() :members: -.. autoclass:: Contact +.. autoclass:: Contact() :members: -.. autoclass:: Location +.. autoclass:: Location() :members: -.. autoclass:: Venue +.. autoclass:: Venue() :members: -.. autoclass:: Sticker +.. autoclass:: Sticker() :members: -.. autoclass:: Poll +.. autoclass:: Game() :members: -.. autoclass:: PollOption +.. autoclass:: Poll() :members: -.. Bots - ---- - -.. autoclass:: ReplyKeyboardMarkup +.. autoclass:: PollOption() :members: -.. autoclass:: KeyboardButton +.. Keyboards + --------- + +.. autoclass:: ReplyKeyboardMarkup() :members: -.. autoclass:: ReplyKeyboardRemove +.. autoclass:: KeyboardButton() :members: -.. autoclass:: InlineKeyboardMarkup +.. autoclass:: ReplyKeyboardRemove() :members: -.. autoclass:: InlineKeyboardButton +.. autoclass:: InlineKeyboardMarkup() :members: -.. autoclass:: ForceReply +.. autoclass:: InlineKeyboardButton() :members: -.. autoclass:: CallbackQuery +.. autoclass:: ForceReply() :members: -.. autoclass:: Game +.. autoclass:: CallbackQuery() :members: -.. autoclass:: GameHighScore +.. autoclass:: GameHighScore() :members: -.. autoclass:: GameHighScores +.. autoclass:: CallbackGame() :members: .. Input Media ----------- -.. autoclass:: InputMedia +.. autoclass:: InputMedia() :members: -.. autoclass:: InputMediaPhoto +.. autoclass:: InputMediaPhoto() :members: -.. autoclass:: InputMediaVideo +.. autoclass:: InputMediaVideo() :members: -.. autoclass:: InputMediaAudio +.. autoclass:: InputMediaAudio() :members: -.. autoclass:: InputMediaAnimation +.. autoclass:: InputMediaAnimation() :members: -.. autoclass:: InputMediaDocument +.. autoclass:: InputMediaDocument() :members: -.. autoclass:: InputPhoneContact +.. autoclass:: InputPhoneContact() :members: .. Inline Mode ----------- -.. autoclass:: InlineQuery +.. autoclass:: InlineQuery() :members: -.. autoclass:: InlineQueryResult +.. autoclass:: InlineQueryResult() :members: -.. autoclass:: InlineQueryResultArticle +.. autoclass:: InlineQueryResultArticle() :members: .. InputMessageContent ------------------- -.. autoclass:: InputMessageContent +.. autoclass:: InputMessageContent() :members: -.. autoclass:: InputTextMessageContent +.. autoclass:: InputTextMessageContent() :members: diff --git a/docs/source/pyrogram/index.rst b/docs/source/pyrogram/index.rst index 286b5db1..84471e89 100644 --- a/docs/source/pyrogram/index.rst +++ b/docs/source/pyrogram/index.rst @@ -4,17 +4,18 @@ Pyrogram In this section you can find a detailed description of the Pyrogram package and its API. :class:`Client ` is the main class. It exposes easy-to-use methods that are named -after the well established `Telegram Bot API`_ methods, thus offering a familiar look to Bot developers. +after the well established Telegram Bot API methods, thus offering a familiar look to Bot developers. .. toctree:: :maxdepth: 1 - Client Types + Methods Handlers + Decorators Filters ChatAction - ParseMode - RPCError + Errors -.. _Telegram Bot API: https://core.telegram.org/bots/api#available-methods + +.. autoclass:: pyrogram.Client() diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 610a0d0c..823faf27 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -64,7 +64,7 @@ class Client(Methods, BaseClient): It exposes bot-like methods for an easy access to the API as well as a simple way to invoke every single Telegram API method available. - Args: + Parameters: session_name (``str``): Name to uniquely identify a session of either a User or a Bot, e.g.: "my_account". This name will be used to save a file to disk that stores details needed for reconnecting without asking again for credentials. @@ -264,8 +264,8 @@ class Client(Methods, BaseClient): """Use this method to start the Client. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ConnectionError`` in case you try to start an already started Client. + RPCError: In case of a Telegram RPC error. + ConnectionError: In case you try to start an already started Client. """ if self.is_started: raise ConnectionError("Client has already been started") @@ -357,7 +357,7 @@ class Client(Methods, BaseClient): """Use this method to stop the Client. Raises: - ``ConnectionError`` in case you try to stop an already stopped Client. + ConnectionError: In case you try to stop an already stopped Client. """ if not self.is_started: raise ConnectionError("Client is already stopped") @@ -399,7 +399,7 @@ class Client(Methods, BaseClient): """Use this method to restart the Client. Raises: - ``ConnectionError`` in case you try to restart a stopped Client. + ConnectionError: In case you try to restart a stopped Client. """ self.stop() self.start() @@ -416,7 +416,7 @@ class Client(Methods, BaseClient): the main script; calling idle() will ensure the client(s) will be kept alive by not letting the main script to end, until you decide to quit. - Args: + Parameters: stop_signals (``tuple``, *optional*): Iterable containing signals the signal handler will listen to. Defaults to (SIGINT, SIGTERM, SIGABRT). @@ -445,7 +445,7 @@ class Client(Methods, BaseClient): since :meth:`idle` will block. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ self.start() self.idle() @@ -457,7 +457,7 @@ class Client(Methods, BaseClient): will be used for a single update. To handle the same update more than once, register your handler using a different group id (lower group id == higher priority). - Args: + Parameters: handler (``Handler``): The handler to be registered. @@ -465,7 +465,7 @@ class Client(Methods, BaseClient): The group identifier, defaults to 0. Returns: - A tuple of (handler, group) + ``tuple``: A tuple consisting of (handler, group). """ if isinstance(handler, DisconnectHandler): self.disconnect_handler = handler.callback @@ -481,7 +481,7 @@ class Client(Methods, BaseClient): the return value of the :meth:`add_handler` method, a tuple of (handler, group), and pass it directly. - Args: + Parameters: handler (``Handler``): The handler to be removed. @@ -1048,8 +1048,8 @@ class Client(Methods, BaseClient): :obj:`functions ` (i.e: a Telegram API method you wish to use which is not available yet in the Client class as an easy-to-use method). - Args: - data (``Object``): + Parameters: + data (``RawFunction``): The API Schema function filled with proper arguments. retries (``int``): @@ -1058,8 +1058,11 @@ class Client(Methods, BaseClient): timeout (``float``): Timeout in seconds. + Returns: + ``RawType``: The raw type response generated by the query. + Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if not self.is_started: raise ConnectionError("Client has not been started") @@ -1347,17 +1350,17 @@ class Client(Methods, BaseClient): :obj:`functions ` (i.e: a Telegram API method you wish to use which is not available yet in the Client class as an easy-to-use method). - Args: + Parameters: peer_id (``int`` | ``str``): The peer id you want to extract the InputPeer from. Can be a direct id (int), a username (str) or a phone number (str). Returns: - On success, the resolved peer id is returned in form of an InputPeer object. + ``InputPeer``: On success, the resolved peer id is returned in form of an InputPeer object. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``KeyError`` in case the peer doesn't exist in the internal database. + RPCError: In case of a Telegram RPC error. + KeyError: In case the peer doesn't exist in the internal database. """ try: return self.peers_by_id[peer_id] @@ -1429,7 +1432,7 @@ class Client(Methods, BaseClient): :obj:`functions ` (i.e: a Telegram API method you wish to use which is not available yet in the Client class as an easy-to-use method). - Args: + Parameters: path (``str``): The path of the file you want to upload that exists on your local machine. @@ -1449,7 +1452,7 @@ class Client(Methods, BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -1463,10 +1466,10 @@ class Client(Methods, BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the uploaded file is returned in form of an InputFile object. + ``InputFile``: On success, the uploaded file is returned in form of an InputFile object. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ part_size = 512 * 1024 file_size = os.path.getsize(path) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 8f5b9164..5070bd52 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -27,7 +27,7 @@ def create(name: str, func: callable, **kwargs) -> type: Custom filters give you extra control over which updates are allowed or not to be processed by your handlers. - Args: + Parameters: name (``str``): Your filter's name. Can be anything you like. @@ -35,9 +35,9 @@ def create(name: str, func: callable, **kwargs) -> type: A function that accepts two arguments *(filter, update)* and returns a Boolean: True if the update should be handled, False otherwise. The "update" argument type will vary depending on which `Handler `_ is coming from. - For example, in a :obj:`MessageHandler ` the update type will be - a :obj:`Message `; in a :obj:`CallbackQueryHandler ` the - update type will be a :obj:`CallbackQuery `. Your function body can then access the + For example, in a :obj:`MessageHandler` the update type will be + a :obj:`Message`; in a :obj:`CallbackQueryHandler` the + update type will be a :obj:`CallbackQuery`. Your function body can then access the incoming update and decide whether to allow it or not. **kwargs (``any``, *optional*): @@ -54,7 +54,7 @@ def create(name: str, func: callable, **kwargs) -> type: class Filters: """This class provides access to all library-defined Filters available in Pyrogram. - The Filters listed here are intended to be used with the :obj:`MessageHandler ` only. + The Filters listed here are intended to be used with the :obj:`MessageHandler` only. At the moment, if you want to filter updates coming from different `Handlers `_ you have to create your own filters with :meth:`Filters.create` and use them in the same way. """ @@ -89,49 +89,49 @@ class Filters: """Filter edited messages.""" audio = create("Audio", lambda _, m: bool(m.audio)) - """Filter messages that contain :obj:`Audio ` objects.""" + """Filter messages that contain :obj:`Audio` objects.""" document = create("Document", lambda _, m: bool(m.document)) - """Filter messages that contain :obj:`Document ` objects.""" + """Filter messages that contain :obj:`Document` objects.""" photo = create("Photo", lambda _, m: bool(m.photo)) - """Filter messages that contain :obj:`Photo ` objects.""" + """Filter messages that contain :obj:`Photo` objects.""" sticker = create("Sticker", lambda _, m: bool(m.sticker)) - """Filter messages that contain :obj:`Sticker ` objects.""" + """Filter messages that contain :obj:`Sticker` objects.""" animation = create("Animation", lambda _, m: bool(m.animation)) - """Filter messages that contain :obj:`Animation ` objects.""" + """Filter messages that contain :obj:`Animation` objects.""" game = create("Game", lambda _, m: bool(m.game)) - """Filter messages that contain :obj:`Game ` objects.""" + """Filter messages that contain :obj:`Game` objects.""" video = create("Video", lambda _, m: bool(m.video)) - """Filter messages that contain :obj:`Video ` objects.""" + """Filter messages that contain :obj:`Video` objects.""" media_group = create("MediaGroup", lambda _, m: bool(m.media_group_id)) """Filter messages containing photos or videos being part of an album.""" voice = create("Voice", lambda _, m: bool(m.voice)) - """Filter messages that contain :obj:`Voice ` note objects.""" + """Filter messages that contain :obj:`Voice` note objects.""" video_note = create("VideoNote", lambda _, m: bool(m.video_note)) - """Filter messages that contain :obj:`VideoNote ` objects.""" + """Filter messages that contain :obj:`VideoNote` objects.""" contact = create("Contact", lambda _, m: bool(m.contact)) - """Filter messages that contain :obj:`Contact ` objects.""" + """Filter messages that contain :obj:`Contact` objects.""" location = create("Location", lambda _, m: bool(m.location)) - """Filter messages that contain :obj:`Location ` objects.""" + """Filter messages that contain :obj:`Location` objects.""" venue = create("Venue", lambda _, m: bool(m.venue)) - """Filter messages that contain :obj:`Venue ` objects.""" + """Filter messages that contain :obj:`Venue` objects.""" web_page = create("WebPage", lambda _, m: m.web_page) """Filter messages sent with a webpage preview.""" poll = create("Poll", lambda _, m: m.poll) - """Filter messages that contain :obj:`Poll ` objects.""" + """Filter messages that contain :obj:`Poll` objects.""" private = create("Private", lambda _, m: bool(m.chat and m.chat.type == "private")) """Filter messages sent in private chats.""" @@ -230,12 +230,12 @@ class Filters: ): """Filter commands, i.e.: text messages starting with "/" or any other custom prefix. - Args: + Parameters: commands (``str`` | ``list``): The command or list of commands as string the filter should look for. Examples: "start", ["start", "help", "settings"]. When a message text containing a command arrives, the command itself and its arguments will be stored in the *command* - field of the :class:`Message `. + field of the :class:`Message`. prefix (``str`` | ``list``, *optional*): A prefix or a list of prefixes as string the filter should look for. @@ -275,11 +275,11 @@ class Filters: def regex(pattern, flags: int = 0): """Filter messages that match a given RegEx pattern. - Args: + Parameters: pattern (``str``): The RegEx pattern as string, it will be applied to the text of a message. When a pattern matches, all the `Match Objects `_ - are stored in the *matches* field of the :class:`Message ` itself. + are stored in the *matches* field of the :class:`Message` itself. flags (``int``, *optional*): RegEx flags. @@ -298,7 +298,7 @@ class Filters: You can use `set bound methods `_ to manipulate the users container. - Args: + Parameters: users (``int`` | ``str`` | ``list``): Pass one or more user ids/usernames to filter users. For you yourself, "me" or "self" can be used as well. @@ -329,7 +329,7 @@ class Filters: You can use `set bound methods `_ to manipulate the chats container. - Args: + Parameters: chats (``int`` | ``str`` | ``list``): Pass one or more chat ids/usernames to filter chats. For your personal cloud (Saved Messages) you can simply use "me" or "self". diff --git a/pyrogram/client/handlers/callback_query_handler.py b/pyrogram/client/handlers/callback_query_handler.py index 88ddd5a0..feb46cb0 100644 --- a/pyrogram/client/handlers/callback_query_handler.py +++ b/pyrogram/client/handlers/callback_query_handler.py @@ -26,17 +26,17 @@ class CallbackQueryHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_callback_query() ` decorator. - Args: + Parameters: callback (``callable``): Pass a function that will be called when a new CallbackQuery arrives. It takes *(client, callback_query)* as positional arguments (look at the section below for a detailed description). - filters (:obj:`Filters `): + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of callback queries to be passed in your callback function. Other parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the message handler. callback_query (:obj:`CallbackQuery `): diff --git a/pyrogram/client/handlers/deleted_messages_handler.py b/pyrogram/client/handlers/deleted_messages_handler.py index 52177dcc..f37caaed 100644 --- a/pyrogram/client/handlers/deleted_messages_handler.py +++ b/pyrogram/client/handlers/deleted_messages_handler.py @@ -27,20 +27,20 @@ class DeletedMessagesHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_deleted_messages() ` decorator. - Args: + Parameters: callback (``callable``): Pass a function that will be called when one or more Messages have been deleted. It takes *(client, messages)* as positional arguments (look at the section below for a detailed description). - filters (:obj:`Filters `): + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of messages to be passed in your callback function. Other parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the message handler. - messages (:obj:`Messages `): + messages (:obj:`Messages`): The deleted messages. """ diff --git a/pyrogram/client/handlers/disconnect_handler.py b/pyrogram/client/handlers/disconnect_handler.py index 1e88a7ee..b9e6350a 100644 --- a/pyrogram/client/handlers/disconnect_handler.py +++ b/pyrogram/client/handlers/disconnect_handler.py @@ -26,13 +26,13 @@ class DisconnectHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_disconnect() ` decorator. - Args: + Parameters: callback (``callable``): Pass a function that will be called when a disconnection occurs. It takes *(client)* as positional argument (look at the section below for a detailed description). Other parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself. Useful, for example, when you want to change the proxy before a new connection is established. """ diff --git a/pyrogram/client/handlers/inline_query_handler.py b/pyrogram/client/handlers/inline_query_handler.py index c64d49c8..98a25652 100644 --- a/pyrogram/client/handlers/inline_query_handler.py +++ b/pyrogram/client/handlers/inline_query_handler.py @@ -26,20 +26,20 @@ class InlineQueryHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_inline_query() ` decorator. - Args: + Parameters: callback (``callable``): Pass a function that will be called when a new InlineQuery arrives. It takes *(client, inline_query)* as positional arguments (look at the section below for a detailed description). - filters (:obj:`Filters `): + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of inline queries to be passed in your callback function. Other parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the inline query handler. - inline_query (:obj:`InlineQuery `): + inline_query (:obj:`InlineQuery`): The received inline query. """ diff --git a/pyrogram/client/handlers/message_handler.py b/pyrogram/client/handlers/message_handler.py index 67b4587e..10fff479 100644 --- a/pyrogram/client/handlers/message_handler.py +++ b/pyrogram/client/handlers/message_handler.py @@ -27,20 +27,20 @@ class MessageHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_message() ` decorator. - Args: + Parameters: callback (``callable``): Pass a function that will be called when a new Message arrives. It takes *(client, message)* as positional arguments (look at the section below for a detailed description). - filters (:obj:`Filters `): + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of messages to be passed in your callback function. Other parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the message handler. - message (:obj:`Message `): + message (:obj:`Message`): The received message. """ diff --git a/pyrogram/client/handlers/poll_handler.py b/pyrogram/client/handlers/poll_handler.py index 567fcec0..9e97f2ac 100644 --- a/pyrogram/client/handlers/poll_handler.py +++ b/pyrogram/client/handlers/poll_handler.py @@ -27,7 +27,7 @@ class PollHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_poll() ` decorator. - Args: + Parameters: callback (``callable``): Pass a function that will be called when a new poll update arrives. It takes *(client, poll)* as positional arguments (look at the section below for a detailed description). diff --git a/pyrogram/client/handlers/raw_update_handler.py b/pyrogram/client/handlers/raw_update_handler.py index 3a5dea50..f54d59b6 100644 --- a/pyrogram/client/handlers/raw_update_handler.py +++ b/pyrogram/client/handlers/raw_update_handler.py @@ -26,14 +26,14 @@ class RawUpdateHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_raw_update() ` decorator. - Args: + Parameters: callback (``callable``): A function that will be called when a new update is received from the server. It takes *(client, update, users, chats)* as positional arguments (look at the section below for a detailed description). Other Parameters: - client (:class:`Client `): + client (:class:`Client`): The Client itself, useful when you want to call other API methods inside the update handler. update (``Update``): diff --git a/pyrogram/client/handlers/user_status_handler.py b/pyrogram/client/handlers/user_status_handler.py index 856ef81d..1250cb19 100644 --- a/pyrogram/client/handlers/user_status_handler.py +++ b/pyrogram/client/handlers/user_status_handler.py @@ -26,20 +26,20 @@ class UserStatusHandler(Handler): For a nicer way to register this handler, have a look at the :meth:`on_user_status() ` decorator. - Args: + Parameters: callback (``callable``): Pass a function that will be called when a new UserStatus update arrives. It takes *(client, user_status)* as positional arguments (look at the section below for a detailed description). - filters (:obj:`Filters `): + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of messages to be passed in your callback function. Other parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the user status handler. - user_status (:obj:`UserStatus `): + user_status (:obj:`UserStatus`): The received UserStatus update. """ diff --git a/pyrogram/client/methods/bots/answer_callback_query.py b/pyrogram/client/methods/bots/answer_callback_query.py index 33458db9..12effe47 100644 --- a/pyrogram/client/methods/bots/answer_callback_query.py +++ b/pyrogram/client/methods/bots/answer_callback_query.py @@ -32,7 +32,7 @@ class AnswerCallbackQuery(BaseClient): """Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. - Args: + Parameters: callback_query_id (``str``): Unique identifier for the query to be answered. @@ -54,10 +54,10 @@ class AnswerCallbackQuery(BaseClient): Telegram apps will support caching starting in version 3.14. Defaults to 0. Returns: - True, on success. + ``bool``: True, on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return self.send( functions.messages.SetBotCallbackAnswer( diff --git a/pyrogram/client/methods/bots/answer_inline_query.py b/pyrogram/client/methods/bots/answer_inline_query.py index 7b3524b2..7a1b14c8 100644 --- a/pyrogram/client/methods/bots/answer_inline_query.py +++ b/pyrogram/client/methods/bots/answer_inline_query.py @@ -37,7 +37,7 @@ class AnswerInlineQuery(BaseClient): """Use this method to send answers to an inline query. No more than 50 results per query are allowed. - Args: + Parameters: inline_query_id (``str``): Unique identifier for the answered query. @@ -73,7 +73,10 @@ class AnswerInlineQuery(BaseClient): where they wanted to use the bot's inline capabilities. Returns: - On success, True is returned. + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. """ return self.send( functions.messages.SetInlineBotResults( diff --git a/pyrogram/client/methods/bots/get_game_high_scores.py b/pyrogram/client/methods/bots/get_game_high_scores.py index bb2e99db..64901fea 100644 --- a/pyrogram/client/methods/bots/get_game_high_scores.py +++ b/pyrogram/client/methods/bots/get_game_high_scores.py @@ -29,10 +29,10 @@ class GetGameHighScores(BaseClient): user_id: Union[int, str], chat_id: Union[int, str], message_id: int = None - ): + ) -> "pyrogram.GameHighScores": """Use this method to get data for high score tables. - Args: + Parameters: user_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -49,10 +49,10 @@ class GetGameHighScores(BaseClient): Required if inline_message_id is not specified. Returns: - On success, a :obj:`GameHighScores ` object is returned. + :obj:`GameHighScores`: On success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ # TODO: inline_message_id diff --git a/pyrogram/client/methods/bots/get_inline_bot_results.py b/pyrogram/client/methods/bots/get_inline_bot_results.py index b12c0439..14628b64 100644 --- a/pyrogram/client/methods/bots/get_inline_bot_results.py +++ b/pyrogram/client/methods/bots/get_inline_bot_results.py @@ -35,7 +35,7 @@ class GetInlineBotResults(BaseClient): """Use this method to get bot results via inline queries. You can then send a result using :obj:`send_inline_bot_result ` - Args: + Parameters: bot (``int`` | ``str``): Unique identifier of the inline bot you want to get results from. You can specify a @username (str) or a bot ID (int). @@ -55,11 +55,11 @@ class GetInlineBotResults(BaseClient): Useful for location-based results only. Returns: - On Success, :obj:`BotResults ` is returned. + :obj:`BotResults `: On Success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``TimeoutError`` if the bot fails to answer within 10 seconds + RPCError: In case of a Telegram RPC error. + TimeoutError: In case the bot fails to answer within 10 seconds. """ # TODO: Don't return the raw type diff --git a/pyrogram/client/methods/bots/request_callback_answer.py b/pyrogram/client/methods/bots/request_callback_answer.py index 7b37f51a..b1d8884f 100644 --- a/pyrogram/client/methods/bots/request_callback_answer.py +++ b/pyrogram/client/methods/bots/request_callback_answer.py @@ -32,7 +32,7 @@ class RequestCallbackAnswer(BaseClient): """Use this method to request a callback answer from bots. This is the equivalent of clicking an inline button containing callback data. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -49,8 +49,8 @@ class RequestCallbackAnswer(BaseClient): or as an alert. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``TimeoutError`` if the bot fails to answer within 10 seconds. + RPCError: In case of a Telegram RPC error. + TimeoutError: In case the bot fails to answer within 10 seconds. """ return self.send( functions.messages.GetBotCallbackAnswer( diff --git a/pyrogram/client/methods/bots/send_game.py b/pyrogram/client/methods/bots/send_game.py index a690c960..03593a56 100644 --- a/pyrogram/client/methods/bots/send_game.py +++ b/pyrogram/client/methods/bots/send_game.py @@ -39,7 +39,7 @@ class SendGame(BaseClient): ) -> "pyrogram.Message": """Use this method to send a game. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -60,10 +60,10 @@ class SendGame(BaseClient): If not empty, the first button must launch the game. Returns: - On success, the sent :obj:`Message` is returned. + :obj:`Message`: On success, the sent game message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( functions.messages.SendMedia( diff --git a/pyrogram/client/methods/bots/send_inline_bot_result.py b/pyrogram/client/methods/bots/send_inline_bot_result.py index 9b375a0a..49dc11ee 100644 --- a/pyrogram/client/methods/bots/send_inline_bot_result.py +++ b/pyrogram/client/methods/bots/send_inline_bot_result.py @@ -35,7 +35,7 @@ class SendInlineBotResult(BaseClient): """Use this method to send an inline bot result. Bot results can be retrieved using :obj:`get_inline_bot_results ` - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -61,7 +61,7 @@ class SendInlineBotResult(BaseClient): On success, the sent Message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return self.send( functions.messages.SendInlineBotResult( diff --git a/pyrogram/client/methods/bots/set_game_score.py b/pyrogram/client/methods/bots/set_game_score.py index 434720c6..f5658542 100644 --- a/pyrogram/client/methods/bots/set_game_score.py +++ b/pyrogram/client/methods/bots/set_game_score.py @@ -36,7 +36,7 @@ class SetGameScore(BaseClient): # inline_message_id: str = None): TODO Add inline_message_id """Use this method to set the score of the specified user in a game. - Args: + Parameters: user_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -63,12 +63,11 @@ class SetGameScore(BaseClient): Required if inline_message_id is not specified. Returns: - On success, if the message was sent by the bot, returns the edited :obj:`Message `, + On success, if the message was sent by the bot, returns the edited :obj:`Message`, otherwise returns True. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - :class:`BotScoreNotModified` if the new score is not greater than the user's current score in the chat and force is False. + RPCError: In case of a Telegram RPC error. """ r = self.send( functions.messages.SetGameScore( diff --git a/pyrogram/client/methods/chats/delete_chat_photo.py b/pyrogram/client/methods/chats/delete_chat_photo.py index c11a0d13..f45a7dc2 100644 --- a/pyrogram/client/methods/chats/delete_chat_photo.py +++ b/pyrogram/client/methods/chats/delete_chat_photo.py @@ -35,15 +35,15 @@ class DeleteChatPhoto(BaseClient): In regular groups (non-supergroups), this method will only work if the "All Members Are Admins" setting is off. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. ``ValueError`` if a chat_id belongs to user. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/export_chat_invite_link.py b/pyrogram/client/methods/chats/export_chat_invite_link.py index 16f5bc01..e1ca27c2 100644 --- a/pyrogram/client/methods/chats/export_chat_invite_link.py +++ b/pyrogram/client/methods/chats/export_chat_invite_link.py @@ -38,16 +38,16 @@ class ExportChatInviteLink(BaseClient): using this method – after this the link will become available to the bot via the :meth:`get_chat` method. If your bot needs to generate a new invite link replacing its previous one, use this method again. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier for the target chat or username of the target channel/supergroup (in the format @username). Returns: - On success, the exported invite link as string is returned. + ``str``: On success, the exported invite link is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/get_chat.py b/pyrogram/client/methods/chats/get_chat.py index 38653459..bf4c4cea 100644 --- a/pyrogram/client/methods/chats/get_chat.py +++ b/pyrogram/client/methods/chats/get_chat.py @@ -32,18 +32,18 @@ class GetChat(BaseClient): Information include current name of the user for one-on-one conversations, current username of a user, group or channel, etc. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. Unique identifier for the target chat in form of a *t.me/joinchat/* link, identifier (int) or username of the target channel/supergroup (in the format @username). Returns: - On success, a :obj:`Chat ` object is returned. + :obj:`Chat`: On success, a chat object is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` in case the chat invite link refers to a chat you haven't joined yet. + RPCError: In case of a Telegram RPC error. + ValueError: In case the chat invite link points to a chat you haven't joined yet. """ match = self.INVITE_LINK_RE.match(str(chat_id)) diff --git a/pyrogram/client/methods/chats/get_chat_member.py b/pyrogram/client/methods/chats/get_chat_member.py index aec4d233..b625e32f 100644 --- a/pyrogram/client/methods/chats/get_chat_member.py +++ b/pyrogram/client/methods/chats/get_chat_member.py @@ -32,7 +32,7 @@ class GetChatMember(BaseClient): ) -> "pyrogram.ChatMember": """Use this method to get information about one member of a chat. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -42,10 +42,10 @@ class GetChatMember(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). Returns: - On success, a :obj:`ChatMember ` object is returned. + :obj:`ChatMember`: On success, a chat member is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ chat_id = self.resolve_peer(chat_id) user_id = self.resolve_peer(user_id) diff --git a/pyrogram/client/methods/chats/get_chat_members.py b/pyrogram/client/methods/chats/get_chat_members.py index 726fd14b..79001614 100644 --- a/pyrogram/client/methods/chats/get_chat_members.py +++ b/pyrogram/client/methods/chats/get_chat_members.py @@ -53,7 +53,7 @@ class GetChatMembers(BaseClient): You must be admin to retrieve the members list of a channel (also known as "subscribers"). For a more convenient way of getting chat members see :meth:`iter_chat_members`. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -86,11 +86,11 @@ class GetChatMembers(BaseClient): .. [2] A query string is applicable only for *"all"*, *"kicked"* and *"restricted"* filters only. Returns: - On success, a :obj:`ChatMembers` object is returned. + :obj:`ChatMembers`: On success, an object containing a list of chat members is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` if you used an invalid filter or a chat_id that belongs to a user. + RPCError: In case of a Telegram RPC error. + ValueError: In case you used an invalid filter or a chat id that belongs to a user. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/get_chat_members_count.py b/pyrogram/client/methods/chats/get_chat_members_count.py index fc13ac39..d40585f5 100644 --- a/pyrogram/client/methods/chats/get_chat_members_count.py +++ b/pyrogram/client/methods/chats/get_chat_members_count.py @@ -29,7 +29,7 @@ class GetChatMembersCount(BaseClient): ) -> int: """Use this method to get the number of members in a chat. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -37,8 +37,8 @@ class GetChatMembersCount(BaseClient): On success, an integer is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` if a chat_id belongs to user. + RPCError: In case of a Telegram RPC error. + ValueError: In case a chat id belongs to user. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/get_chat_preview.py b/pyrogram/client/methods/chats/get_chat_preview.py index 9b6c6955..fd00c374 100644 --- a/pyrogram/client/methods/chats/get_chat_preview.py +++ b/pyrogram/client/methods/chats/get_chat_preview.py @@ -30,16 +30,18 @@ class GetChatPreview(BaseClient): This method only returns a chat preview, if you want to join a chat use :meth:`join_chat` - Args: + Parameters: invite_link (``str``): Unique identifier for the target chat in form of *t.me/joinchat/* links. Returns: - Either :obj:`Chat` or :obj:`ChatPreview`, depending on whether you already joined the chat or not. + :obj:`Chat`: In case you already joined the chat. + + :obj:`ChatPreview` -- In case you haven't joined the chat yet. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` in case of an invalid invite_link. + RPCError: In case of a Telegram RPC error. + ValueError: In case of an invalid invite link. """ match = self.INVITE_LINK_RE.match(invite_link) diff --git a/pyrogram/client/methods/chats/get_dialogs.py b/pyrogram/client/methods/chats/get_dialogs.py index 3bcf223f..83732d07 100644 --- a/pyrogram/client/methods/chats/get_dialogs.py +++ b/pyrogram/client/methods/chats/get_dialogs.py @@ -39,7 +39,7 @@ class GetDialogs(BaseClient): You can get up to 100 dialogs at once. For a more convenient way of getting a user's dialogs see :meth:`iter_dialogs`. - Args: + Parameters: offset_date (``int``): The offset date in Unix time taken from the top message of a :obj:`Dialog`. Defaults to 0. Valid for non-pinned dialogs only. @@ -53,10 +53,10 @@ class GetDialogs(BaseClient): Defaults to False. Returns: - On success, a :obj:`Dialogs` object is returned. + :obj:`Dialogs`: On success, an object containing a list of dialogs is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ while True: diff --git a/pyrogram/client/methods/chats/get_dialogs_count.py b/pyrogram/client/methods/chats/get_dialogs_count.py index bf1754ee..eea327da 100644 --- a/pyrogram/client/methods/chats/get_dialogs_count.py +++ b/pyrogram/client/methods/chats/get_dialogs_count.py @@ -29,10 +29,10 @@ class GetDialogsCount(BaseClient): Defaults to False. Returns: - On success, an integer is returned. + ``int``: On success, an integer is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if pinned_only: diff --git a/pyrogram/client/methods/chats/iter_chat_members.py b/pyrogram/client/methods/chats/iter_chat_members.py index 2f41763e..f735da48 100644 --- a/pyrogram/client/methods/chats/iter_chat_members.py +++ b/pyrogram/client/methods/chats/iter_chat_members.py @@ -51,7 +51,7 @@ class IterChatMembers(BaseClient): from the hassle of setting up boilerplate code. It is useful for getting the whole members list of a chat with a single call. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -75,10 +75,10 @@ class IterChatMembers(BaseClient): Defaults to *"all"*. Returns: - A generator yielding :obj:`ChatMember ` objects. + ``Generator``: A generator yielding :obj:`ChatMember` objects. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ current = 0 yielded = set() diff --git a/pyrogram/client/methods/chats/iter_dialogs.py b/pyrogram/client/methods/chats/iter_dialogs.py index 99437cb4..6fc9f81c 100644 --- a/pyrogram/client/methods/chats/iter_dialogs.py +++ b/pyrogram/client/methods/chats/iter_dialogs.py @@ -33,7 +33,7 @@ class IterDialogs(BaseClient): This convenience method does the same as repeatedly calling :meth:`get_dialogs` in a loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting the whole dialogs list with a single call. - Args: + Parameters: offset_date (``int``): The offset date in Unix time taken from the top message of a :obj:`Dialog`. Defaults to 0 (most recent dialog). @@ -43,10 +43,10 @@ class IterDialogs(BaseClient): By default, no limit is applied and all dialogs are returned. Returns: - A generator yielding :obj:`Dialog ` objects. + ``Generator``: A generator yielding :obj:`Dialog` objects. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ current = 0 total = limit or (1 << 31) - 1 diff --git a/pyrogram/client/methods/chats/join_chat.py b/pyrogram/client/methods/chats/join_chat.py index a7933bea..77b2ee50 100644 --- a/pyrogram/client/methods/chats/join_chat.py +++ b/pyrogram/client/methods/chats/join_chat.py @@ -28,16 +28,16 @@ class JoinChat(BaseClient): ): """Use this method to join a group chat or channel. - Args: + Parameters: chat_id (``str``): Unique identifier for the target chat in form of a *t.me/joinchat/* link or username of the target channel/supergroup (in the format @username). Returns: - On success, a :obj:`Chat ` object is returned. + :obj:`Chat`: On success, a chat object is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ match = self.INVITE_LINK_RE.match(chat_id) diff --git a/pyrogram/client/methods/chats/kick_chat_member.py b/pyrogram/client/methods/chats/kick_chat_member.py index 7b10ddea..dbd095ad 100644 --- a/pyrogram/client/methods/chats/kick_chat_member.py +++ b/pyrogram/client/methods/chats/kick_chat_member.py @@ -40,7 +40,7 @@ class KickChatMember(BaseClient): off in the target group. Otherwise members may only be removed by the group's creator or by the member that added them. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -54,10 +54,12 @@ class KickChatMember(BaseClient): considered to be banned forever. Defaults to 0 (ban forever). Returns: - On success, either True or a service :obj:`Message ` will be returned (when applicable). + :obj:`Message`: On success, a service message will be returned (when applicable). + + ``bool`` -- True, in case a message object couldn't be returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ chat_peer = self.resolve_peer(chat_id) user_peer = self.resolve_peer(user_id) diff --git a/pyrogram/client/methods/chats/leave_chat.py b/pyrogram/client/methods/chats/leave_chat.py index 8ba3a3d1..57cc1090 100644 --- a/pyrogram/client/methods/chats/leave_chat.py +++ b/pyrogram/client/methods/chats/leave_chat.py @@ -30,7 +30,7 @@ class LeaveChat(BaseClient): ): """Use this method to leave a group chat or channel. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier for the target chat or username of the target channel/supergroup (in the format @username). @@ -39,7 +39,7 @@ class LeaveChat(BaseClient): Deletes the group chat dialog after leaving (for simple group chats, not supergroups). Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/pin_chat_message.py b/pyrogram/client/methods/chats/pin_chat_message.py index 1d5466ba..2c485dab 100644 --- a/pyrogram/client/methods/chats/pin_chat_message.py +++ b/pyrogram/client/methods/chats/pin_chat_message.py @@ -33,7 +33,7 @@ class PinChatMessage(BaseClient): You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin right in the supergroup or "can_edit_messages" admin right in the channel. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -45,10 +45,10 @@ class PinChatMessage(BaseClient): message. Notifications are always disabled in channels. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ self.send( functions.messages.UpdatePinnedMessage( diff --git a/pyrogram/client/methods/chats/promote_chat_member.py b/pyrogram/client/methods/chats/promote_chat_member.py index 26d49516..0b93576a 100644 --- a/pyrogram/client/methods/chats/promote_chat_member.py +++ b/pyrogram/client/methods/chats/promote_chat_member.py @@ -41,7 +41,7 @@ class PromoteChatMember(BaseClient): You must be an administrator in the chat for this to work and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -76,10 +76,10 @@ class PromoteChatMember(BaseClient): were appointed by him). Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ self.send( functions.channels.EditAdmin( diff --git a/pyrogram/client/methods/chats/restrict_chat.py b/pyrogram/client/methods/chats/restrict_chat.py index 40d46d34..9f6d2910 100644 --- a/pyrogram/client/methods/chats/restrict_chat.py +++ b/pyrogram/client/methods/chats/restrict_chat.py @@ -39,7 +39,7 @@ class RestrictChat(BaseClient): """Use this method to restrict a chat. Pass True for all boolean parameters to lift restrictions from a chat. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -70,10 +70,10 @@ class RestrictChat(BaseClient): Pass True, if the user can pin messages. Returns: - On success, a :obj:`Chat ` object is returned. + :obj:`Chat`: On success, a chat object is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ send_messages = True send_media = True diff --git a/pyrogram/client/methods/chats/restrict_chat_member.py b/pyrogram/client/methods/chats/restrict_chat_member.py index 8688ecca..1f31d8eb 100644 --- a/pyrogram/client/methods/chats/restrict_chat_member.py +++ b/pyrogram/client/methods/chats/restrict_chat_member.py @@ -43,7 +43,7 @@ class RestrictChatMember(BaseClient): The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights. Pass True for all boolean parameters to lift restrictions from a user. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -83,10 +83,10 @@ class RestrictChatMember(BaseClient): Pass True, if the user can pin messages. Returns: - On success, a :obj:`Chat ` object is returned. + :obj:`Chat`: On success, a chat object is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ send_messages = True send_media = True diff --git a/pyrogram/client/methods/chats/set_chat_description.py b/pyrogram/client/methods/chats/set_chat_description.py index 9d4e130b..6cc3bbd3 100644 --- a/pyrogram/client/methods/chats/set_chat_description.py +++ b/pyrogram/client/methods/chats/set_chat_description.py @@ -31,7 +31,7 @@ class SetChatDescription(BaseClient): """Use this method to change the description of a supergroup or a channel. You must be an administrator in the chat for this to work and must have the appropriate admin rights. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -39,10 +39,10 @@ class SetChatDescription(BaseClient): New chat description, 0-255 characters. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. ``ValueError`` if a chat_id doesn't belong to a supergroup or a channel. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/set_chat_photo.py b/pyrogram/client/methods/chats/set_chat_photo.py index 87fe1b72..7248a265 100644 --- a/pyrogram/client/methods/chats/set_chat_photo.py +++ b/pyrogram/client/methods/chats/set_chat_photo.py @@ -39,7 +39,7 @@ class SetChatPhoto(BaseClient): In regular groups (non-supergroups), this method will only work if the "All Members Are Admins" setting is off. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -47,10 +47,10 @@ class SetChatPhoto(BaseClient): New chat photo. You can pass a :class:`Photo` id or a file path to upload a new photo. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. ``ValueError`` if a chat_id belongs to user. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/set_chat_title.py b/pyrogram/client/methods/chats/set_chat_title.py index e94f16a8..a159d2cc 100644 --- a/pyrogram/client/methods/chats/set_chat_title.py +++ b/pyrogram/client/methods/chats/set_chat_title.py @@ -36,7 +36,7 @@ class SetChatTitle(BaseClient): In regular groups (non-supergroups), this method will only work if the "All Members Are Admins" setting is off. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -44,11 +44,11 @@ class SetChatTitle(BaseClient): New chat title, 1-255 characters. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` if a chat_id belongs to user. + RPCError: In case of a Telegram RPC error. + ValueError: In case a chat id belongs to user. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/chats/unban_chat_member.py b/pyrogram/client/methods/chats/unban_chat_member.py index 0576c028..35ea0343 100644 --- a/pyrogram/client/methods/chats/unban_chat_member.py +++ b/pyrogram/client/methods/chats/unban_chat_member.py @@ -32,7 +32,7 @@ class UnbanChatMember(BaseClient): The user will **not** return to the group or channel automatically, but will be able to join via link, etc. You must be an administrator for this to work. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. @@ -41,10 +41,10 @@ class UnbanChatMember(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ self.send( functions.channels.EditBanned( diff --git a/pyrogram/client/methods/chats/unpin_chat_message.py b/pyrogram/client/methods/chats/unpin_chat_message.py index 9753d656..4e2531fd 100644 --- a/pyrogram/client/methods/chats/unpin_chat_message.py +++ b/pyrogram/client/methods/chats/unpin_chat_message.py @@ -31,15 +31,15 @@ class UnpinChatMessage(BaseClient): You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin right in the supergroup or "can_edit_messages" admin right in the channel. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ self.send( functions.messages.UpdatePinnedMessage( diff --git a/pyrogram/client/methods/chats/update_chat_username.py b/pyrogram/client/methods/chats/update_chat_username.py index 39cdfaeb..2e8adb05 100644 --- a/pyrogram/client/methods/chats/update_chat_username.py +++ b/pyrogram/client/methods/chats/update_chat_username.py @@ -32,18 +32,18 @@ class UpdateChatUsername(BaseClient): To update your own username (for users only, not bots) you can use :meth:`update_username`. - Args: + Parameters: chat_id (``int`` | ``str``) Unique identifier (int) or username (str) of the target chat. username (``str`` | ``None``): Username to set. Pass "" (empty string) or None to remove the username. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` if a chat_id belongs to a user or chat. + RPCError: In case of a Telegram RPC error. + ValueError: In case a chat id belongs to a user or chat. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/contacts/add_contacts.py b/pyrogram/client/methods/contacts/add_contacts.py index d1a97c99..aa8e1fd5 100644 --- a/pyrogram/client/methods/contacts/add_contacts.py +++ b/pyrogram/client/methods/contacts/add_contacts.py @@ -30,15 +30,12 @@ class AddContacts(BaseClient): ): """Use this method to add contacts to your Telegram address book. - Args: - contacts (List of :obj:`InputPhoneContact `): + Parameters: + contacts (List of :obj:`InputPhoneContact`): The contact list to be added - Returns: - On success, the added contacts are returned. - Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ imported_contacts = self.send( functions.contacts.ImportContacts( diff --git a/pyrogram/client/methods/contacts/delete_contacts.py b/pyrogram/client/methods/contacts/delete_contacts.py index af8f453e..db5b9df1 100644 --- a/pyrogram/client/methods/contacts/delete_contacts.py +++ b/pyrogram/client/methods/contacts/delete_contacts.py @@ -30,16 +30,16 @@ class DeleteContacts(BaseClient): ): """Use this method to delete contacts from your Telegram address book. - Args: + Parameters: ids (List of ``int``): A list of unique identifiers for the target users. Can be an ID (int), a username (string) or phone number (string). Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ contacts = [] diff --git a/pyrogram/client/methods/contacts/get_contacts.py b/pyrogram/client/methods/contacts/get_contacts.py index e62847c8..7e607e77 100644 --- a/pyrogram/client/methods/contacts/get_contacts.py +++ b/pyrogram/client/methods/contacts/get_contacts.py @@ -18,6 +18,7 @@ import logging import time +from typing import List import pyrogram from pyrogram.api import functions @@ -28,14 +29,14 @@ log = logging.getLogger(__name__) class GetContacts(BaseClient): - def get_contacts(self): + def get_contacts(self) -> List["pyrogram.User"]: """Use this method to get contacts from your Telegram address book. Returns: - On success, a list of :obj:`User` objects is returned. + List of :obj:`User`: On success, a list of users is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ while True: try: diff --git a/pyrogram/client/methods/contacts/get_contacts_count.py b/pyrogram/client/methods/contacts/get_contacts_count.py index b41b27b8..b9e6f6c4 100644 --- a/pyrogram/client/methods/contacts/get_contacts_count.py +++ b/pyrogram/client/methods/contacts/get_contacts_count.py @@ -25,10 +25,10 @@ class GetContactsCount(BaseClient): """Use this method to get the total count of contacts from your Telegram address book. Returns: - On success, an integer is returned. + ``int``: On success, an integer is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return len(self.send(functions.contacts.GetContacts(hash=0)).contacts) diff --git a/pyrogram/client/methods/decorators/on_callback_query.py b/pyrogram/client/methods/decorators/on_callback_query.py index 3c747c5f..9ead25b4 100644 --- a/pyrogram/client/methods/decorators/on_callback_query.py +++ b/pyrogram/client/methods/decorators/on_callback_query.py @@ -33,8 +33,8 @@ class OnCallbackQuery(BaseClient): """Use this decorator to automatically register a function for handling callback queries. This does the same thing as :meth:`add_handler` using the :class:`CallbackQueryHandler`. - Args: - filters (:obj:`Filters `): + Parameters: + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of callback queries to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_deleted_messages.py b/pyrogram/client/methods/decorators/on_deleted_messages.py index cf8f9cf2..eb9dfcd0 100644 --- a/pyrogram/client/methods/decorators/on_deleted_messages.py +++ b/pyrogram/client/methods/decorators/on_deleted_messages.py @@ -33,8 +33,8 @@ class OnDeletedMessages(BaseClient): """Use this decorator to automatically register a function for handling deleted messages. This does the same thing as :meth:`add_handler` using the :class:`DeletedMessagesHandler`. - Args: - filters (:obj:`Filters `): + Parameters: + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of messages to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_inline_query.py b/pyrogram/client/methods/decorators/on_inline_query.py index 81f0f676..e9758c64 100644 --- a/pyrogram/client/methods/decorators/on_inline_query.py +++ b/pyrogram/client/methods/decorators/on_inline_query.py @@ -33,7 +33,7 @@ class OnInlineQuery(BaseClient): """Use this decorator to automatically register a function for handling inline queries. This does the same thing as :meth:`add_handler` using the :class:`InlineQueryHandler`. - Args: + Parameters: filters (:obj:`Filters `): Pass one or more filters to allow only a subset of inline queries to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_message.py b/pyrogram/client/methods/decorators/on_message.py index e6563893..ad95cd45 100644 --- a/pyrogram/client/methods/decorators/on_message.py +++ b/pyrogram/client/methods/decorators/on_message.py @@ -33,8 +33,8 @@ class OnMessage(BaseClient): """Use this decorator to automatically register a function for handling messages. This does the same thing as :meth:`add_handler` using the :class:`MessageHandler`. - Args: - filters (:obj:`Filters `): + Parameters: + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of messages to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_poll.py b/pyrogram/client/methods/decorators/on_poll.py index 56dcd757..68f3d78e 100644 --- a/pyrogram/client/methods/decorators/on_poll.py +++ b/pyrogram/client/methods/decorators/on_poll.py @@ -33,7 +33,7 @@ class OnPoll(BaseClient): """Use this decorator to automatically register a function for handling poll updates. This does the same thing as :meth:`add_handler` using the :class:`PollHandler`. - Args: + Parameters: filters (:obj:`Filters `): Pass one or more filters to allow only a subset of polls to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_raw_update.py b/pyrogram/client/methods/decorators/on_raw_update.py index 1494a319..2ab1f61b 100644 --- a/pyrogram/client/methods/decorators/on_raw_update.py +++ b/pyrogram/client/methods/decorators/on_raw_update.py @@ -31,7 +31,7 @@ class OnRawUpdate(BaseClient): """Use this decorator to automatically register a function for handling raw updates. This does the same thing as :meth:`add_handler` using the :class:`RawUpdateHandler`. - Args: + Parameters: group (``int``, *optional*): The group identifier, defaults to 0. """ diff --git a/pyrogram/client/methods/decorators/on_user_status.py b/pyrogram/client/methods/decorators/on_user_status.py index 4d8185b1..5b49bb3c 100644 --- a/pyrogram/client/methods/decorators/on_user_status.py +++ b/pyrogram/client/methods/decorators/on_user_status.py @@ -33,8 +33,8 @@ class OnUserStatus(BaseClient): """Use this decorator to automatically register a function for handling user status updates. This does the same thing as :meth:`add_handler` using the :class:`UserStatusHandler`. - Args: - filters (:obj:`Filters `): + Parameters: + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of UserStatus updated to be passed in your function. group (``int``, *optional*): diff --git a/pyrogram/client/methods/messages/delete_messages.py b/pyrogram/client/methods/messages/delete_messages.py index 4076be22..067d2fae 100644 --- a/pyrogram/client/methods/messages/delete_messages.py +++ b/pyrogram/client/methods/messages/delete_messages.py @@ -31,7 +31,7 @@ class DeleteMessages(BaseClient): ) -> bool: """Use this method to delete messages, including service messages. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -48,10 +48,10 @@ class DeleteMessages(BaseClient): Defaults to True. Returns: - True on success, False otherwise. + ``bool``: True on success, False otherwise. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ peer = self.resolve_peer(chat_id) message_ids = list(message_ids) if not isinstance(message_ids, int) else [message_ids] diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index 35959d4a..04a5ec57 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -34,8 +34,8 @@ class DownloadMedia(BaseClient): ) -> Union[str, None]: """Use this method to download the media from a message. - Args: - message (:obj:`Message ` | ``str``): + Parameters: + message (:obj:`Message` | ``str``): Pass a Message containing the media, the media itself (message.audio, message.video, ...) or the file id as string. @@ -59,7 +59,7 @@ class DownloadMedia(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -73,11 +73,12 @@ class DownloadMedia(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the absolute path of the downloaded file as string is returned, None otherwise. - In case the download is deliberately stopped with :meth:`stop_transmission`, None is returned as well. + ``str``: On success, the absolute path of the downloaded file is returned. + + ``None`` -- In case the download is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. ``ValueError`` if the message doesn't contain any downloadable media """ error_message = "This message doesn't contain any downloadable media" diff --git a/pyrogram/client/methods/messages/edit_message_caption.py b/pyrogram/client/methods/messages/edit_message_caption.py index c7bcbd70..fe19dcc9 100644 --- a/pyrogram/client/methods/messages/edit_message_caption.py +++ b/pyrogram/client/methods/messages/edit_message_caption.py @@ -34,7 +34,7 @@ class EditMessageCaption(BaseClient): ) -> "pyrogram.Message": """Use this method to edit captions of messages. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -47,18 +47,17 @@ class EditMessageCaption(BaseClient): New caption of the message. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message ` is returned. + :obj:`Message`: On success, the edited message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/edit_message_media.py b/pyrogram/client/methods/messages/edit_message_media.py index 69693384..b03fb1e0 100644 --- a/pyrogram/client/methods/messages/edit_message_media.py +++ b/pyrogram/client/methods/messages/edit_message_media.py @@ -47,7 +47,7 @@ class EditMessageMedia(BaseClient): Use previously uploaded file via its file_id or specify a URL. On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -63,10 +63,10 @@ class EditMessageMedia(BaseClient): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message ` is returned. + :obj:`Message`: On success, the edited message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ style = self.html if media.parse_mode.lower() == "html" else self.markdown caption = media.caption diff --git a/pyrogram/client/methods/messages/edit_message_reply_markup.py b/pyrogram/client/methods/messages/edit_message_reply_markup.py index e3495476..73561451 100644 --- a/pyrogram/client/methods/messages/edit_message_reply_markup.py +++ b/pyrogram/client/methods/messages/edit_message_reply_markup.py @@ -32,7 +32,7 @@ class EditMessageReplyMarkup(BaseClient): ) -> "pyrogram.Message": """Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -45,11 +45,12 @@ class EditMessageReplyMarkup(BaseClient): An InlineKeyboardMarkup object. Returns: - On success, if edited message is sent by the bot, the edited - :obj:`Message ` is returned, otherwise True is returned. + :obj:`Message`: In case the edited message is sent by the bot. + + ``bool`` -- True, in case the edited message is sent by the user. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( diff --git a/pyrogram/client/methods/messages/edit_message_text.py b/pyrogram/client/methods/messages/edit_message_text.py index 8e23b1de..30b58b68 100644 --- a/pyrogram/client/methods/messages/edit_message_text.py +++ b/pyrogram/client/methods/messages/edit_message_text.py @@ -35,7 +35,7 @@ class EditMessageText(BaseClient): ) -> "pyrogram.Message": """Use this method to edit text messages. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -48,9 +48,8 @@ class EditMessageText(BaseClient): New text of the message. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your message. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". disable_web_page_preview (``bool``, *optional*): Disables link previews for links in this message. @@ -59,10 +58,10 @@ class EditMessageText(BaseClient): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message ` is returned. + :obj:`Message`: On success, the edited message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/forward_messages.py b/pyrogram/client/methods/messages/forward_messages.py index 5540b38a..08cc48ea 100644 --- a/pyrogram/client/methods/messages/forward_messages.py +++ b/pyrogram/client/methods/messages/forward_messages.py @@ -35,7 +35,7 @@ class ForwardMessages(BaseClient): ) -> "pyrogram.Messages": """Use this method to forward messages of any kind. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -64,13 +64,14 @@ class ForwardMessages(BaseClient): Defaults to False. Returns: - On success and in case *message_ids* was an iterable, the returned value will be a list of the forwarded - :obj:`Messages ` even if a list contains just one element, otherwise if - *message_ids* was an integer, the single forwarded :obj:`Message ` - is returned. + :obj:`Message`: In case *message_ids* was an integer, the single forwarded message is + returned. + + :obj:`Messages` -- In case *message_ids* was an iterable, the returned value will be an + object containing a list of messages, even if such iterable contained just a single element. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ is_iterable = not isinstance(message_ids, int) diff --git a/pyrogram/client/methods/messages/get_history.py b/pyrogram/client/methods/messages/get_history.py index 1953fabc..ffd8f9e0 100644 --- a/pyrogram/client/methods/messages/get_history.py +++ b/pyrogram/client/methods/messages/get_history.py @@ -43,7 +43,7 @@ class GetHistory(BaseClient): You can get up to 100 messages at once. For a more convenient way of getting a chat history see :meth:`iter_history`. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -67,10 +67,10 @@ class GetHistory(BaseClient): Pass True to retrieve the messages in reversed order (from older to most recent). Returns: - On success, a :obj:`Messages ` object is returned. + :obj:`Messages` - On success, an object containing a list of the retrieved messages. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ while True: diff --git a/pyrogram/client/methods/messages/get_history_count.py b/pyrogram/client/methods/messages/get_history_count.py index 046ec095..b4812d26 100644 --- a/pyrogram/client/methods/messages/get_history_count.py +++ b/pyrogram/client/methods/messages/get_history_count.py @@ -40,15 +40,15 @@ class GetHistoryCount(BaseClient): a **private** or a **basic group** chat has with a single method call. To overcome this limitation, Pyrogram has to iterate over all the messages. Channels and supergroups are not affected by this limitation. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. Returns: - On success, an integer is returned. + ``int``: On success, an integer is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/methods/messages/get_messages.py b/pyrogram/client/methods/messages/get_messages.py index f03cac93..391c251c 100644 --- a/pyrogram/client/methods/messages/get_messages.py +++ b/pyrogram/client/methods/messages/get_messages.py @@ -39,7 +39,7 @@ class GetMessages(BaseClient): """Use this method to get one or more messages that belong to a specific chat. You can retrieve up to 200 messages at once. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -60,12 +60,14 @@ class GetMessages(BaseClient): Defaults to 1. Returns: - On success and in case *message_ids* or *reply_to_message_ids* was an iterable, the returned value will be a - :obj:`Messages ` even if a list contains just one element. Otherwise, if *message_ids* or - *reply_to_message_ids* was an integer, the single requested :obj:`Message ` is returned. + :obj:`Message`: In case *message_ids* was an integer, the single forwarded message is + returned. + + :obj:`Messages` -- In case *message_ids* was an iterable, the returned value will be an + object containing a list of messages, even if such iterable contained just a single element. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ ids, ids_type = ( (message_ids, types.InputMessageID) if message_ids diff --git a/pyrogram/client/methods/messages/iter_history.py b/pyrogram/client/methods/messages/iter_history.py index f7a8a74e..b1546318 100644 --- a/pyrogram/client/methods/messages/iter_history.py +++ b/pyrogram/client/methods/messages/iter_history.py @@ -37,7 +37,7 @@ class IterHistory(BaseClient): This convenience method does the same as repeatedly calling :meth:`get_history` in a loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting the whole chat history with a single call. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -61,10 +61,10 @@ class IterHistory(BaseClient): Pass True to retrieve the messages in reversed order (from older to most recent). Returns: - A generator yielding :obj:`Message ` objects. + ``Generator``: A generator yielding :obj:`Message` objects. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ offset_id = offset_id or (1 if reverse else 0) current = 0 diff --git a/pyrogram/client/methods/messages/retract_vote.py b/pyrogram/client/methods/messages/retract_vote.py index ce8a0140..929298df 100644 --- a/pyrogram/client/methods/messages/retract_vote.py +++ b/pyrogram/client/methods/messages/retract_vote.py @@ -31,7 +31,7 @@ class RetractVote(BaseClient): ) -> "pyrogram.Poll": """Use this method to retract your vote in a poll. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -41,10 +41,10 @@ class RetractVote(BaseClient): Identifier of the original message with the poll. Returns: - On success, the :obj:`Poll ` with the retracted vote is returned. + :obj:`Poll`: On success, the poll with the retracted vote is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( functions.messages.SendVote( diff --git a/pyrogram/client/methods/messages/send_animation.py b/pyrogram/client/methods/messages/send_animation.py index e2335f72..4e21e56c 100644 --- a/pyrogram/client/methods/messages/send_animation.py +++ b/pyrogram/client/methods/messages/send_animation.py @@ -51,7 +51,7 @@ class SendAnimation(BaseClient): ) -> Union["pyrogram.Message", None]: """Use this method to send animation files (animation or H.264/MPEG-4 AVC video without sound). - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -67,9 +67,8 @@ class SendAnimation(BaseClient): Animation caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of sent animation in seconds. @@ -107,7 +106,7 @@ class SendAnimation(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -121,11 +120,12 @@ class SendAnimation(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent animation message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/send_audio.py b/pyrogram/client/methods/messages/send_audio.py index 2f01396f..71458c33 100644 --- a/pyrogram/client/methods/messages/send_audio.py +++ b/pyrogram/client/methods/messages/send_audio.py @@ -53,7 +53,7 @@ class SendAudio(BaseClient): For sending voice messages, use the :obj:`send_voice()` method instead. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -69,9 +69,8 @@ class SendAudio(BaseClient): Audio caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of the audio in seconds. @@ -109,7 +108,7 @@ class SendAudio(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -123,11 +122,12 @@ class SendAudio(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent audio message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/send_cached_media.py b/pyrogram/client/methods/messages/send_cached_media.py index f0c690d9..b0b3fc4e 100644 --- a/pyrogram/client/methods/messages/send_cached_media.py +++ b/pyrogram/client/methods/messages/send_cached_media.py @@ -48,7 +48,7 @@ class SendCachedMedia(BaseClient): It does the same as calling the relevant method for sending media using a file_id, thus saving you from the hassle of using the correct method for the media the file_id is pointing to. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -62,9 +62,8 @@ class SendCachedMedia(BaseClient): Media caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". disable_notification (``bool``, *optional*): Sends the message silently. @@ -78,10 +77,10 @@ class SendCachedMedia(BaseClient): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + :obj:`Message`: On success, the sent media message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/send_chat_action.py b/pyrogram/client/methods/messages/send_chat_action.py index 04777d42..5c50c2cf 100644 --- a/pyrogram/client/methods/messages/send_chat_action.py +++ b/pyrogram/client/methods/messages/send_chat_action.py @@ -31,15 +31,15 @@ class SendChatAction(BaseClient): ): """Use this method when you need to tell the other party that something is happening on your side. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - action (:obj:`ChatAction ` | ``str``): + action (:obj:`ChatAction` | ``str``): Type of action to broadcast. - Choose one from the :class:`ChatAction ` enumeration, + Choose one from the :class:`ChatAction` enumeration, depending on what the user is about to receive. You can also provide a string (e.g. "typing", "upload_photo", "record_audio", ...). @@ -48,11 +48,11 @@ class SendChatAction(BaseClient): Currently useless because official clients don't seem to be handling this. Returns: - On success, True is returned. + ``bool``: On success, True is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` if the provided string is not a valid ChatAction. + RPCError: In case of a Telegram RPC error. + ValueError: In case the provided string is not a valid ChatAction. """ # Resolve Enum type diff --git a/pyrogram/client/methods/messages/send_contact.py b/pyrogram/client/methods/messages/send_contact.py index 9143440e..27df6505 100644 --- a/pyrogram/client/methods/messages/send_contact.py +++ b/pyrogram/client/methods/messages/send_contact.py @@ -42,7 +42,7 @@ class SendContact(BaseClient): ) -> "pyrogram.Message": """Use this method to send phone contacts. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -72,10 +72,10 @@ class SendContact(BaseClient): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + :obj:`Message`: On success, the sent contact message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( functions.messages.SendMedia( diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index 596adeb1..e2ac0d23 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -48,7 +48,7 @@ class SendDocument(BaseClient): ) -> Union["pyrogram.Message", None]: """Use this method to send general files. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -70,9 +70,8 @@ class SendDocument(BaseClient): Document caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". disable_notification (``bool``, *optional*): Sends the message silently. @@ -95,7 +94,7 @@ class SendDocument(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -109,11 +108,12 @@ class SendDocument(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent document message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/send_location.py b/pyrogram/client/methods/messages/send_location.py index f3ed81df..dce6671b 100644 --- a/pyrogram/client/methods/messages/send_location.py +++ b/pyrogram/client/methods/messages/send_location.py @@ -40,7 +40,7 @@ class SendLocation(BaseClient): ) -> "pyrogram.Message": """Use this method to send points on the map. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -64,10 +64,10 @@ class SendLocation(BaseClient): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + :obj:`Message`: On success, the sent location message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( functions.messages.SendMedia( diff --git a/pyrogram/client/methods/messages/send_media_group.py b/pyrogram/client/methods/messages/send_media_group.py index f40401b0..fe6725f0 100644 --- a/pyrogram/client/methods/messages/send_media_group.py +++ b/pyrogram/client/methods/messages/send_media_group.py @@ -43,7 +43,7 @@ class SendMediaGroup(BaseClient): ): """Use this method to send a group of photos or videos as an album. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -60,11 +60,10 @@ class SendMediaGroup(BaseClient): If the message is a reply, ID of the original message. Returns: - On success, a :obj:`Messages ` object is returned containing all the - single messages sent. + :obj:`Messages`: On success, an object is returned containing all the single messages sent. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ multi_media = [] diff --git a/pyrogram/client/methods/messages/send_message.py b/pyrogram/client/methods/messages/send_message.py index b45b7192..15c1487a 100644 --- a/pyrogram/client/methods/messages/send_message.py +++ b/pyrogram/client/methods/messages/send_message.py @@ -41,7 +41,7 @@ class SendMessage(BaseClient): ) -> "pyrogram.Message": """Use this method to send text messages. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -51,9 +51,8 @@ class SendMessage(BaseClient): Text of the message to be sent. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your message. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". disable_web_page_preview (``bool``, *optional*): Disables link previews for links in this message. @@ -70,10 +69,10 @@ class SendMessage(BaseClient): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message` is returned. + :obj:`Message`: On success, the sent text message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ style = self.html if parse_mode.lower() == "html" else self.markdown message, entities = style.parse(text).values() diff --git a/pyrogram/client/methods/messages/send_photo.py b/pyrogram/client/methods/messages/send_photo.py index 7e327cbd..5487761e 100644 --- a/pyrogram/client/methods/messages/send_photo.py +++ b/pyrogram/client/methods/messages/send_photo.py @@ -48,7 +48,7 @@ class SendPhoto(BaseClient): ) -> Union["pyrogram.Message", None]: """Use this method to send photos. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -64,9 +64,8 @@ class SendPhoto(BaseClient): Photo caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". ttl_seconds (``int``, *optional*): Self-Destruct Timer. @@ -94,7 +93,7 @@ class SendPhoto(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -108,11 +107,12 @@ class SendPhoto(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent photo message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/send_poll.py b/pyrogram/client/methods/messages/send_poll.py index 6b4e227a..ff5c8533 100644 --- a/pyrogram/client/methods/messages/send_poll.py +++ b/pyrogram/client/methods/messages/send_poll.py @@ -40,7 +40,7 @@ class SendPoll(BaseClient): ) -> "pyrogram.Message": """Use this method to send a new poll. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -64,10 +64,10 @@ class SendPoll(BaseClient): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + :obj:`Message`: On success, the sent poll message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( functions.messages.SendMedia( diff --git a/pyrogram/client/methods/messages/send_sticker.py b/pyrogram/client/methods/messages/send_sticker.py index a10f3b74..0e314641 100644 --- a/pyrogram/client/methods/messages/send_sticker.py +++ b/pyrogram/client/methods/messages/send_sticker.py @@ -45,7 +45,7 @@ class SendSticker(BaseClient): ) -> Union["pyrogram.Message", None]: """Use this method to send .webp stickers. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -78,7 +78,7 @@ class SendSticker(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -92,11 +92,12 @@ class SendSticker(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent sticker message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None diff --git a/pyrogram/client/methods/messages/send_venue.py b/pyrogram/client/methods/messages/send_venue.py index 1c9ca630..1045bdbd 100644 --- a/pyrogram/client/methods/messages/send_venue.py +++ b/pyrogram/client/methods/messages/send_venue.py @@ -44,7 +44,7 @@ class SendVenue(BaseClient): ) -> "pyrogram.Message": """Use this method to send information about a venue. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -81,10 +81,10 @@ class SendVenue(BaseClient): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + :obj:`Message`: On success, the sent venue message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( functions.messages.SendMedia( diff --git a/pyrogram/client/methods/messages/send_video.py b/pyrogram/client/methods/messages/send_video.py index 045c1cca..baa91d29 100644 --- a/pyrogram/client/methods/messages/send_video.py +++ b/pyrogram/client/methods/messages/send_video.py @@ -52,7 +52,7 @@ class SendVideo(BaseClient): ) -> Union["pyrogram.Message", None]: """Use this method to send video files. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -68,9 +68,8 @@ class SendVideo(BaseClient): Video caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of sent video in seconds. @@ -111,7 +110,7 @@ class SendVideo(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -125,11 +124,12 @@ class SendVideo(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent video message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/send_video_note.py b/pyrogram/client/methods/messages/send_video_note.py index 464f2711..9f934efe 100644 --- a/pyrogram/client/methods/messages/send_video_note.py +++ b/pyrogram/client/methods/messages/send_video_note.py @@ -48,7 +48,7 @@ class SendVideoNote(BaseClient): ) -> Union["pyrogram.Message", None]: """Use this method to send video messages. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -93,7 +93,7 @@ class SendVideoNote(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -107,11 +107,12 @@ class SendVideoNote(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent video note message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None diff --git a/pyrogram/client/methods/messages/send_voice.py b/pyrogram/client/methods/messages/send_voice.py index 44e998b6..e7ec2b11 100644 --- a/pyrogram/client/methods/messages/send_voice.py +++ b/pyrogram/client/methods/messages/send_voice.py @@ -48,7 +48,7 @@ class SendVoice(BaseClient): ) -> Union["pyrogram.Message", None]: """Use this method to send audio files. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -64,9 +64,8 @@ class SendVoice(BaseClient): Voice message caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of the voice message in seconds. @@ -92,7 +91,7 @@ class SendVoice(BaseClient): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -106,11 +105,12 @@ class SendVoice(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + :obj:`Message`: On success, the sent voice message is returned. + + ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ file = None style = self.html if parse_mode.lower() == "html" else self.markdown diff --git a/pyrogram/client/methods/messages/stop_poll.py b/pyrogram/client/methods/messages/stop_poll.py index a5a4ecc8..4179cce4 100644 --- a/pyrogram/client/methods/messages/stop_poll.py +++ b/pyrogram/client/methods/messages/stop_poll.py @@ -34,7 +34,7 @@ class StopPoll(BaseClient): Stopped polls can't be reopened and nobody will be able to vote in it anymore. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -47,10 +47,10 @@ class StopPoll(BaseClient): An InlineKeyboardMarkup object. Returns: - On success, the stopped :obj:`Poll ` with the final results is returned. + :obj:`Poll`: On success, the stopped poll with the final results is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ poll = self.get_messages(chat_id, message_id).poll diff --git a/pyrogram/client/methods/messages/vote_poll.py b/pyrogram/client/methods/messages/vote_poll.py index 58f21a6c..5e7b8ce8 100644 --- a/pyrogram/client/methods/messages/vote_poll.py +++ b/pyrogram/client/methods/messages/vote_poll.py @@ -32,7 +32,7 @@ class VotePoll(BaseClient): ) -> "pyrogram.Poll": """Use this method to vote a poll. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -45,10 +45,10 @@ class VotePoll(BaseClient): Index of the poll option you want to vote for (0 to 9). Returns: - On success, the :obj:`Poll ` with the chosen option is returned. + :obj:`Poll` - On success, the poll with the chosen option is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ poll = self.get_messages(chat_id, message_id).poll diff --git a/pyrogram/client/methods/password/change_cloud_password.py b/pyrogram/client/methods/password/change_cloud_password.py index 2f8cfbd6..b9ee37d5 100644 --- a/pyrogram/client/methods/password/change_cloud_password.py +++ b/pyrogram/client/methods/password/change_cloud_password.py @@ -32,7 +32,7 @@ class ChangeCloudPassword(BaseClient): ) -> bool: """Use this method to change your Two-Step Verification password (Cloud Password) with a new one. - Args: + Parameters: current_password (``str``): Your current password. @@ -43,11 +43,11 @@ class ChangeCloudPassword(BaseClient): A new password hint. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` in case there is no cloud password to change. + RPCError: In case of a Telegram RPC error. + ValueError: In case there is no cloud password to change. """ r = self.send(functions.account.GetPassword()) diff --git a/pyrogram/client/methods/password/enable_cloud_password.py b/pyrogram/client/methods/password/enable_cloud_password.py index b29dcfd3..e2e05633 100644 --- a/pyrogram/client/methods/password/enable_cloud_password.py +++ b/pyrogram/client/methods/password/enable_cloud_password.py @@ -34,7 +34,7 @@ class EnableCloudPassword(BaseClient): This password will be asked when you log-in on a new device in addition to the SMS code. - Args: + Parameters: password (``str``): Your password. @@ -45,11 +45,11 @@ class EnableCloudPassword(BaseClient): Recovery e-mail. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` in case there is already a cloud password enabled. + RPCError: In case of a Telegram RPC error. + ValueError: In case there is already a cloud password enabled. """ r = self.send(functions.account.GetPassword()) diff --git a/pyrogram/client/methods/password/remove_cloud_password.py b/pyrogram/client/methods/password/remove_cloud_password.py index 6e9a0ab4..37160530 100644 --- a/pyrogram/client/methods/password/remove_cloud_password.py +++ b/pyrogram/client/methods/password/remove_cloud_password.py @@ -28,16 +28,16 @@ class RemoveCloudPassword(BaseClient): ) -> bool: """Use this method to turn off the Two-Step Verification security feature (Cloud Password) on your account. - Args: + Parameters: password (``str``): Your current password. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. - ``ValueError`` in case there is no cloud password to remove. + RPCError: In case of a Telegram RPC error. + ValueError: In case there is no cloud password to remove. """ r = self.send(functions.account.GetPassword()) diff --git a/pyrogram/client/methods/users/delete_user_profile_photos.py b/pyrogram/client/methods/users/delete_user_profile_photos.py index bd9fc98e..4e962245 100644 --- a/pyrogram/client/methods/users/delete_user_profile_photos.py +++ b/pyrogram/client/methods/users/delete_user_profile_photos.py @@ -31,16 +31,16 @@ class DeleteUserProfilePhotos(BaseClient): ) -> bool: """Use this method to delete your own profile photos. - Args: + Parameters: id (``str`` | ``list``): - A single :obj:`Photo ` id as string or multiple ids as list of strings for deleting + A single :obj:`Photo` id as string or multiple ids as list of strings for deleting more than one photos at once. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ id = id if isinstance(id, list) else [id] input_photos = [] diff --git a/pyrogram/client/methods/users/get_me.py b/pyrogram/client/methods/users/get_me.py index c8b6c1f1..03d3cdf1 100644 --- a/pyrogram/client/methods/users/get_me.py +++ b/pyrogram/client/methods/users/get_me.py @@ -26,10 +26,10 @@ class GetMe(BaseClient): """A simple method for testing your authorization. Requires no parameters. Returns: - Basic information about the user or bot in form of a :obj:`User` object + :obj:`User`: Basic information about the user or bot. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return pyrogram.User._parse( self, diff --git a/pyrogram/client/methods/users/get_user_profile_photos.py b/pyrogram/client/methods/users/get_user_profile_photos.py index ac7a872e..41dd2593 100644 --- a/pyrogram/client/methods/users/get_user_profile_photos.py +++ b/pyrogram/client/methods/users/get_user_profile_photos.py @@ -32,7 +32,7 @@ class GetUserProfilePhotos(BaseClient): ) -> "pyrogram.UserProfilePhotos": """Use this method to get a list of profile pictures for a user. - Args: + Parameters: user_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -47,10 +47,10 @@ class GetUserProfilePhotos(BaseClient): Values between 1—100 are accepted. Defaults to 100. Returns: - On success, a :obj:`UserProfilePhotos` object is returned. + :obj:`UserProfilePhotos`: On success, an object containing a list of the profile photos is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return pyrogram.UserProfilePhotos._parse( self, diff --git a/pyrogram/client/methods/users/get_user_profile_photos_count.py b/pyrogram/client/methods/users/get_user_profile_photos_count.py index fdb81790..595352c3 100644 --- a/pyrogram/client/methods/users/get_user_profile_photos_count.py +++ b/pyrogram/client/methods/users/get_user_profile_photos_count.py @@ -26,17 +26,17 @@ class GetUserProfilePhotosCount(BaseClient): def get_user_profile_photos_count(self, user_id: Union[int, str]) -> int: """Use this method to get the total count of profile pictures for a user. - Args: + Parameters: user_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). Returns: - On success, an integer is returned. + ``int``: On success, an integer is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ r = self.send( diff --git a/pyrogram/client/methods/users/get_users.py b/pyrogram/client/methods/users/get_users.py index 7e6ebd6b..b1314349 100644 --- a/pyrogram/client/methods/users/get_users.py +++ b/pyrogram/client/methods/users/get_users.py @@ -31,19 +31,19 @@ class GetUsers(BaseClient): """Use this method to get information about a user. You can retrieve up to 200 users at once. - Args: + Parameters: user_ids (``iterable``): A list of User identifiers (id or username) or a single user id/username. For a contact that exists in your Telegram address book you can use his phone number (str). Iterators and Generators are also accepted. Returns: - On success and in case *user_ids* was an iterable, the returned value will be a list of the requested - :obj:`Users ` even if a list contains just one element, otherwise if - *user_ids* was an integer or string, the single requested :obj:`User` is returned. + :obj:`User`: In case *user_ids* was an integer or string. + + List of :obj:`User` -- In case *user_ids* was an iterable, even if the iterable contained one item only. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ is_iterable = not isinstance(user_ids, (int, str)) user_ids = list(user_ids) if is_iterable else [user_ids] diff --git a/pyrogram/client/methods/users/set_user_profile_photo.py b/pyrogram/client/methods/users/set_user_profile_photo.py index af02a12d..e873cf40 100644 --- a/pyrogram/client/methods/users/set_user_profile_photo.py +++ b/pyrogram/client/methods/users/set_user_profile_photo.py @@ -30,16 +30,16 @@ class SetUserProfilePhoto(BaseClient): This method only works for Users. Bots profile photos must be set using BotFather. - Args: + Parameters: photo (``str``): Profile photo to set. Pass a file path as string to upload a new photo that exists on your local machine. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return bool( diff --git a/pyrogram/client/methods/users/update_username.py b/pyrogram/client/methods/users/update_username.py index d0c87eb2..8b5b37ae 100644 --- a/pyrogram/client/methods/users/update_username.py +++ b/pyrogram/client/methods/users/update_username.py @@ -33,15 +33,15 @@ class UpdateUsername(BaseClient): them from scratch using BotFather. To update a channel or supergroup username you can use :meth:`update_chat_username`. - Args: + Parameters: username (``str`` | ``None``): - Username to set. "" (empty string) or None to remove the username. + Username to set. "" (empty string) or None to remove it. Returns: - True on success. + ``bool``: True on success. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return bool( diff --git a/pyrogram/client/types/inline_mode/inline_query.py b/pyrogram/client/types/inline_mode/inline_query.py index 9c1c02ac..a5190452 100644 --- a/pyrogram/client/types/inline_mode/inline_query.py +++ b/pyrogram/client/types/inline_mode/inline_query.py @@ -31,11 +31,11 @@ class InlineQuery(PyrogramType, Update): """This object represents an incoming inline query. When the user sends an empty query, your bot could return some default or trending results. - Args: + Parameters: id (``str``): Unique identifier for this query. - from_user (:obj:`User `): + from_user (:obj:`User`): Sender. query (``str``): @@ -44,7 +44,7 @@ class InlineQuery(PyrogramType, Update): offset (``str``): Offset of the results to be returned, can be controlled by the bot. - location (:obj:`Location `. *optional*): + location (:obj:`Location`. *optional*): Sender location, only for bots that request user location. """ __slots__ = ["id", "from_user", "query", "offset", "location"] @@ -108,7 +108,7 @@ class InlineQuery(PyrogramType, Update): inline_query.answer([...]) - Args: + Parameters: results (List of :obj:`InlineQueryResult `): A list of results for the inline query. 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 8d0089c3..bc0b4e20 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result_article.py +++ b/pyrogram/client/types/inline_mode/inline_query_result_article.py @@ -27,7 +27,7 @@ class InlineQueryResultArticle(InlineQueryResult): TODO: Hide url? - Args: + Parameters: id (``str``): Unique identifier for this result, 1-64 bytes. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py index a67163c6..0ef30b20 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py @@ -25,7 +25,7 @@ class InlineQueryResultAudio(PyrogramType): Attributes: ID: ``0xb0700004`` - Args: + Parameters: type (``str``): Type of the result, must be audio. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py index f6ed1f15..dc51139b 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py @@ -31,7 +31,7 @@ class InlineQueryResultCachedAudio(PyrogramType): By default, this audio file will be sent by the user. Alternatively, you can use *input_message_content* to send a message with the specified content instead of the audio. - Args: + Parameters: id (``str``): Unique identifier for this result, 1-64 bytes. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py index ab1637d2..e2873638 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py @@ -25,7 +25,7 @@ class InlineQueryResultCachedDocument(PyrogramType): Attributes: ID: ``0xb0700015`` - Args: + Parameters: type (``str``): Type of the result, must be document. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py index 4c457873..8b523dbd 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py @@ -25,7 +25,7 @@ class InlineQueryResultCachedGif(PyrogramType): Attributes: ID: ``0xb0700012`` - Args: + Parameters: type (``str``): Type of the result, must be gif. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py index 93ec1efb..2082150d 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py @@ -25,7 +25,7 @@ class InlineQueryResultCachedMpeg4Gif(PyrogramType): Attributes: ID: ``0xb0700013`` - Args: + Parameters: type (``str``): Type of the result, must be mpeg4_gif. @@ -47,7 +47,7 @@ class InlineQueryResultCachedMpeg4Gif(PyrogramType): reply_markup (:obj:`InlineKeyboardMarkup `, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the video animation. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py index ee6b2654..20c1adbc 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py @@ -25,7 +25,7 @@ class InlineQueryResultCachedPhoto(PyrogramType): Attributes: ID: ``0xb0700011`` - Args: + Parameters: type (``str``): Type of the result, must be photo. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py index 6142b1fa..06944deb 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py @@ -25,7 +25,7 @@ class InlineQueryResultCachedSticker(PyrogramType): Attributes: ID: ``0xb0700014`` - Args: + Parameters: type (``str``): Type of the result, must be sticker. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py index 8c00c61a..e47cae1b 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py @@ -25,7 +25,7 @@ class InlineQueryResultCachedVideo(PyrogramType): Attributes: ID: ``0xb0700016`` - Args: + Parameters: type (``str``): Type of the result, must be video. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py index 741df389..3f8bb6a3 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py @@ -25,7 +25,7 @@ class InlineQueryResultCachedVoice(PyrogramType): Attributes: ID: ``0xb0700017`` - Args: + Parameters: type (``str``): Type of the result, must be voice. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py index e26af4ea..60512f0d 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py @@ -25,7 +25,7 @@ class InlineQueryResultContact(PyrogramType): Attributes: ID: ``0xb0700009`` - Args: + Parameters: type (``str``): Type of the result, must be contact. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py index 93b8fcae..148ec01d 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py @@ -25,7 +25,7 @@ class InlineQueryResultDocument(PyrogramType): Attributes: ID: ``0xb0700006`` - Args: + Parameters: type (``str``): Type of the result, must be document. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py index 3e7cfb73..faebacea 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py @@ -25,7 +25,7 @@ class InlineQueryResultGame(PyrogramType): Attributes: ID: ``0xb0700010`` - Args: + Parameters: type (``str``): Type of the result, must be game. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py index 13f4fc18..d84e098b 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py @@ -25,7 +25,7 @@ class InlineQueryResultGif(PyrogramType): Attributes: ID: ``0xb0700001`` - Args: + Parameters: type (``str``): Type of the result, must be gif. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py index 176591d2..cd05c832 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py @@ -25,7 +25,7 @@ class InlineQueryResultLocation(PyrogramType): Attributes: ID: ``0xb0700007`` - Args: + Parameters: type (``str``): Type of the result, must be location. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py index 37aa8986..cb704eeb 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py @@ -25,7 +25,7 @@ class InlineQueryResultMpeg4Gif(PyrogramType): Attributes: ID: ``0xb0700002`` - Args: + Parameters: type (``str``): Type of the result, must be mpeg4_gif. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py index 2ba7c312..3412b3f4 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py @@ -25,7 +25,7 @@ class InlineQueryResultPhoto(PyrogramType): """Represents a link to a photo. By default, this photo will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo. - Args: + Parameters: id (``str``): Unique identifier for this result, 1-64 bytes. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py index 23ddfc35..1dee9509 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py @@ -25,7 +25,7 @@ class InlineQueryResultVenue(PyrogramType): Attributes: ID: ``0xb0700008`` - Args: + Parameters: type (``str``): Type of the result, must be venue. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py index 9b1723e1..22d810e1 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py @@ -25,7 +25,7 @@ class InlineQueryResultVideo(PyrogramType): Attributes: ID: ``0xb0700003`` - Args: + Parameters: type (``str``): Type of the result, must be video. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py index 188063ec..73d7fb1d 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py @@ -25,7 +25,7 @@ class InlineQueryResultVoice(PyrogramType): Attributes: ID: ``0xb0700005`` - Args: + Parameters: type (``str``): Type of the result, must be voice. diff --git a/pyrogram/client/types/input_media/input_media.py b/pyrogram/client/types/input_media/input_media.py index 3062f136..1e0fbc01 100644 --- a/pyrogram/client/types/input_media/input_media.py +++ b/pyrogram/client/types/input_media/input_media.py @@ -22,11 +22,11 @@ from ..pyrogram_type import PyrogramType class InputMedia(PyrogramType): """This object represents the content of a media message to be sent. It should be one of: - - :obj:`InputMediaAnimation ` - - :obj:`InputMediaDocument ` - - :obj:`InputMediaAudio ` - - :obj:`InputMediaPhoto ` - - :obj:`InputMediaVideo ` + - :obj:`InputMediaAnimation` + - :obj:`InputMediaDocument` + - :obj:`InputMediaAudio` + - :obj:`InputMediaPhoto` + - :obj:`InputMediaVideo` """ __slots__ = ["media", "caption", "parse_mode"] diff --git a/pyrogram/client/types/input_media/input_media_animation.py b/pyrogram/client/types/input_media/input_media_animation.py index 6c06df7b..177bd9ad 100644 --- a/pyrogram/client/types/input_media/input_media_animation.py +++ b/pyrogram/client/types/input_media/input_media_animation.py @@ -22,7 +22,7 @@ from . import InputMedia class InputMediaAnimation(InputMedia): """This object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent. - Args: + Parameters: media (``str``): Animation to send. Pass a file_id as string to send a file that exists on the Telegram servers or @@ -38,9 +38,8 @@ class InputMediaAnimation(InputMedia): Caption of the animation to be sent, 0-1024 characters parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline URLs + in your caption. Defaults to "markdown". width (``int``, *optional*): Animation width. diff --git a/pyrogram/client/types/input_media/input_media_audio.py b/pyrogram/client/types/input_media/input_media_audio.py index 6b7659fe..152532fa 100644 --- a/pyrogram/client/types/input_media/input_media_audio.py +++ b/pyrogram/client/types/input_media/input_media_audio.py @@ -23,7 +23,7 @@ class InputMediaAudio(InputMedia): """This object represents an audio to be sent inside an album. It is intended to be used with :obj:`send_media_group() `. - Args: + Parameters: media (``str``): Audio to send. Pass a file_id as string to send an audio that exists on the Telegram servers or @@ -39,9 +39,8 @@ class InputMediaAudio(InputMedia): Caption of the audio to be sent, 0-1024 characters parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline URLs + in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of the audio in seconds diff --git a/pyrogram/client/types/input_media/input_media_document.py b/pyrogram/client/types/input_media/input_media_document.py index a5d36261..046b731c 100644 --- a/pyrogram/client/types/input_media/input_media_document.py +++ b/pyrogram/client/types/input_media/input_media_document.py @@ -22,7 +22,7 @@ from . import InputMedia class InputMediaDocument(InputMedia): """This object represents a general file to be sent. - Args: + Parameters: media (``str``): File to send. Pass a file_id as string to send a file that exists on the Telegram servers or @@ -38,9 +38,8 @@ class InputMediaDocument(InputMedia): Caption of the document to be sent, 0-1024 characters parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline URLs + in your caption. Defaults to "markdown". """ __slots__ = ["thumb"] diff --git a/pyrogram/client/types/input_media/input_media_photo.py b/pyrogram/client/types/input_media/input_media_photo.py index e6bba03b..2797bd5f 100644 --- a/pyrogram/client/types/input_media/input_media_photo.py +++ b/pyrogram/client/types/input_media/input_media_photo.py @@ -23,7 +23,7 @@ class InputMediaPhoto(InputMedia): """This object represents a photo to be sent inside an album. It is intended to be used with :obj:`send_media_group() `. - Args: + Parameters: media (``str``): Photo to send. Pass a file_id as string to send a photo that exists on the Telegram servers or @@ -34,9 +34,8 @@ class InputMediaPhoto(InputMedia): Caption of the photo to be sent, 0-1024 characters parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline URLs + in your caption. Defaults to "markdown". """ __slots__ = [] diff --git a/pyrogram/client/types/input_media/input_media_video.py b/pyrogram/client/types/input_media/input_media_video.py index 27d166bd..319973de 100644 --- a/pyrogram/client/types/input_media/input_media_video.py +++ b/pyrogram/client/types/input_media/input_media_video.py @@ -23,7 +23,7 @@ class InputMediaVideo(InputMedia): """This object represents a video to be sent inside an album. It is intended to be used with :obj:`send_media_group() `. - Args: + Parameters: media (``str``): Video to send. Pass a file_id as string to send a video that exists on the Telegram servers or @@ -40,9 +40,8 @@ class InputMediaVideo(InputMedia): Caption of the video to be sent, 0-1024 characters parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline URLs + in your caption. Defaults to "markdown". width (``int``, *optional*): Video width. diff --git a/pyrogram/client/types/input_media/input_phone_contact.py b/pyrogram/client/types/input_media/input_phone_contact.py index d2ac8012..02189011 100644 --- a/pyrogram/client/types/input_media/input_phone_contact.py +++ b/pyrogram/client/types/input_media/input_phone_contact.py @@ -25,7 +25,7 @@ class InputPhoneContact(PyrogramType): """This object represents a Phone Contact to be added in your Telegram address book. It is intended to be used with :meth:`add_contacts() ` - Args: + Parameters: phone (``str``): Contact's phone number 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 0e6ffa8b..feedd298 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 @@ -24,14 +24,13 @@ from ...style import HTML, Markdown class InputTextMessageContent(InputMessageContent): """This object represents the content of a text message to be sent as the result of an inline query. - Args: + Parameters: message_text (``str``): Text of the message to be sent, 1-4096 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your message. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline URLs + in your message. Defaults to "markdown". disable_web_page_preview (``bool``, *optional*): Disables link previews for links in this message. diff --git a/pyrogram/client/types/keyboards/callback_query.py b/pyrogram/client/types/keyboards/callback_query.py index ac58338a..61bbfe40 100644 --- a/pyrogram/client/types/keyboards/callback_query.py +++ b/pyrogram/client/types/keyboards/callback_query.py @@ -32,18 +32,18 @@ class CallbackQuery(PyrogramType, Update): will be present. If the button was attached to a message sent via the bot (in inline mode), the field inline_message_id will be present. Exactly one of the fields data or game_short_name will be present. - Args: + Parameters: id (``str``): Unique identifier for this query. - from_user (:obj:`User `): + from_user (:obj:`User`): Sender. chat_instance (``str``, *optional*): Global identifier, uniquely corresponding to the chat to which the message with the callback button was sent. Useful for high scores in games. - message (:obj:`Message `, *optional*): + message (:obj:`Message`, *optional*): Message with the callback button that originated the query. Note that message content and message date will not be available if the message is too old. @@ -121,7 +121,7 @@ class CallbackQuery(PyrogramType, Update): ) def answer(self, text: str = None, show_alert: bool = None, url: str = None, cache_time: int = 0): - """Bound method *answer* of :obj:`CallbackQuery `. + """Bound method *answer* of :obj:`CallbackQuery`. Use this method as a shortcut for: @@ -138,7 +138,7 @@ class CallbackQuery(PyrogramType, Update): callback_query.answer("Hello", show_alert=True) - Args: + Parameters: text (``str``): Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters. diff --git a/pyrogram/client/types/keyboards/force_reply.py b/pyrogram/client/types/keyboards/force_reply.py index 12969742..f48dab14 100644 --- a/pyrogram/client/types/keyboards/force_reply.py +++ b/pyrogram/client/types/keyboards/force_reply.py @@ -27,7 +27,7 @@ class ForceReply(PyrogramType): This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode. - Args: + Parameters: selective (``bool``, *optional*): Use this parameter if you want to force reply from specific users only. Targets: 1) users that are @mentioned in the text of the Message object; diff --git a/pyrogram/client/types/keyboards/game_high_score.py b/pyrogram/client/types/keyboards/game_high_score.py index da6b2881..07db8e73 100644 --- a/pyrogram/client/types/keyboards/game_high_score.py +++ b/pyrogram/client/types/keyboards/game_high_score.py @@ -26,7 +26,7 @@ from pyrogram.client.types.user_and_chats import User class GameHighScore(PyrogramType): """This object represents one row of the high scores table for a game. - Args: + Parameters: user (:obj:`User`): User. diff --git a/pyrogram/client/types/keyboards/game_high_scores.py b/pyrogram/client/types/keyboards/game_high_scores.py index 3c197969..36b14c0f 100644 --- a/pyrogram/client/types/keyboards/game_high_scores.py +++ b/pyrogram/client/types/keyboards/game_high_scores.py @@ -27,11 +27,11 @@ from .game_high_score import GameHighScore class GameHighScores(PyrogramType): """This object represents the high scores table for a game. - Args: + Parameters: total_count (``int``): Total number of scores the target game has. - game_high_scores (List of :obj:`GameHighScore `): + game_high_scores (List of :obj:`GameHighScore`): Game scores. """ diff --git a/pyrogram/client/types/keyboards/inline_keyboard_button.py b/pyrogram/client/types/keyboards/inline_keyboard_button.py index a26d6ca6..ea110f7f 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_button.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_button.py @@ -29,7 +29,7 @@ from ..pyrogram_type import PyrogramType class InlineKeyboardButton(PyrogramType): """This object represents one button of an inline keyboard. You must use exactly one of the optional fields. - Args: + Parameters: text (``str``): Label text on the button. diff --git a/pyrogram/client/types/keyboards/inline_keyboard_markup.py b/pyrogram/client/types/keyboards/inline_keyboard_markup.py index 54476c5e..f48f4b8c 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_markup.py @@ -26,8 +26,8 @@ from ..pyrogram_type import PyrogramType class InlineKeyboardMarkup(PyrogramType): """This object represents an inline keyboard that appears right next to the message it belongs to. - Args: - inline_keyboard (List of List of :obj:`InlineKeyboardButton `): + Parameters: + inline_keyboard (List of List of :obj:`InlineKeyboardButton`): List of button rows, each represented by a List of InlineKeyboardButton objects. """ diff --git a/pyrogram/client/types/keyboards/keyboard_button.py b/pyrogram/client/types/keyboards/keyboard_button.py index 477442cc..e0393e3d 100644 --- a/pyrogram/client/types/keyboards/keyboard_button.py +++ b/pyrogram/client/types/keyboards/keyboard_button.py @@ -26,7 +26,7 @@ class KeyboardButton(PyrogramType): For simple text buttons String can be used instead of this object to specify text of the button. Optional fields are mutually exclusive. - Args: + Parameters: text (``str``): Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed. diff --git a/pyrogram/client/types/keyboards/reply_keyboard_markup.py b/pyrogram/client/types/keyboards/reply_keyboard_markup.py index b0216803..32c73c6b 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_markup.py @@ -27,8 +27,8 @@ from ..pyrogram_type import PyrogramType class ReplyKeyboardMarkup(PyrogramType): """This object represents a custom keyboard with reply options. - Args: - keyboard (List of List of :obj:`KeyboardButton `): + Parameters: + keyboard (List of List of :obj:`KeyboardButton`): List of button rows, each represented by a List of KeyboardButton objects. resize_keyboard (``bool``, *optional*): diff --git a/pyrogram/client/types/keyboards/reply_keyboard_remove.py b/pyrogram/client/types/keyboards/reply_keyboard_remove.py index 75f2a7b5..560c89ee 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_remove.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_remove.py @@ -25,7 +25,7 @@ class ReplyKeyboardRemove(PyrogramType): By default, custom keyboards are displayed until a new keyboard is sent by a bot. An exception is made for one-time keyboards that are hidden immediately after the user presses a button (see ReplyKeyboardMarkup). - Args: + Parameters: selective (``bool``, *optional*): Use this parameter if you want to remove the keyboard for specific users only. Targets: 1) users that are @mentioned in the text of the Message object; diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index 21a01e0f..25dda78e 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -28,7 +28,7 @@ from ...ext.utils import encode class Animation(PyrogramType): """This object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound). - Args: + Parameters: file_id (``str``): Unique identifier for this file. diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index db49f2eb..9f024ee1 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -28,14 +28,14 @@ from ...ext.utils import encode class Audio(PyrogramType): """This object represents an audio file to be treated as music by the Telegram clients. - Args: + Parameters: file_id (``str``): Unique identifier for this file. duration (``int``): Duration of the audio in seconds as defined by sender. - thumb (:obj:`PhotoSize `, *optional*): + thumb (:obj:`PhotoSize`, *optional*): Thumbnail of the music file album cover. file_name (``str``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/contact.py b/pyrogram/client/types/messages_and_media/contact.py index 5abe5319..e2fba707 100644 --- a/pyrogram/client/types/messages_and_media/contact.py +++ b/pyrogram/client/types/messages_and_media/contact.py @@ -25,7 +25,7 @@ from ..pyrogram_type import PyrogramType class Contact(PyrogramType): """This object represents a phone contact. - Args: + Parameters: phone_number (``str``): Contact's phone number. diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index f3ccc4f8..c4c8ab16 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -28,11 +28,11 @@ from ...ext.utils import encode class Document(PyrogramType): """This object represents a general file (as opposed to photos, voice messages, audio files, ...). - Args: + Parameters: file_id (``str``): Unique file identifier. - thumb (:obj:`PhotoSize `, *optional*): + thumb (:obj:`PhotoSize`, *optional*): Document thumbnail as defined by sender. file_name (``str``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/game.py b/pyrogram/client/types/messages_and_media/game.py index cf0b4fa6..50268153 100644 --- a/pyrogram/client/types/messages_and_media/game.py +++ b/pyrogram/client/types/messages_and_media/game.py @@ -27,7 +27,7 @@ class Game(PyrogramType): """This object represents a game. Use BotFather to create and edit games, their short names will act as unique identifiers. - Args: + Parameters: id (``int``): Unique identifier of the game. @@ -40,10 +40,10 @@ class Game(PyrogramType): description (``str``): Description of the game. - photo (:obj:`Photo `): + photo (:obj:`Photo`): Photo that will be displayed in the game message in chats. - animation (:obj:`Animation `, *optional*): + animation (:obj:`Animation`, *optional*): Animation that will be displayed in the game message in chats. Upload via BotFather. """ diff --git a/pyrogram/client/types/messages_and_media/location.py b/pyrogram/client/types/messages_and_media/location.py index 3a7f6d38..6af918f7 100644 --- a/pyrogram/client/types/messages_and_media/location.py +++ b/pyrogram/client/types/messages_and_media/location.py @@ -25,7 +25,7 @@ from ..pyrogram_type import PyrogramType class Location(PyrogramType): """This object represents a point on the map. - Args: + Parameters: longitude (``float``): Longitude as defined by sender. diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 9234cb42..46f6187a 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -63,26 +63,26 @@ class Str(str): class Message(PyrogramType, Update): """This object represents a message. - Args: + Parameters: message_id (``int``): Unique message identifier inside this chat. date (``int``, *optional*): Date the message was sent in Unix time. - chat (:obj:`Chat `, *optional*): + chat (:obj:`Chat`, *optional*): Conversation the message belongs to. - from_user (:obj:`User `, *optional*): + from_user (:obj:`User`, *optional*): Sender, empty for messages sent to channels. - forward_from (:obj:`User `, *optional*): + forward_from (:obj:`User`, *optional*): For forwarded messages, sender of the original message. forward_sender_name (``str``, *optional*): For messages forwarded from users who have hidden their accounts, name of the user. - forward_from_chat (:obj:`Chat `, *optional*): + forward_from_chat (:obj:`Chat`, *optional*): For messages forwarded from channels, information about the original channel. forward_from_message_id (``int``, *optional*): @@ -94,7 +94,7 @@ class Message(PyrogramType, Update): forward_date (``int``, *optional*): For forwarded messages, date the original message was sent in Unix time. - reply_to_message (:obj:`Message `, *optional*): + reply_to_message (:obj:`Message`, *optional*): For replies, the original message. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply. @@ -131,38 +131,38 @@ class Message(PyrogramType, Update): *text.html* to get the marked up message text. In case there is no entity, the fields will contain the same text as *text*. - entities (List of :obj:`MessageEntity `, *optional*): + entities (List of :obj:`MessageEntity`, *optional*): For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text. - caption_entities (List of :obj:`MessageEntity `, *optional*): + caption_entities (List of :obj:`MessageEntity`, *optional*): For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption. - audio (:obj:`Audio `, *optional*): + audio (:obj:`Audio`, *optional*): Message is an audio file, information about the file. - document (:obj:`Document `, *optional*): + document (:obj:`Document`, *optional*): Message is a general file, information about the file. - photo (:obj:`Photo `, *optional*): + photo (:obj:`Photo`, *optional*): Message is a photo, information about the photo. - sticker (:obj:`Sticker `, *optional*): + sticker (:obj:`Sticker`, *optional*): Message is a sticker, information about the sticker. - animation (:obj:`Animation `, *optional*): + animation (:obj:`Animation`, *optional*): Message is an animation, information about the animation. - game (:obj:`Game `, *optional*): + game (:obj:`Game`, *optional*): Message is a game, information about the game. - video (:obj:`Video `, *optional*): + video (:obj:`Video`, *optional*): Message is a video, information about the video. - voice (:obj:`Voice `, *optional*): + voice (:obj:`Voice`, *optional*): Message is a voice message, information about the file. - video_note (:obj:`VideoNote `, *optional*): + video_note (:obj:`VideoNote`, *optional*): Message is a video note, information about the video message. caption (``str``, *optional*): @@ -171,13 +171,13 @@ class Message(PyrogramType, Update): *caption.html* to get the marked up caption text. In case there is no caption entity, the fields will contain the same text as *caption*. - contact (:obj:`Contact `, *optional*): + contact (:obj:`Contact`, *optional*): Message is a shared contact, information about the contact. - location (:obj:`Location `, *optional*): + location (:obj:`Location`, *optional*): Message is a shared location, information about the location. - venue (:obj:`Venue `, *optional*): + venue (:obj:`Venue`, *optional*): Message is a venue, information about the venue. web_page (``bool``, *optional*): @@ -186,20 +186,20 @@ class Message(PyrogramType, Update): web page preview. In future versions this property could turn into a full web page object that contains more details. - poll (:obj:`Poll `, *optional*): + poll (:obj:`Poll`, *optional*): Message is a native poll, information about the poll. - new_chat_members (List of :obj:`User `, *optional*): + new_chat_members (List of :obj:`User`, *optional*): New members that were added to the group or supergroup and information about them (the bot itself may be one of these members). - left_chat_member (:obj:`User `, *optional*): + left_chat_member (:obj:`User`, *optional*): A member was removed from the group, information about them (this member may be the bot itself). new_chat_title (``str``, *optional*): A chat title was changed to this value. - new_chat_photo (:obj:`Photo `, *optional*): + new_chat_photo (:obj:`Photo`, *optional*): A chat photo was change to this value. delete_chat_photo (``bool``, *optional*): @@ -232,19 +232,19 @@ class Message(PyrogramType, Update): in interpreting it. But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier. - pinned_message (:obj:`Message `, *optional*): + pinned_message (:obj:`Message`, *optional*): Specified message was pinned. Note that the Message object in this field will not contain further reply_to_message fields even if it is itself a reply. - game_high_score (:obj:`GameHighScore `, *optional*): + game_high_score (:obj:`GameHighScore`, *optional*): The game score for a user. The reply_to_message field will contain the game Message. views (``int``, *optional*): Channel post views. - via_bot (:obj:`User `): + via_bot (:obj:`User`): The information of the bot that generated the message from an inline query of a user. outgoing (``bool``, *optional*): @@ -662,7 +662,7 @@ class Message(PyrogramType, Update): reply_to_message_id: int = None, reply_markup=None ) -> "Message": - """Bound method *reply* of :obj:`Message `. + """Bound method *reply* of :obj:`Message`. Use as a shortcut for: @@ -679,7 +679,7 @@ class Message(PyrogramType, Update): message.reply("hello", quote=True) - Args: + Parameters: text (``str``): Text of the message to be sent. @@ -689,9 +689,8 @@ class Message(PyrogramType, Update): Defaults to ``True`` in group chats and ``False`` in private chats. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your message. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". disable_web_page_preview (``bool``, *optional*): Disables link previews for links in this message. @@ -711,7 +710,7 @@ class Message(PyrogramType, Update): On success, the sent Message is returned. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -750,7 +749,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_animation* of :obj:`Message `. + """Bound method *reply_animation* of :obj:`Message`. Use as a shortcut for: @@ -766,7 +765,7 @@ class Message(PyrogramType, Update): message.reply_animation(animation) - Args: + Parameters: animation (``str``): Animation to send. Pass a file_id as string to send an animation that exists on the Telegram servers, @@ -782,9 +781,8 @@ class Message(PyrogramType, Update): Animation caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of sent animation in seconds. @@ -822,7 +820,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -836,11 +834,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -885,7 +883,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_audio* of :obj:`Message `. + """Bound method *reply_audio* of :obj:`Message`. Use as a shortcut for: @@ -901,7 +899,7 @@ class Message(PyrogramType, Update): message.reply_audio(audio) - Args: + Parameters: audio (``str``): Audio file to send. Pass a file_id as string to send an audio file that exists on the Telegram servers, @@ -917,9 +915,8 @@ class Message(PyrogramType, Update): Audio caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of the audio in seconds. @@ -957,7 +954,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -971,11 +968,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1014,7 +1011,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_cached_media* of :obj:`Message `. + """Bound method *reply_cached_media* of :obj:`Message`. Use as a shortcut for: @@ -1030,7 +1027,7 @@ class Message(PyrogramType, Update): message.reply_cached_media(file_id) - Args: + Parameters: file_id (``str``): Media to send. Pass a file_id as string to send a media that exists on the Telegram servers. @@ -1044,9 +1041,8 @@ class Message(PyrogramType, Update): Media caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". disable_notification (``bool``, *optional*): Sends the message silently. @@ -1060,10 +1056,10 @@ class Message(PyrogramType, Update): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1086,7 +1082,7 @@ class Message(PyrogramType, Update): action: Union[ChatAction, str], progress: int = 0 ) -> "Message": - """Bound method *reply_chat_action* of :obj:`Message `. + """Bound method *reply_chat_action* of :obj:`Message`. Use as a shortcut for: @@ -1102,7 +1098,7 @@ class Message(PyrogramType, Update): message.reply_chat_action("typing") - Args: + Parameters: action (:obj:`ChatAction ` | ``str``): Type of action to broadcast. Choose one from the :class:`ChatAction ` enumeration, @@ -1117,7 +1113,7 @@ class Message(PyrogramType, Update): On success, True is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. ``ValueError`` if the provided string is not a valid ChatAction. """ return self._client.send_chat_action( @@ -1142,7 +1138,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_contact* of :obj:`Message `. + """Bound method *reply_contact* of :obj:`Message`. Use as a shortcut for: @@ -1159,7 +1155,7 @@ class Message(PyrogramType, Update): message.reply_contact(phone_number, "Dan") - Args: + Parameters: phone_number (``str``): Contact's phone number. @@ -1189,10 +1185,10 @@ class Message(PyrogramType, Update): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1229,7 +1225,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_document* of :obj:`Message `. + """Bound method *reply_document* of :obj:`Message`. Use as a shortcut for: @@ -1245,7 +1241,7 @@ class Message(PyrogramType, Update): message.reply_document(document) - Args: + Parameters: document (``str``): File to send. Pass a file_id as string to send a file that exists on the Telegram servers, @@ -1267,9 +1263,8 @@ class Message(PyrogramType, Update): Document caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". disable_notification (``bool``, *optional*): Sends the message silently. @@ -1292,7 +1287,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -1306,11 +1301,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1344,7 +1339,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_game* of :obj:`Message `. + """Bound method *reply_game* of :obj:`Message`. Use as a shortcut for: @@ -1360,7 +1355,7 @@ class Message(PyrogramType, Update): message.reply_game("lumberjack") - Args: + Parameters: game_short_name (``str``): Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather. @@ -1384,7 +1379,7 @@ class Message(PyrogramType, Update): On success, the sent :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1409,7 +1404,7 @@ class Message(PyrogramType, Update): reply_to_message_id: int = None, hide_via: bool = None ) -> "Message": - """Bound method *reply_inline_bot_result* of :obj:`Message `. + """Bound method *reply_inline_bot_result* of :obj:`Message`. Use as a shortcut for: @@ -1426,7 +1421,7 @@ class Message(PyrogramType, Update): message.reply_inline_bot_result(query_id, result_id) - Args: + Parameters: query_id (``int``): Unique identifier for the answered query. @@ -1452,7 +1447,7 @@ class Message(PyrogramType, Update): On success, the sent Message is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1483,7 +1478,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_location* of :obj:`Message `. + """Bound method *reply_location* of :obj:`Message`. Use as a shortcut for: @@ -1500,7 +1495,7 @@ class Message(PyrogramType, Update): message.reply_location(41.890251, 12.492373) - Args: + Parameters: latitude (``float``): Latitude of the location. @@ -1524,10 +1519,10 @@ class Message(PyrogramType, Update): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1551,7 +1546,7 @@ class Message(PyrogramType, Update): disable_notification: bool = None, reply_to_message_id: int = None ) -> "Message": - """Bound method *reply_media_group* of :obj:`Message `. + """Bound method *reply_media_group* of :obj:`Message`. Use as a shortcut for: @@ -1567,7 +1562,7 @@ class Message(PyrogramType, Update): message.reply_media_group(list_of_media) - Args: + Parameters: media (``list``): A list containing either :obj:`InputMediaPhoto ` or :obj:`InputMediaVideo ` objects @@ -1586,11 +1581,11 @@ class Message(PyrogramType, Update): If the message is a reply, ID of the original message. Returns: - On success, a :obj:`Messages ` object is returned containing all the + On success, a :obj:`Messages` object is returned containing all the single messages sent. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1623,7 +1618,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_photo* of :obj:`Message `. + """Bound method *reply_photo* of :obj:`Message`. Use as a shortcut for: @@ -1639,7 +1634,7 @@ class Message(PyrogramType, Update): message.reply_photo(photo) - Args: + Parameters: photo (``str``): Photo to send. Pass a file_id as string to send a photo that exists on the Telegram servers, @@ -1655,9 +1650,8 @@ class Message(PyrogramType, Update): Photo caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". ttl_seconds (``int``, *optional*): Self-Destruct Timer. @@ -1685,7 +1679,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -1699,11 +1693,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1738,7 +1732,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_poll* of :obj:`Message `. + """Bound method *reply_poll* of :obj:`Message`. Use as a shortcut for: @@ -1755,7 +1749,7 @@ class Message(PyrogramType, Update): message.reply_poll("Is Pyrogram the best?", ["Yes", "Yes"]) - Args: + Parameters: question (``str``): The poll question, as string. @@ -1779,10 +1773,10 @@ class Message(PyrogramType, Update): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1814,7 +1808,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_sticker* of :obj:`Message `. + """Bound method *reply_sticker* of :obj:`Message`. Use as a shortcut for: @@ -1830,7 +1824,7 @@ class Message(PyrogramType, Update): message.reply_sticker(sticker) - Args: + Parameters: sticker (``str``): Sticker to send. Pass a file_id as string to send a sticker that exists on the Telegram servers, @@ -1863,7 +1857,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -1877,11 +1871,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -1917,7 +1911,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_venue* of :obj:`Message `. + """Bound method *reply_venue* of :obj:`Message`. Use as a shortcut for: @@ -1936,7 +1930,7 @@ class Message(PyrogramType, Update): message.reply_venue(41.890251, 12.492373, "Coliseum", "Piazza del Colosseo, 1, 00184 Roma RM") - Args: + Parameters: latitude (``float``): Latitude of the venue. @@ -1973,10 +1967,10 @@ class Message(PyrogramType, Update): instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -2019,7 +2013,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video* of :obj:`Message `. + """Bound method *reply_video* of :obj:`Message`. Use as a shortcut for: @@ -2035,7 +2029,7 @@ class Message(PyrogramType, Update): message.reply_video(video) - Args: + Parameters: video (``str``): Video to send. Pass a file_id as string to send a video that exists on the Telegram servers, @@ -2051,9 +2045,8 @@ class Message(PyrogramType, Update): Video caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of sent video in seconds. @@ -2094,7 +2087,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -2108,11 +2101,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -2155,7 +2148,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video_note* of :obj:`Message `. + """Bound method *reply_video_note* of :obj:`Message`. Use as a shortcut for: @@ -2171,7 +2164,7 @@ class Message(PyrogramType, Update): message.reply_video_note(video_note) - Args: + Parameters: video_note (``str``): Video note to send. Pass a file_id as string to send a video note that exists on the Telegram servers, or @@ -2216,7 +2209,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -2230,11 +2223,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -2273,7 +2266,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_voice* of :obj:`Message `. + """Bound method *reply_voice* of :obj:`Message`. Use as a shortcut for: @@ -2289,7 +2282,7 @@ class Message(PyrogramType, Update): message.reply_voice(voice) - Args: + Parameters: voice (``str``): Audio file to send. Pass a file_id as string to send an audio that exists on the Telegram servers, @@ -2305,9 +2298,8 @@ class Message(PyrogramType, Update): Voice message caption, 0-1024 characters. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your caption. Defaults to "markdown". duration (``int``, *optional*): Duration of the voice message in seconds. @@ -2333,7 +2325,7 @@ class Message(PyrogramType, Update): a chat_id and a message_id in order to edit a message with the updated progress. Other Parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the callback function. current (``int``): @@ -2347,11 +2339,11 @@ class Message(PyrogramType, Update): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - On success, the sent :obj:`Message ` is returned. + On success, the sent :obj:`Message` is returned. In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ if quote is None: quote = self.chat.type != "private" @@ -2384,7 +2376,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit* of :obj:`Message ` + """Bound method *edit* of :obj:`Message` Use as a shortcut for: @@ -2401,14 +2393,13 @@ class Message(PyrogramType, Update): message.edit("hello") - Args: + Parameters: text (``str``): New text of the message. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your message. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". disable_web_page_preview (``bool``, *optional*): Disables link previews for links in this message. @@ -2417,10 +2408,10 @@ class Message(PyrogramType, Update): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message ` is returned. + On success, the edited :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return self._client.edit_message_text( chat_id=self.chat.id, @@ -2442,7 +2433,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit_caption* of :obj:`Message ` + """Bound method *edit_caption* of :obj:`Message` Use as a shortcut for: @@ -2459,23 +2450,22 @@ class Message(PyrogramType, Update): message.edit_caption("hello") - Args: + Parameters: caption (``str``): New caption of the message. parse_mode (``str``, *optional*): - Use :obj:`MARKDOWN ` or :obj:`HTML ` - if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your message. - Defaults to Markdown. + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message ` is returned. + On success, the edited :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return self._client.edit_message_caption( chat_id=self.chat.id, @@ -2486,7 +2476,7 @@ class Message(PyrogramType, Update): ) def edit_media(self, media: InputMedia, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_media* of :obj:`Message ` + """Bound method *edit_media* of :obj:`Message` Use as a shortcut for: @@ -2503,7 +2493,7 @@ class Message(PyrogramType, Update): message.edit_media(media) - Args: + Parameters: media (:obj:`InputMediaAnimation` | :obj:`InputMediaAudio` | :obj:`InputMediaDocument` | :obj:`InputMediaPhoto` | :obj:`InputMediaVideo`) One of the InputMedia objects describing an animation, audio, document, photo or video. @@ -2511,10 +2501,10 @@ class Message(PyrogramType, Update): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message ` is returned. + On success, the edited :obj:`Message` is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return self._client.edit_message_media( chat_id=self.chat.id, @@ -2524,7 +2514,7 @@ class Message(PyrogramType, Update): ) def edit_reply_markup(self, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_reply_markup* of :obj:`Message ` + """Bound method *edit_reply_markup* of :obj:`Message` Use as a shortcut for: @@ -2541,16 +2531,16 @@ class Message(PyrogramType, Update): message.edit_reply_markup(inline_reply_markup) - Args: + Parameters: reply_markup (:obj:`InlineKeyboardMarkup`): An InlineKeyboardMarkup object. Returns: On success, if edited message is sent by the bot, the edited - :obj:`Message ` is returned, otherwise True is returned. + :obj:`Message` is returned, otherwise True is returned. Raises: - :class:`RPCError ` in case of a Telegram RPC error. + RPCError: In case of a Telegram RPC error. """ return self._client.edit_message_reply_markup( chat_id=self.chat.id, @@ -2565,7 +2555,7 @@ class Message(PyrogramType, Update): as_copy: bool = False, remove_caption: bool = False ) -> "Message": - """Bound method *forward* of :obj:`Message `. + """Bound method *forward* of :obj:`Message`. Use as a shortcut for: @@ -2582,7 +2572,7 @@ class Message(PyrogramType, Update): message.forward(chat_id) - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -2605,7 +2595,7 @@ class Message(PyrogramType, Update): On success, the forwarded Message is returned. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ if as_copy: if self.service: @@ -2708,7 +2698,7 @@ class Message(PyrogramType, Update): ) def delete(self, revoke: bool = True): - """Bound method *delete* of :obj:`Message `. + """Bound method *delete* of :obj:`Message`. Use as a shortcut for: @@ -2724,7 +2714,7 @@ class Message(PyrogramType, Update): message.delete() - Args: + Parameters: revoke (``bool``, *optional*): Deletes messages on both parts. This is only for private cloud chats and normal groups, messages on @@ -2735,7 +2725,7 @@ class Message(PyrogramType, Update): True on success, False otherwise. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ return self._client.delete_messages( chat_id=self.chat.id, @@ -2744,7 +2734,7 @@ class Message(PyrogramType, Update): ) def click(self, x: int or str, y: int = None, quote: bool = None): - """Bound method *click* of :obj:`Message `. + """Bound method *click* of :obj:`Message`. Use as a shortcut for clicking a button attached to the message instead of. @@ -2779,7 +2769,7 @@ class Message(PyrogramType, Update): 3. Pass one string argument only (e.g.: ``.click("Settings")``, to click a button by using its label). Only the first matching button will be pressed. - Args: + Parameters: x (``int`` | ``str``): Used as integer index, integer abscissa (in pair with y) or as string label. @@ -2798,7 +2788,7 @@ class Message(PyrogramType, Update): button. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. ``ValueError``: If the provided index or position is out of range or the button label was not found ``TimeoutError``: If, after clicking an inline button, the bot fails to answer within 10 seconds """ @@ -2862,7 +2852,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *download* of :obj:`Message `. + """Bound method *download* of :obj:`Message`. Use as a shortcut for: @@ -2875,7 +2865,7 @@ class Message(PyrogramType, Update): message.download() - Args: + Parameters: file_name (``str``, *optional*): A custom *file_name* to be used instead of the one provided by Telegram. By default, all files are downloaded in the *downloads* folder in your working directory. @@ -2899,7 +2889,7 @@ class Message(PyrogramType, Update): On success, the absolute path of the downloaded file as string is returned, None otherwise. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. ``ValueError``: If the message doesn't contain any downloadable media """ return self._client.download_media( @@ -2911,7 +2901,7 @@ class Message(PyrogramType, Update): ) def pin(self, disable_notification: bool = None) -> "Message": - """Bound method *pin* of :obj:`Message `. + """Bound method *pin* of :obj:`Message`. Use as a shortcut for: @@ -2927,7 +2917,7 @@ class Message(PyrogramType, Update): message.pin() - Args: + Parameters: disable_notification (``bool``): Pass True, if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels. diff --git a/pyrogram/client/types/messages_and_media/message_entity.py b/pyrogram/client/types/messages_and_media/message_entity.py index 160d0d1e..6fe4ef91 100644 --- a/pyrogram/client/types/messages_and_media/message_entity.py +++ b/pyrogram/client/types/messages_and_media/message_entity.py @@ -27,7 +27,7 @@ class MessageEntity(PyrogramType): """This object represents one special entity in a text message. For example, hashtags, usernames, URLs, etc. - Args: + Parameters: type (``str``): Type of the entity. Can be "mention" (@username), "hashtag", "cashtag", "bot_command", "url", "email", "phone_number", "bold" @@ -43,7 +43,7 @@ class MessageEntity(PyrogramType): url (``str``, *optional*): For "text_link" only, url that will be opened after user taps on the text. - user (:obj:`User `, *optional*): + user (:obj:`User`, *optional*): For "text_mention" only, the mentioned user. """ diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py index 4f78277c..4ce41aec 100644 --- a/pyrogram/client/types/messages_and_media/messages.py +++ b/pyrogram/client/types/messages_and_media/messages.py @@ -29,11 +29,11 @@ from ..user_and_chats import Chat class Messages(PyrogramType, Update): """This object represents a chat's messages. - Args: + Parameters: total_count (``int``): Total number of messages the target chat has. - messages (List of :obj:`Message `): + messages (List of :obj:`Message`): Requested messages. """ @@ -124,9 +124,9 @@ class Messages(PyrogramType, Update): as_copy: bool = False, remove_caption: bool = False ): - """Bound method *forward* of :obj:`Message `. + """Bound method *forward* of :obj:`Message`. - Args: + Parameters: chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". @@ -146,10 +146,10 @@ class Messages(PyrogramType, Update): Defaults to False. Returns: - On success, a :class:`Messages ` containing forwarded messages is returned. + On success, a :class:`Messages` containing forwarded messages is returned. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ forwarded_messages = [] diff --git a/pyrogram/client/types/messages_and_media/photo.py b/pyrogram/client/types/messages_and_media/photo.py index 6f1852fb..f7f9f4ec 100644 --- a/pyrogram/client/types/messages_and_media/photo.py +++ b/pyrogram/client/types/messages_and_media/photo.py @@ -30,14 +30,14 @@ from ...ext.utils import encode class Photo(PyrogramType): """This object represents a Photo. - Args: + Parameters: id (``str``): Unique identifier for this photo. date (``int``): Date the photo was sent in Unix time. - sizes (List of :obj:`PhotoSize `): + sizes (List of :obj:`PhotoSize`): Available sizes of this photo. """ diff --git a/pyrogram/client/types/messages_and_media/photo_size.py b/pyrogram/client/types/messages_and_media/photo_size.py index 10d00a86..a154c077 100644 --- a/pyrogram/client/types/messages_and_media/photo_size.py +++ b/pyrogram/client/types/messages_and_media/photo_size.py @@ -28,7 +28,7 @@ from ..pyrogram_type import PyrogramType class PhotoSize(PyrogramType): """This object represents one size of a photo or a file/sticker thumbnail. - Args: + Parameters: file_id (``str``): Unique identifier for this file. diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index fa68f669..602da364 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -28,7 +28,7 @@ from ..update import Update class Poll(PyrogramType, Update): """This object represents a Poll. - Args: + Parameters: id (``str``): Unique poll identifier. diff --git a/pyrogram/client/types/messages_and_media/poll_option.py b/pyrogram/client/types/messages_and_media/poll_option.py index 4b32623a..31eed702 100644 --- a/pyrogram/client/types/messages_and_media/poll_option.py +++ b/pyrogram/client/types/messages_and_media/poll_option.py @@ -23,7 +23,7 @@ from ..pyrogram_type import PyrogramType class PollOption(PyrogramType): """This object contains information about one answer option in a poll. - Args: + Parameters: text (``str``): Option text, 1-100 characters. diff --git a/pyrogram/client/types/messages_and_media/sticker.py b/pyrogram/client/types/messages_and_media/sticker.py index 1ae2c23e..e6b8de35 100644 --- a/pyrogram/client/types/messages_and_media/sticker.py +++ b/pyrogram/client/types/messages_and_media/sticker.py @@ -30,7 +30,7 @@ from ...ext.utils import encode class Sticker(PyrogramType): """This object represents a sticker. - Args: + Parameters: file_id (``str``): Unique identifier for this file. @@ -40,7 +40,7 @@ class Sticker(PyrogramType): height (``int``): Sticker height. - thumb (:obj:`PhotoSize `, *optional*): + thumb (:obj:`PhotoSize`, *optional*): Sticker thumbnail in the .webp or .jpg format. file_name (``str``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/user_profile_photos.py b/pyrogram/client/types/messages_and_media/user_profile_photos.py index f162b077..66bcb51a 100644 --- a/pyrogram/client/types/messages_and_media/user_profile_photos.py +++ b/pyrogram/client/types/messages_and_media/user_profile_photos.py @@ -26,11 +26,11 @@ from ..pyrogram_type import PyrogramType class UserProfilePhotos(PyrogramType): """This object represents a user's profile pictures. - Args: + Parameters: total_count (``int``): Total number of profile pictures the target user has. - photos (List of :obj:`Photo `): + photos (List of :obj:`Photo`): Requested profile pictures. """ diff --git a/pyrogram/client/types/messages_and_media/venue.py b/pyrogram/client/types/messages_and_media/venue.py index 97829142..61e3d912 100644 --- a/pyrogram/client/types/messages_and_media/venue.py +++ b/pyrogram/client/types/messages_and_media/venue.py @@ -25,8 +25,8 @@ from ..pyrogram_type import PyrogramType class Venue(PyrogramType): """This object represents a venue. - Args: - location (:obj:`Location `): + Parameters: + location (:obj:`Location`): Venue location. title (``str``): diff --git a/pyrogram/client/types/messages_and_media/video.py b/pyrogram/client/types/messages_and_media/video.py index a45a8f8d..8c3e9c00 100644 --- a/pyrogram/client/types/messages_and_media/video.py +++ b/pyrogram/client/types/messages_and_media/video.py @@ -28,7 +28,7 @@ from ...ext.utils import encode class Video(PyrogramType): """This object represents a video file. - Args: + Parameters: file_id (``str``): Unique identifier for this file. @@ -41,7 +41,7 @@ class Video(PyrogramType): duration (``int``): Duration of the video in seconds as defined by sender. - thumb (:obj:`PhotoSize `, *optional*): + thumb (:obj:`PhotoSize`, *optional*): Video thumbnail. file_name (``str``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/video_note.py b/pyrogram/client/types/messages_and_media/video_note.py index e6c2ab31..59c60c6e 100644 --- a/pyrogram/client/types/messages_and_media/video_note.py +++ b/pyrogram/client/types/messages_and_media/video_note.py @@ -28,7 +28,7 @@ from ...ext.utils import encode class VideoNote(PyrogramType): """This object represents a video note. - Args: + Parameters: file_id (``str``): Unique identifier for this file. @@ -38,7 +38,7 @@ class VideoNote(PyrogramType): duration (``int``): Duration of the video in seconds as defined by sender. - thumb (:obj:`PhotoSize `, *optional*): + thumb (:obj:`PhotoSize`, *optional*): Video thumbnail. mime_type (``str``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/voice.py b/pyrogram/client/types/messages_and_media/voice.py index b4063088..87804826 100644 --- a/pyrogram/client/types/messages_and_media/voice.py +++ b/pyrogram/client/types/messages_and_media/voice.py @@ -27,7 +27,7 @@ from ...ext.utils import encode class Voice(PyrogramType): """This object represents a voice note. - Args: + Parameters: file_id (``str``): Unique identifier for this file. diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 1d4369d4..0c6210eb 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -28,7 +28,7 @@ from ..pyrogram_type import PyrogramType class Chat(PyrogramType): """This object represents a chat. - Args: + Parameters: id (``int``): Unique identifier for this chat. @@ -58,7 +58,7 @@ class Chat(PyrogramType): Chat invite link, for supergroups and channel chats. Returned only in :meth:`get_chat() `. - pinned_message (:obj:`Message `, *optional*): + pinned_message (:obj:`Message`, *optional*): Pinned message, for supergroups and channel chats. Returned only in :meth:`get_chat() `. diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 046d2ebc..9841af83 100644 --- a/pyrogram/client/types/user_and_chats/chat_member.py +++ b/pyrogram/client/types/user_and_chats/chat_member.py @@ -25,8 +25,8 @@ from ..pyrogram_type import PyrogramType class ChatMember(PyrogramType): """This object contains information about one member of a chat. - Args: - user (:obj:`User `): + Parameters: + user (:obj:`User`): Information about the user. status (``str``): @@ -39,17 +39,17 @@ class ChatMember(PyrogramType): is_member (``bool``, *optional*): Restricted only. True, if the user is a member of the chat at the moment of the request. - invited_by (:obj:`User `, *optional*): + invited_by (:obj:`User`, *optional*): Administrators and self member only. Information about the user who invited this member. In case the user joined by himself this will be the same as "user". - promoted_by (:obj:`User `, *optional*): + promoted_by (:obj:`User`, *optional*): Administrators only. Information about the user who promoted this member as administrator. - restricted_by (:obj:`User `, *optional*): + restricted_by (:obj:`User`, *optional*): Restricted and kicked only. Information about the user who restricted or kicked this member. - permissions (:obj:`ChatPermissions ` *optional*): + permissions (:obj:`ChatPermissions` *optional*): Administrators, restricted and kicked members only. Information about the member permissions. """ diff --git a/pyrogram/client/types/user_and_chats/chat_members.py b/pyrogram/client/types/user_and_chats/chat_members.py index 3c89b124..d7cf3b9a 100644 --- a/pyrogram/client/types/user_and_chats/chat_members.py +++ b/pyrogram/client/types/user_and_chats/chat_members.py @@ -27,7 +27,7 @@ from ..pyrogram_type import PyrogramType class ChatMembers(PyrogramType): """This object contains information about the members list of a chat. - Args: + Parameters: total_count (``int``): Total number of members the chat has. diff --git a/pyrogram/client/types/user_and_chats/chat_permissions.py b/pyrogram/client/types/user_and_chats/chat_permissions.py index 7b35b1d0..ec00272e 100644 --- a/pyrogram/client/types/user_and_chats/chat_permissions.py +++ b/pyrogram/client/types/user_and_chats/chat_permissions.py @@ -28,7 +28,7 @@ class ChatPermissions(PyrogramType): Some permissions make sense depending on the context: default chat permissions, restricted/kicked member or administrators in groups or channels. - Args: + Parameters: until_date (``int``, *optional*): Applicable to restricted and kicked members only. Date when user restrictions will be lifted, unix time. diff --git a/pyrogram/client/types/user_and_chats/chat_photo.py b/pyrogram/client/types/user_and_chats/chat_photo.py index 6fbc779d..af4f2df4 100644 --- a/pyrogram/client/types/user_and_chats/chat_photo.py +++ b/pyrogram/client/types/user_and_chats/chat_photo.py @@ -27,7 +27,7 @@ from ...ext.utils import encode class ChatPhoto(PyrogramType): """This object represents a chat photo. - Args: + Parameters: small_file_id (``str``): Unique file identifier of small (160x160) chat photo. This file_id can be used only for photo download. diff --git a/pyrogram/client/types/user_and_chats/chat_preview.py b/pyrogram/client/types/user_and_chats/chat_preview.py index ddd84b09..b6b136a1 100644 --- a/pyrogram/client/types/user_and_chats/chat_preview.py +++ b/pyrogram/client/types/user_and_chats/chat_preview.py @@ -28,7 +28,7 @@ from ..user_and_chats.user import User class ChatPreview(PyrogramType): """This object represents a chat preview. - Args: + Parameters: title (``str``): Title of the chat. diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index d406d783..ec011d81 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -26,11 +26,11 @@ from ..user_and_chats import Chat class Dialog(PyrogramType): """This object represents a dialog. - Args: + Parameters: chat (:obj:`Chat `): Conversation the dialog belongs to. - top_message (:obj:`Message `): + top_message (:obj:`Message`): The last message sent in the dialog at this time. unread_messages_count (``int``): diff --git a/pyrogram/client/types/user_and_chats/dialogs.py b/pyrogram/client/types/user_and_chats/dialogs.py index 431cca8d..97ca462b 100644 --- a/pyrogram/client/types/user_and_chats/dialogs.py +++ b/pyrogram/client/types/user_and_chats/dialogs.py @@ -28,11 +28,11 @@ from ..pyrogram_type import PyrogramType class Dialogs(PyrogramType): """This object represents a user's dialogs chunk. - Args: + Parameters: total_count (``int``): Total number of dialogs the user has. - dialogs (List of :obj:`Dialog `): + dialogs (List of :obj:`Dialog`): Requested dialogs. """ diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 5718b917..976ce5a0 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -26,7 +26,7 @@ from ..pyrogram_type import PyrogramType class User(PyrogramType): """This object represents a Telegram user or bot. - Args: + Parameters: id (``int``): Unique identifier for this user or bot. diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index 170ce373..0f9c003e 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -31,7 +31,7 @@ class UserStatus(PyrogramType, Update): You won't see exact last seen timestamps for people with whom you don't share your own. Instead, you get "recently", "within_week", "within_month" or "long_time_ago" fields set. - Args: + Parameters: user_id (``int``): User's id. From 3a494a478ff95b4d18164d8ce198bc5896cc0c4a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 9 May 2019 04:32:43 +0200 Subject: [PATCH 038/202] Remove ParseMode It's pretty much useless, better just use "markdown" and "html" --- pyrogram/client/__init__.py | 4 +-- pyrogram/client/ext/__init__.py | 1 - pyrogram/client/ext/parse_mode.py | 29 ------------------- .../types/messages_and_media/message.py | 4 +-- 4 files changed, 4 insertions(+), 34 deletions(-) delete mode 100644 pyrogram/client/ext/parse_mode.py diff --git a/pyrogram/client/__init__.py b/pyrogram/client/__init__.py index d43511d2..584449c7 100644 --- a/pyrogram/client/__init__.py +++ b/pyrogram/client/__init__.py @@ -17,9 +17,9 @@ # along with Pyrogram. If not, see . from .client import Client -from .ext import BaseClient, ChatAction, Emoji, ParseMode +from .ext import BaseClient, ChatAction, Emoji from .filters import Filters __all__ = [ - "Client", "BaseClient", "ChatAction", "Emoji", "ParseMode", "Filters", + "Client", "BaseClient", "ChatAction", "Emoji", "Filters", ] diff --git a/pyrogram/client/ext/__init__.py b/pyrogram/client/ext/__init__.py index 18c28ac3..a8e7c794 100644 --- a/pyrogram/client/ext/__init__.py +++ b/pyrogram/client/ext/__init__.py @@ -20,5 +20,4 @@ from .base_client import BaseClient from .chat_action import ChatAction from .dispatcher import Dispatcher from .emoji import Emoji -from .parse_mode import ParseMode from .syncer import Syncer diff --git a/pyrogram/client/ext/parse_mode.py b/pyrogram/client/ext/parse_mode.py deleted file mode 100644 index 46ed97e3..00000000 --- a/pyrogram/client/ext/parse_mode.py +++ /dev/null @@ -1,29 +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 . - - -class ParseMode: - """This class provides a convenient access to Parse Modes. - Parse Modes are intended to be used with any method that accepts the optional argument **parse_mode**. - """ - - HTML = "html" - """Set the parse mode to HTML style""" - - MARKDOWN = "markdown" - """Set the parse mode to Markdown style""" diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 46f6187a..648177d4 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -22,7 +22,7 @@ from typing import List, Match, Union import pyrogram from pyrogram.api import types from pyrogram.errors import MessageIdsEmpty -from pyrogram.client.ext import ChatAction, ParseMode +from pyrogram.client.ext import ChatAction from pyrogram.client.types.input_media import InputMedia from .contact import Contact from .location import Location @@ -2686,7 +2686,7 @@ class Message(PyrogramType, Update): if self.sticker or self.video_note: # Sticker and VideoNote should have no caption return send_media(file_id=file_id) else: - return send_media(file_id=file_id, caption=caption, parse_mode=ParseMode.HTML) + return send_media(file_id=file_id, caption=caption, parse_mode="html") else: raise ValueError("Can't copy this message") else: From 6530c7e293b6f088d2db14ef3e2443bd79b6922b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 9 May 2019 04:58:55 +0200 Subject: [PATCH 039/202] Remove ChatAction module too It's pretty much useless, better just use strings --- docs/source/pyrogram/ChatAction.rst | 5 -- docs/source/pyrogram/index.rst | 1 - pyrogram/client/__init__.py | 4 +- pyrogram/client/ext/__init__.py | 1 - pyrogram/client/ext/chat_action.py | 77 ------------------- .../methods/messages/send_chat_action.py | 59 ++++++++------ .../types/messages_and_media/message.py | 30 +++----- 7 files changed, 49 insertions(+), 128 deletions(-) delete mode 100644 docs/source/pyrogram/ChatAction.rst delete mode 100644 pyrogram/client/ext/chat_action.py diff --git a/docs/source/pyrogram/ChatAction.rst b/docs/source/pyrogram/ChatAction.rst deleted file mode 100644 index dfa56945..00000000 --- a/docs/source/pyrogram/ChatAction.rst +++ /dev/null @@ -1,5 +0,0 @@ -ChatAction -========== - -.. autoclass:: pyrogram.ChatAction - :members: diff --git a/docs/source/pyrogram/index.rst b/docs/source/pyrogram/index.rst index 84471e89..5546070d 100644 --- a/docs/source/pyrogram/index.rst +++ b/docs/source/pyrogram/index.rst @@ -14,7 +14,6 @@ after the well established Telegram Bot API methods, thus offering a familiar lo Handlers Decorators Filters - ChatAction Errors diff --git a/pyrogram/client/__init__.py b/pyrogram/client/__init__.py index 584449c7..f4a954c6 100644 --- a/pyrogram/client/__init__.py +++ b/pyrogram/client/__init__.py @@ -17,9 +17,9 @@ # along with Pyrogram. If not, see . from .client import Client -from .ext import BaseClient, ChatAction, Emoji +from .ext import BaseClient, Emoji from .filters import Filters __all__ = [ - "Client", "BaseClient", "ChatAction", "Emoji", "Filters", + "Client", "BaseClient", "Emoji", "Filters", ] diff --git a/pyrogram/client/ext/__init__.py b/pyrogram/client/ext/__init__.py index a8e7c794..917c9e62 100644 --- a/pyrogram/client/ext/__init__.py +++ b/pyrogram/client/ext/__init__.py @@ -17,7 +17,6 @@ # along with Pyrogram. If not, see . from .base_client import BaseClient -from .chat_action import ChatAction from .dispatcher import Dispatcher from .emoji import Emoji from .syncer import Syncer diff --git a/pyrogram/client/ext/chat_action.py b/pyrogram/client/ext/chat_action.py deleted file mode 100644 index c0ee0585..00000000 --- a/pyrogram/client/ext/chat_action.py +++ /dev/null @@ -1,77 +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 enum import Enum - -from pyrogram.api import types - - -class ChatAction(Enum): - """This enumeration provides a convenient access to all Chat Actions available. - Chat Actions are intended to be used with - :meth:`send_chat_action() `. - """ - - CANCEL = types.SendMessageCancelAction - """Cancels any chat action currently displayed.""" - - TYPING = types.SendMessageTypingAction - """User is typing a text message.""" - - PLAYING = types.SendMessageGamePlayAction - """User is playing a game.""" - - CHOOSE_CONTACT = types.SendMessageChooseContactAction - """User is choosing a contact to share.""" - - UPLOAD_PHOTO = types.SendMessageUploadPhotoAction - """User is uploading a photo.""" - - RECORD_VIDEO = types.SendMessageRecordVideoAction - """User is recording a video.""" - - UPLOAD_VIDEO = types.SendMessageUploadVideoAction - """User is uploading a video.""" - - RECORD_AUDIO = types.SendMessageRecordAudioAction - """User is recording an audio message.""" - - UPLOAD_AUDIO = types.SendMessageUploadAudioAction - """User is uploading an audio message.""" - - UPLOAD_DOCUMENT = types.SendMessageUploadDocumentAction - """User is uploading a generic document.""" - - FIND_LOCATION = types.SendMessageGeoLocationAction - """User is searching for a location on the map.""" - - RECORD_VIDEO_NOTE = types.SendMessageRecordRoundAction - """User is recording a round video note.""" - - UPLOAD_VIDEO_NOTE = types.SendMessageUploadRoundAction - """User is uploading a round video note.""" - - @staticmethod - def from_string(action: str) -> "ChatAction": - for a in ChatAction: - if a.name.lower() == action.lower(): - return a - - raise ValueError("Invalid ChatAction: '{}'. Possible types are {}".format( - action, [x.name.lower() for x in ChatAction] - )) diff --git a/pyrogram/client/methods/messages/send_chat_action.py b/pyrogram/client/methods/messages/send_chat_action.py index 5c50c2cf..1d819747 100644 --- a/pyrogram/client/methods/messages/send_chat_action.py +++ b/pyrogram/client/methods/messages/send_chat_action.py @@ -18,17 +18,32 @@ from typing import Union -from pyrogram.api import functions -from pyrogram.client.ext import BaseClient, ChatAction +from pyrogram.api import functions, types +from pyrogram.client.ext import BaseClient +import json + + +class ChatAction: + TYPING = types.SendMessageTypingAction + UPLOAD_PHOTO = types.SendMessageUploadPhotoAction + RECORD_VIDEO = types.SendMessageRecordVideoAction + UPLOAD_VIDEO = types.SendMessageUploadVideoAction + RECORD_AUDIO = types.SendMessageRecordAudioAction + UPLOAD_AUDIO = types.SendMessageUploadAudioAction + UPLOAD_DOCUMENT = types.SendMessageUploadDocumentAction + FIND_LOCATION = types.SendMessageGeoLocationAction + RECORD_VIDEO_NOTE = types.SendMessageRecordRoundAction + UPLOAD_VIDEO_NOTE = types.SendMessageUploadRoundAction + PLAYING = types.SendMessageGamePlayAction + CHOOSE_CONTACT = types.SendMessageChooseContactAction + CANCEL = types.SendMessageCancelAction + + +POSSIBLE_VALUES = list(map(lambda x: x.lower(), filter(lambda x: not x.startswith("__"), ChatAction.__dict__.keys()))) class SendChatAction(BaseClient): - def send_chat_action( - self, - chat_id: Union[int, str], - action: Union[ChatAction, str], - progress: int = 0 - ): + def send_chat_action(self, chat_id: Union[int, str], action: str) -> bool: """Use this method when you need to tell the other party that something is happening on your side. Parameters: @@ -37,15 +52,13 @@ class SendChatAction(BaseClient): For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - action (:obj:`ChatAction` | ``str``): - Type of action to broadcast. - Choose one from the :class:`ChatAction` enumeration, - depending on what the user is about to receive. - You can also provide a string (e.g. "typing", "upload_photo", "record_audio", ...). - - progress (``int``, *optional*): - Progress of the upload process. - Currently useless because official clients don't seem to be handling this. + action (``str``): + Type of action to broadcast. Choose one, depending on what the user is about to receive: *"typing"* for + text messages, *"upload_photo"* for photos, *"record_video"* or *"upload_video"* for videos, + *"record_audio"* or *"upload_audio"* for audio files, *"upload_document"* for general files, + *"find_location"* for location data, *"record_video_note"* or *"upload_video_note"* for video notes, + *"choose_contact"* for contacts, *"playing"* for games or *"cancel"* to cancel any chat action currently + displayed. Returns: ``bool``: On success, True is returned. @@ -55,14 +68,14 @@ class SendChatAction(BaseClient): ValueError: In case the provided string is not a valid ChatAction. """ - # Resolve Enum type - if isinstance(action, str): - action = ChatAction.from_string(action).value - elif isinstance(action, ChatAction): - action = action.value + try: + action = ChatAction.__dict__[action.upper()] + except KeyError: + raise ValueError("Invalid chat action '{}'. Possible values are: {}".format( + action, json.dumps(POSSIBLE_VALUES, indent=4))) from None if "Upload" in action.__name__: - action = action(progress=progress) + action = action(progress=0) else: action = action() diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 648177d4..05ff94f3 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -22,7 +22,6 @@ from typing import List, Match, Union import pyrogram from pyrogram.api import types from pyrogram.errors import MessageIdsEmpty -from pyrogram.client.ext import ChatAction from pyrogram.client.types.input_media import InputMedia from .contact import Contact from .location import Location @@ -1077,11 +1076,7 @@ class Message(PyrogramType, Update): reply_markup=reply_markup ) - def reply_chat_action( - self, - action: Union[ChatAction, str], - progress: int = 0 - ) -> "Message": + def reply_chat_action(self, action: str) -> bool: """Bound method *reply_chat_action* of :obj:`Message`. Use as a shortcut for: @@ -1099,27 +1094,24 @@ class Message(PyrogramType, Update): message.reply_chat_action("typing") Parameters: - action (:obj:`ChatAction ` | ``str``): - Type of action to broadcast. - Choose one from the :class:`ChatAction ` enumeration, - depending on what the user is about to receive. - You can also provide a string (e.g. "typing", "upload_photo", "record_audio", ...). - - progress (``int``, *optional*): - Progress of the upload process. - Currently useless because official clients don't seem to be handling this. + action (``str``): + Type of action to broadcast. Choose one, depending on what the user is about to receive: *"typing"* for + text messages, *"upload_photo"* for photos, *"record_video"* or *"upload_video"* for videos, + *"record_audio"* or *"upload_audio"* for audio files, *"upload_document"* for general files, + *"find_location"* for location data, *"record_video_note"* or *"upload_video_note"* for video notes, + *"choose_contact"* for contacts, *"playing"* for games or *"cancel"* to cancel any chat action currently + displayed. Returns: - On success, True is returned. + ``bool``: On success, True is returned. Raises: RPCError: In case of a Telegram RPC error. - ``ValueError`` if the provided string is not a valid ChatAction. + ValueError: In case the provided string is not a valid chat action. """ return self._client.send_chat_action( chat_id=self.chat.id, - action=action, - progress=progress + action=action ) def reply_contact( From 92283d6cabe10ffa822a8db41587feb206761ddd Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 9 May 2019 05:55:44 +0200 Subject: [PATCH 040/202] Add timeout to Message.click --- .../methods/bots/request_callback_answer.py | 8 +- .../types/messages_and_media/message.py | 95 ++++++++++--------- 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/pyrogram/client/methods/bots/request_callback_answer.py b/pyrogram/client/methods/bots/request_callback_answer.py index b1d8884f..7e57b39b 100644 --- a/pyrogram/client/methods/bots/request_callback_answer.py +++ b/pyrogram/client/methods/bots/request_callback_answer.py @@ -27,7 +27,8 @@ class RequestCallbackAnswer(BaseClient): self, chat_id: Union[int, str], message_id: int, - callback_data: bytes + callback_data: bytes, + timeout: int = 10 ): """Use this method to request a callback answer from bots. This is the equivalent of clicking an inline button containing callback data. @@ -44,6 +45,9 @@ class RequestCallbackAnswer(BaseClient): callback_data (``bytes``): Callback data associated with the inline button you want to get the answer from. + timeout (``int``, *optional*): + Timeout in seconds. + Returns: The answer containing info useful for clients to display a notification at the top of the chat screen or as an alert. @@ -59,5 +63,5 @@ class RequestCallbackAnswer(BaseClient): data=callback_data ), retries=0, - timeout=10 + timeout=timeout ) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 05ff94f3..a4d759c8 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -21,8 +21,8 @@ from typing import List, Match, Union import pyrogram from pyrogram.api import types -from pyrogram.errors import MessageIdsEmpty from pyrogram.client.types.input_media import InputMedia +from pyrogram.errors import MessageIdsEmpty from .contact import Contact from .location import Location from .message_entity import MessageEntity @@ -2725,10 +2725,10 @@ class Message(PyrogramType, Update): revoke=revoke ) - def click(self, x: int or str, y: int = None, quote: bool = None): + def click(self, x: int or str, y: int = None, quote: bool = None, timeout: int = 10): """Bound method *click* of :obj:`Message`. - Use as a shortcut for clicking a button attached to the message instead of. + Use as a shortcut for clicking a button attached to the message instead of: - Clicking inline buttons: @@ -2773,58 +2773,67 @@ class Message(PyrogramType, Update): If ``True``, the message will be sent as a reply to this message. Defaults to ``True`` in group chats and ``False`` in private chats. + timeout (``int``, *optional*): + Timeout in seconds. + Returns: - - The result of *request_callback_answer()* in case of inline callback button clicks. - - The result of *reply()* in case of normal button clicks. - - A string in case the inline button is an URL, switch_inline_query or switch_inline_query_current_chat - button. + - The result of :meth:`request_callback_answer() ` in case of + inline callback button clicks. + - The result of :meth:`reply() ` in case of normal button clicks. + - A string in case the inline button is a URL, a *switch_inline_query* or a + *switch_inline_query_current_chat* button. Raises: RPCError: In case of a Telegram RPC error. - ``ValueError``: If the provided index or position is out of range or the button label was not found - ``TimeoutError``: If, after clicking an inline button, the bot fails to answer within 10 seconds + ValueError: In case the provided index or position is out of range or the button label was not found. + TimeoutError: In case, after clicking an inline button, the bot fails to answer within the timeout. """ + if isinstance(self.reply_markup, pyrogram.ReplyKeyboardMarkup): - return self.reply(x, quote=quote) + keyboard = self.reply_markup.keyboard + is_inline = False elif isinstance(self.reply_markup, pyrogram.InlineKeyboardMarkup): - if isinstance(x, int) and y is None: - try: - button = [ - button - for row in self.reply_markup.inline_keyboard - for button in row - ][x] - except IndexError: - raise ValueError("The button at index {} doesn't exist".format(x)) from None - elif isinstance(x, int) and isinstance(y, int): - try: - button = self.reply_markup.inline_keyboard[y][x] - except IndexError: - raise ValueError("The button at position ({}, {}) doesn't exist".format(x, y)) from None - elif isinstance(x, str): - x = x.encode("utf-16", "surrogatepass").decode("utf-16") + keyboard = self.reply_markup.inline_keyboard + is_inline = True + else: + raise ValueError("The message doesn't contain any keyboard") - try: - button = [ - button - for row in self.reply_markup.inline_keyboard - for button in row - if x == button.text - ][0] - except IndexError: - raise ValueError( - "The button with label '{}' doesn't exists".format( - x.encode("unicode_escape").decode() - ) - ) from None - else: - raise ValueError("Invalid arguments") + if isinstance(x, int) and y is None: + try: + button = [ + button + for row in keyboard + for button in row + ][x] + except IndexError: + raise ValueError("The button at index {} doesn't exist".format(x)) + elif isinstance(x, int) and isinstance(y, int): + try: + button = keyboard[y][x] + except IndexError: + raise ValueError("The button at position ({}, {}) doesn't exist".format(x, y)) + elif isinstance(x, str) and y is None: + label = x.encode("utf-16", "surrogatepass").decode("utf-16") + try: + button = [ + button + for row in keyboard + for button in row + if label == button.text + ][0] + except IndexError: + raise ValueError("The button with label '{}' doesn't exists".format(x)) + else: + raise ValueError("Invalid arguments") + + if is_inline: if button.callback_data: return self._client.request_callback_answer( chat_id=self.chat.id, message_id=self.message_id, - callback_data=button.callback_data + callback_data=button.callback_data, + timeout=timeout ) elif button.url: return button.url @@ -2835,7 +2844,7 @@ class Message(PyrogramType, Update): else: raise ValueError("This button is not supported yet") else: - raise ValueError("The message doesn't contain any keyboard") + self.reply(button, quote=quote) def download( self, From 559eaa2d033b45daea44b858c80edf930b408602 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 9 May 2019 14:37:02 +0200 Subject: [PATCH 041/202] Use lower-case names for pages --- .../{BadRequest.rst => bad-request.rst} | 0 docs/source/errors/{Flood.rst => flood.rst} | 0 .../errors/{Forbidden.rst => forbidden.rst} | 0 ...verError.rst => internal-server-error.rst} | 0 .../{NotAcceptable.rst => not-acceptable.rst} | 0 .../errors/{SeeOther.rst => see-other.rst} | 0 .../{Unauthorized.rst => unauthorized.rst} | 0 .../{UnknownError.rst => unknown-error.rst} | 0 docs/source/index.rst | 38 +++++++++---------- .../{Decorators.rst => decorators.rst} | 0 .../pyrogram/{Errors.rst => errors.rst} | 16 ++++---- .../pyrogram/{Filters.rst => filters.rst} | 0 .../pyrogram/{Handlers.rst => handlers.rst} | 0 docs/source/pyrogram/index.rst | 12 +++--- .../pyrogram/{Methods.rst => methods.rst} | 0 docs/source/pyrogram/{Types.rst => types.rst} | 0 .../{AdvancedUsage.rst => advanced-usage.rst} | 0 ...thorization.rst => auto-authorization.rst} | 0 ...tsInteraction.rst => bots-interaction.rst} | 0 .../{Changelog.rst => changelog.rst} | 0 ...urationFile.rst => configuration-file.rst} | 0 ...izeSessions.rst => customize-sessions.rst} | 0 .../{ErrorHandling.rst => error-handling.rst} | 0 ...{MoreOnUpdates.rst => more-on-updates.rst} | 0 .../{SmartPlugins.rst => smart-plugins.rst} | 0 .../{SOCKS5Proxy.rst => socks5-proxy.rst} | 0 .../{TestServers.rst => test-servers.rst} | 0 ...TextFormatting.rst => text-formatting.rst} | 0 .../resources/{TgCrypto.rst => tgcrypto.rst} | 0 ...UpdateHandling.rst => update-handling.rst} | 0 .../{UsingFilters.rst => using-filters.rst} | 0 .../{VoiceCalls.rst => voice-calls.rst} | 0 .../{Installation.rst => installation.rst} | 0 docs/source/start/{Setup.rst => setup.rst} | 0 docs/source/start/{Usage.rst => usage.rst} | 0 35 files changed, 33 insertions(+), 33 deletions(-) rename docs/source/errors/{BadRequest.rst => bad-request.rst} (100%) rename docs/source/errors/{Flood.rst => flood.rst} (100%) rename docs/source/errors/{Forbidden.rst => forbidden.rst} (100%) rename docs/source/errors/{InternalServerError.rst => internal-server-error.rst} (100%) rename docs/source/errors/{NotAcceptable.rst => not-acceptable.rst} (100%) rename docs/source/errors/{SeeOther.rst => see-other.rst} (100%) rename docs/source/errors/{Unauthorized.rst => unauthorized.rst} (100%) rename docs/source/errors/{UnknownError.rst => unknown-error.rst} (100%) rename docs/source/pyrogram/{Decorators.rst => decorators.rst} (100%) rename docs/source/pyrogram/{Errors.rst => errors.rst} (57%) rename docs/source/pyrogram/{Filters.rst => filters.rst} (100%) rename docs/source/pyrogram/{Handlers.rst => handlers.rst} (100%) rename docs/source/pyrogram/{Methods.rst => methods.rst} (100%) rename docs/source/pyrogram/{Types.rst => types.rst} (100%) rename docs/source/resources/{AdvancedUsage.rst => advanced-usage.rst} (100%) rename docs/source/resources/{AutoAuthorization.rst => auto-authorization.rst} (100%) rename docs/source/resources/{BotsInteraction.rst => bots-interaction.rst} (100%) rename docs/source/resources/{Changelog.rst => changelog.rst} (100%) rename docs/source/resources/{ConfigurationFile.rst => configuration-file.rst} (100%) rename docs/source/resources/{CustomizeSessions.rst => customize-sessions.rst} (100%) rename docs/source/resources/{ErrorHandling.rst => error-handling.rst} (100%) rename docs/source/resources/{MoreOnUpdates.rst => more-on-updates.rst} (100%) rename docs/source/resources/{SmartPlugins.rst => smart-plugins.rst} (100%) rename docs/source/resources/{SOCKS5Proxy.rst => socks5-proxy.rst} (100%) rename docs/source/resources/{TestServers.rst => test-servers.rst} (100%) rename docs/source/resources/{TextFormatting.rst => text-formatting.rst} (100%) rename docs/source/resources/{TgCrypto.rst => tgcrypto.rst} (100%) rename docs/source/resources/{UpdateHandling.rst => update-handling.rst} (100%) rename docs/source/resources/{UsingFilters.rst => using-filters.rst} (100%) rename docs/source/resources/{VoiceCalls.rst => voice-calls.rst} (100%) rename docs/source/start/{Installation.rst => installation.rst} (100%) rename docs/source/start/{Setup.rst => setup.rst} (100%) rename docs/source/start/{Usage.rst => usage.rst} (100%) diff --git a/docs/source/errors/BadRequest.rst b/docs/source/errors/bad-request.rst similarity index 100% rename from docs/source/errors/BadRequest.rst rename to docs/source/errors/bad-request.rst diff --git a/docs/source/errors/Flood.rst b/docs/source/errors/flood.rst similarity index 100% rename from docs/source/errors/Flood.rst rename to docs/source/errors/flood.rst diff --git a/docs/source/errors/Forbidden.rst b/docs/source/errors/forbidden.rst similarity index 100% rename from docs/source/errors/Forbidden.rst rename to docs/source/errors/forbidden.rst diff --git a/docs/source/errors/InternalServerError.rst b/docs/source/errors/internal-server-error.rst similarity index 100% rename from docs/source/errors/InternalServerError.rst rename to docs/source/errors/internal-server-error.rst diff --git a/docs/source/errors/NotAcceptable.rst b/docs/source/errors/not-acceptable.rst similarity index 100% rename from docs/source/errors/NotAcceptable.rst rename to docs/source/errors/not-acceptable.rst diff --git a/docs/source/errors/SeeOther.rst b/docs/source/errors/see-other.rst similarity index 100% rename from docs/source/errors/SeeOther.rst rename to docs/source/errors/see-other.rst diff --git a/docs/source/errors/Unauthorized.rst b/docs/source/errors/unauthorized.rst similarity index 100% rename from docs/source/errors/Unauthorized.rst rename to docs/source/errors/unauthorized.rst diff --git a/docs/source/errors/UnknownError.rst b/docs/source/errors/unknown-error.rst similarity index 100% rename from docs/source/errors/UnknownError.rst rename to docs/source/errors/unknown-error.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index bd62547e..623c503e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -77,30 +77,30 @@ To get started, press the Next button. :hidden: :caption: Quick Start - start/Installation - start/Setup - start/Usage + start/installation + start/setup + start/usage .. toctree:: :hidden: :caption: Resources - resources/UpdateHandling - resources/UsingFilters - resources/MoreOnUpdates - resources/ConfigurationFile - resources/SmartPlugins - resources/AutoAuthorization - resources/CustomizeSessions - resources/TgCrypto - resources/TextFormatting - resources/SOCKS5Proxy - resources/BotsInteraction - resources/ErrorHandling - resources/TestServers - resources/AdvancedUsage - resources/VoiceCalls - resources/Changelog + resources/update-handling + resources/using-filters + resources/more-on-updates + resources/configuration-file + resources/smart-plugins + resources/auto-authorization + resources/customize-sessions + resources/tgcrypto + resources/text-formatting + resources/socks5-proxy + resources/bots-interaction + resources/error-handling + resources/test-servers + resources/advanced-usage + resources/voice-calls + resources/changelog .. toctree:: :hidden: diff --git a/docs/source/pyrogram/Decorators.rst b/docs/source/pyrogram/decorators.rst similarity index 100% rename from docs/source/pyrogram/Decorators.rst rename to docs/source/pyrogram/decorators.rst diff --git a/docs/source/pyrogram/Errors.rst b/docs/source/pyrogram/errors.rst similarity index 57% rename from docs/source/pyrogram/Errors.rst rename to docs/source/pyrogram/errors.rst index 6c816a72..68313bdd 100644 --- a/docs/source/pyrogram/Errors.rst +++ b/docs/source/pyrogram/errors.rst @@ -18,11 +18,11 @@ All the Pyrogram errors listed here live inside the ``errors`` sub-package. :members: .. toctree:: - ../errors/SeeOther - ../errors/BadRequest - ../errors/Unauthorized - ../errors/Forbidden - ../errors/NotAcceptable - ../errors/Flood - ../errors/InternalServerError - ../errors/UnknownError + ../errors/see-other + ../errors/bad-request + ../errors/unauthorized + ../errors/forbidden + ../errors/not-acceptable + ../errors/flood + ../errors/internal-server-error + ../errors/unknown-error diff --git a/docs/source/pyrogram/Filters.rst b/docs/source/pyrogram/filters.rst similarity index 100% rename from docs/source/pyrogram/Filters.rst rename to docs/source/pyrogram/filters.rst diff --git a/docs/source/pyrogram/Handlers.rst b/docs/source/pyrogram/handlers.rst similarity index 100% rename from docs/source/pyrogram/Handlers.rst rename to docs/source/pyrogram/handlers.rst diff --git a/docs/source/pyrogram/index.rst b/docs/source/pyrogram/index.rst index 5546070d..3dc4227b 100644 --- a/docs/source/pyrogram/index.rst +++ b/docs/source/pyrogram/index.rst @@ -9,12 +9,12 @@ after the well established Telegram Bot API methods, thus offering a familiar lo .. toctree:: :maxdepth: 1 - Types - Methods - Handlers - Decorators - Filters - Errors + types + methods + handlers + decorators + filters + errors .. autoclass:: pyrogram.Client() diff --git a/docs/source/pyrogram/Methods.rst b/docs/source/pyrogram/methods.rst similarity index 100% rename from docs/source/pyrogram/Methods.rst rename to docs/source/pyrogram/methods.rst diff --git a/docs/source/pyrogram/Types.rst b/docs/source/pyrogram/types.rst similarity index 100% rename from docs/source/pyrogram/Types.rst rename to docs/source/pyrogram/types.rst diff --git a/docs/source/resources/AdvancedUsage.rst b/docs/source/resources/advanced-usage.rst similarity index 100% rename from docs/source/resources/AdvancedUsage.rst rename to docs/source/resources/advanced-usage.rst diff --git a/docs/source/resources/AutoAuthorization.rst b/docs/source/resources/auto-authorization.rst similarity index 100% rename from docs/source/resources/AutoAuthorization.rst rename to docs/source/resources/auto-authorization.rst diff --git a/docs/source/resources/BotsInteraction.rst b/docs/source/resources/bots-interaction.rst similarity index 100% rename from docs/source/resources/BotsInteraction.rst rename to docs/source/resources/bots-interaction.rst diff --git a/docs/source/resources/Changelog.rst b/docs/source/resources/changelog.rst similarity index 100% rename from docs/source/resources/Changelog.rst rename to docs/source/resources/changelog.rst diff --git a/docs/source/resources/ConfigurationFile.rst b/docs/source/resources/configuration-file.rst similarity index 100% rename from docs/source/resources/ConfigurationFile.rst rename to docs/source/resources/configuration-file.rst diff --git a/docs/source/resources/CustomizeSessions.rst b/docs/source/resources/customize-sessions.rst similarity index 100% rename from docs/source/resources/CustomizeSessions.rst rename to docs/source/resources/customize-sessions.rst diff --git a/docs/source/resources/ErrorHandling.rst b/docs/source/resources/error-handling.rst similarity index 100% rename from docs/source/resources/ErrorHandling.rst rename to docs/source/resources/error-handling.rst diff --git a/docs/source/resources/MoreOnUpdates.rst b/docs/source/resources/more-on-updates.rst similarity index 100% rename from docs/source/resources/MoreOnUpdates.rst rename to docs/source/resources/more-on-updates.rst diff --git a/docs/source/resources/SmartPlugins.rst b/docs/source/resources/smart-plugins.rst similarity index 100% rename from docs/source/resources/SmartPlugins.rst rename to docs/source/resources/smart-plugins.rst diff --git a/docs/source/resources/SOCKS5Proxy.rst b/docs/source/resources/socks5-proxy.rst similarity index 100% rename from docs/source/resources/SOCKS5Proxy.rst rename to docs/source/resources/socks5-proxy.rst diff --git a/docs/source/resources/TestServers.rst b/docs/source/resources/test-servers.rst similarity index 100% rename from docs/source/resources/TestServers.rst rename to docs/source/resources/test-servers.rst diff --git a/docs/source/resources/TextFormatting.rst b/docs/source/resources/text-formatting.rst similarity index 100% rename from docs/source/resources/TextFormatting.rst rename to docs/source/resources/text-formatting.rst diff --git a/docs/source/resources/TgCrypto.rst b/docs/source/resources/tgcrypto.rst similarity index 100% rename from docs/source/resources/TgCrypto.rst rename to docs/source/resources/tgcrypto.rst diff --git a/docs/source/resources/UpdateHandling.rst b/docs/source/resources/update-handling.rst similarity index 100% rename from docs/source/resources/UpdateHandling.rst rename to docs/source/resources/update-handling.rst diff --git a/docs/source/resources/UsingFilters.rst b/docs/source/resources/using-filters.rst similarity index 100% rename from docs/source/resources/UsingFilters.rst rename to docs/source/resources/using-filters.rst diff --git a/docs/source/resources/VoiceCalls.rst b/docs/source/resources/voice-calls.rst similarity index 100% rename from docs/source/resources/VoiceCalls.rst rename to docs/source/resources/voice-calls.rst diff --git a/docs/source/start/Installation.rst b/docs/source/start/installation.rst similarity index 100% rename from docs/source/start/Installation.rst rename to docs/source/start/installation.rst diff --git a/docs/source/start/Setup.rst b/docs/source/start/setup.rst similarity index 100% rename from docs/source/start/Setup.rst rename to docs/source/start/setup.rst diff --git a/docs/source/start/Usage.rst b/docs/source/start/usage.rst similarity index 100% rename from docs/source/start/Usage.rst rename to docs/source/start/usage.rst From 570d7ca15e5f47073bb6561fbe5c96e9b7afda35 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 16:06:45 +0200 Subject: [PATCH 042/202] Create bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..25c58a29 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug report +about: Create a bug report to help us improve +labels: "bug" +--- + +## Summary +A clear and concise description of the problem. + +## Steps to Reproduce +A minimal, complete and verifiable example (https://stackoverflow.com/help/mcve). + +## Expected Results +A description of what should happen. + +## Actual Results +A description of what actually happened. + +## Environment info +- **OS**: [e.g. Linux/macOS/Windows] +- **Python version**: [e.g. 3.7.2] +- **Pyrogram version**: [e.g. 0.12.0/develop] + +## Extra details +Other details about the problem. + +
Logs: +Insert logs here (if necessary) +
From 3827581bd90d01d550c13bfef8dd851ebab5f4a7 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 16:09:19 +0200 Subject: [PATCH 043/202] Create feature_request.md --- .github/ISSUE_TEMPLATE/feature_request.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..fda9f94c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,5 @@ +--- +name: Question +about: Ask a question +labels: "question" +--- From 077031572767a2a035617a46527addaa669c883e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 16:11:29 +0200 Subject: [PATCH 044/202] Create CONTRIBUTING.md --- .github/CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CONTRIBUTING.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..e721fd98 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1 @@ +# How to Contribute From e4b0a78f1aa3dec6291ef8d18792ce3089f2a13a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 16:14:10 +0200 Subject: [PATCH 045/202] Docs revamp. Part 2 --- .../{pyrogram/index.rst => core/client.rst} | 12 +- docs/source/{pyrogram => core}/decorators.rst | 0 docs/source/{pyrogram => core}/errors.rst | 0 docs/source/{pyrogram => core}/filters.rst | 0 docs/source/{pyrogram => core}/handlers.rst | 4 +- docs/source/{pyrogram => core}/methods.rst | 4 +- docs/source/{pyrogram => core}/types.rst | 4 +- docs/source/index.rst | 111 +++++++++------- docs/source/intro/auth.rst | 68 ++++++++++ .../installation.rst => intro/install.rst} | 8 +- docs/source/intro/setup.rst | 61 +++++++++ docs/source/intro/start.rst | 45 +++++++ docs/source/resources/update-handling.rst | 72 ----------- docs/source/start/setup.rst | 120 ------------------ docs/source/start/usage.rst | 51 -------- .../{resources => topics}/advanced-usage.rst | 0 .../auto-authorization.rst | 0 .../bots-interaction.rst | 0 .../{resources => topics}/changelog.rst | 0 .../configuration-file.rst | 0 .../customize-sessions.rst | 0 .../{resources => topics}/error-handling.rst | 0 .../{resources => topics}/more-on-updates.rst | 6 +- .../{resources => topics}/smart-plugins.rst | 0 .../{resources => topics}/socks5-proxy.rst | 0 .../{resources => topics}/test-servers.rst | 0 .../{resources => topics}/text-formatting.rst | 0 .../source/{resources => topics}/tgcrypto.rst | 0 docs/source/topics/update-handling.rst | 109 ++++++++++++++++ docs/source/topics/usage.rst | 85 +++++++++++++ .../{resources => topics}/using-filters.rst | 0 .../{resources => topics}/voice-calls.rst | 0 pyrogram/client/methods/users/get_users.py | 2 +- 33 files changed, 447 insertions(+), 315 deletions(-) rename docs/source/{pyrogram/index.rst => core/client.rst} (76%) rename docs/source/{pyrogram => core}/decorators.rst (100%) rename docs/source/{pyrogram => core}/errors.rst (100%) rename docs/source/{pyrogram => core}/filters.rst (100%) rename docs/source/{pyrogram => core}/handlers.rst (97%) rename docs/source/{pyrogram => core}/methods.rst (98%) rename docs/source/{pyrogram => core}/types.rst (99%) create mode 100644 docs/source/intro/auth.rst rename docs/source/{start/installation.rst => intro/install.rst} (95%) create mode 100644 docs/source/intro/setup.rst create mode 100644 docs/source/intro/start.rst delete mode 100644 docs/source/resources/update-handling.rst delete mode 100644 docs/source/start/setup.rst delete mode 100644 docs/source/start/usage.rst rename docs/source/{resources => topics}/advanced-usage.rst (100%) rename docs/source/{resources => topics}/auto-authorization.rst (100%) rename docs/source/{resources => topics}/bots-interaction.rst (100%) rename docs/source/{resources => topics}/changelog.rst (100%) rename docs/source/{resources => topics}/configuration-file.rst (100%) rename docs/source/{resources => topics}/customize-sessions.rst (100%) rename docs/source/{resources => topics}/error-handling.rst (100%) rename docs/source/{resources => topics}/more-on-updates.rst (94%) rename docs/source/{resources => topics}/smart-plugins.rst (100%) rename docs/source/{resources => topics}/socks5-proxy.rst (100%) rename docs/source/{resources => topics}/test-servers.rst (100%) rename docs/source/{resources => topics}/text-formatting.rst (100%) rename docs/source/{resources => topics}/tgcrypto.rst (100%) create mode 100644 docs/source/topics/update-handling.rst create mode 100644 docs/source/topics/usage.rst rename docs/source/{resources => topics}/using-filters.rst (100%) rename docs/source/{resources => topics}/voice-calls.rst (100%) diff --git a/docs/source/pyrogram/index.rst b/docs/source/core/client.rst similarity index 76% rename from docs/source/pyrogram/index.rst rename to docs/source/core/client.rst index 3dc4227b..43524cb3 100644 --- a/docs/source/pyrogram/index.rst +++ b/docs/source/core/client.rst @@ -6,15 +6,7 @@ In this section you can find a detailed description of the Pyrogram package and :class:`Client ` is the main class. It exposes easy-to-use methods that are named after the well established Telegram Bot API methods, thus offering a familiar look to Bot developers. -.. toctree:: - :maxdepth: 1 - - types - methods - handlers - decorators - filters - errors - +Client +------ .. autoclass:: pyrogram.Client() diff --git a/docs/source/pyrogram/decorators.rst b/docs/source/core/decorators.rst similarity index 100% rename from docs/source/pyrogram/decorators.rst rename to docs/source/core/decorators.rst diff --git a/docs/source/pyrogram/errors.rst b/docs/source/core/errors.rst similarity index 100% rename from docs/source/pyrogram/errors.rst rename to docs/source/core/errors.rst diff --git a/docs/source/pyrogram/filters.rst b/docs/source/core/filters.rst similarity index 100% rename from docs/source/pyrogram/filters.rst rename to docs/source/core/filters.rst diff --git a/docs/source/pyrogram/handlers.rst b/docs/source/core/handlers.rst similarity index 97% rename from docs/source/pyrogram/handlers.rst rename to docs/source/core/handlers.rst index 7140897b..08d40039 100644 --- a/docs/source/pyrogram/handlers.rst +++ b/docs/source/core/handlers.rst @@ -1,5 +1,5 @@ -Handlers -======== +Update Handlers +=============== Handlers are used to instruct Pyrogram about which kind of updates you'd like to handle with your callback functions. diff --git a/docs/source/pyrogram/methods.rst b/docs/source/core/methods.rst similarity index 98% rename from docs/source/pyrogram/methods.rst rename to docs/source/core/methods.rst index d0387790..24210c2f 100644 --- a/docs/source/pyrogram/methods.rst +++ b/docs/source/core/methods.rst @@ -1,5 +1,5 @@ -Methods -======= +Available Methods +================= All Pyrogram methods listed here are bound to a :obj:`Client ` instance. diff --git a/docs/source/pyrogram/types.rst b/docs/source/core/types.rst similarity index 99% rename from docs/source/pyrogram/types.rst rename to docs/source/core/types.rst index 52e97107..710a772d 100644 --- a/docs/source/pyrogram/types.rst +++ b/docs/source/core/types.rst @@ -1,5 +1,5 @@ -Types -===== +Available Types +=============== All Pyrogram types listed here are accessible through the main package directly. diff --git a/docs/source/index.rst b/docs/source/index.rst index 623c503e..74f68433 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,16 +13,21 @@ Welcome to Pyrogram Telegram MTProto API Framework for Python
- - Documentation + + GitHub + • + + Community + + • Changelog • - - Community + + PyPI
@@ -49,64 +54,69 @@ Welcome to Pyrogram app.run() -Welcome to Pyrogram's Documentation! Here you can find resources for learning how to use the framework. -Contents are organized into self-contained topics and can be accessed from the sidebar, or by following them in order -using the Next button at the end of each page. But first, here's a brief overview of what is this all about. - -About ------ - **Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and C. It enables you to easily create custom apps using both user and bot identities (bot API alternative) via the `MTProto API`_. -Features --------- +How the documentation is organized +---------------------------------- -- **Easy**: You can install Pyrogram with pip and start building your applications right away. -- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way. -- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C. -- **Documented**: Pyrogram API methods, types and public interfaces are well documented. -- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. -- **Updated**, to the latest Telegram API version, currently Layer 97 on top of `MTProto 2.0`_. -- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code. -- **Comprehensive**: Execute any advanced action an official client is able to do, and even more. +Contents are organized into self-contained topics and can be accessed from the sidebar, or by following them in order +using the Next button at the end of each page. -To get started, press the Next button. +Relevant Pages +^^^^^^^^^^^^^^ + +- `Quick Start`_ - Concise steps to get you started as fast as possible. +- `API Usage`_ - Guide on how to use Pyrogram's API. +- `Update Handling`_ - Guide on how to handle Telegram updates. +- Client_ - Reference details about the Client class. +- Types_ - All the available Pyrogram types. +- Methods_ - All the available Pyrogram methods. + +**To get started, press the Next button** .. toctree:: :hidden: - :caption: Quick Start + :caption: Introduction - start/installation - start/setup - start/usage + intro/start + intro/install + intro/setup + intro/auth .. toctree:: :hidden: - :caption: Resources + :caption: Topic Guides - resources/update-handling - resources/using-filters - resources/more-on-updates - resources/configuration-file - resources/smart-plugins - resources/auto-authorization - resources/customize-sessions - resources/tgcrypto - resources/text-formatting - resources/socks5-proxy - resources/bots-interaction - resources/error-handling - resources/test-servers - resources/advanced-usage - resources/voice-calls - resources/changelog + topics/usage + topics/update-handling + topics/using-filters + topics/more-on-updates + topics/configuration-file + topics/smart-plugins + topics/auto-authorization + topics/customize-sessions + topics/tgcrypto + topics/text-formatting + topics/socks5-proxy + topics/bots-interaction + topics/error-handling + topics/test-servers + topics/advanced-usage + topics/voice-calls + topics/changelog .. toctree:: :hidden: - :caption: Main Package + :caption: API Reference - pyrogram/index + core/client + core/types + core/methods + core/handlers + core/decorators + core/filters + core/errors .. toctree:: :hidden: @@ -115,7 +125,12 @@ To get started, press the Next button. functions/index types/index -.. _`Telegram`: https://telegram.org +.. _Telegram: https://telegram.org .. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto -.. _`MTProto API`: https://core.telegram.org/api#telegram-api -.. _`MTProto 2.0`: https://core.telegram.org/mtproto +.. _MTProto API: https://core.telegram.org/api#telegram-api +.. _Quick Start: intro/start.html +.. _API Usage: topics/usage.html +.. _Update Handling: topics/update-handling.html +.. _Client: core/client.html +.. _Types: core/types.html +.. _Methods: core/methods diff --git a/docs/source/intro/auth.rst b/docs/source/intro/auth.rst new file mode 100644 index 00000000..86217137 --- /dev/null +++ b/docs/source/intro/auth.rst @@ -0,0 +1,68 @@ +Authorization +============= + +Once a `project is set up`_, you will still have to follow a few steps before you can actually use Pyrogram to make +API calls. This section provides all the information you need in order to authorize yourself as user or a bot. + +User Authorization +------------------ + +In order to use the API, Telegram requires that users be authorized via their phone numbers. +Pyrogram automatically manages this access, all you need to do is create an instance of the +:class:`Client ` class by passing to it a ``session_name`` of your choice (e.g.: "my_account") and call +the :meth:`run() ` method: + +.. code-block:: python + + from pyrogram import Client + + app = Client("my_account") + app.run() + +This starts an interactive shell asking you to input your **phone number** (including your `Country Code`_) and the +**phone code** you will receive in your devices that are already authorized or via SMS: + +.. code-block:: text + + Enter phone number: +39********** + Is "+39**********" correct? (y/n): y + Enter phone code: 32768 + Logged in successfully as Dan + +After successfully authorizing yourself, a new file called ``my_account.session`` will be created allowing Pyrogram to +execute API calls with your identity. This file will be loaded again when you restart your app, and as long as you +keep the session alive, Pyrogram won't ask you again to enter your phone number. + +.. important:: + + Your ``*.session`` files are personal and must be kept secret. + +.. note:: + + The code above does nothing except asking for credentials and keeping the client online, hit ``CTRL+C`` now to stop + your application and keep reading. + +Bot Authorization +----------------- + +Bots are a special kind of users that are authorized via their tokens (instead of phone numbers), which are created by +the `Bot Father`_. Bot tokens replace the users' phone numbers only — you still need to +`configure a Telegram API key `_ with Pyrogram, even when using bots. + +The authorization process is automatically managed. All you need to do is choose a ``session_name`` (can be anything, +usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named +after the session name, which will be ``pyrogrambot.session`` for the example below. + +.. code-block:: python + + from pyrogram import Client + + app = Client( + "my_bot", + bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" + ) + app.run() + +.. _project is set up: setup.html +.. _Country Code: https://en.wikipedia.org/wiki/List_of_country_calling_codes +.. _Bot Father: https://t.me/botfather \ No newline at end of file diff --git a/docs/source/start/installation.rst b/docs/source/intro/install.rst similarity index 95% rename from docs/source/start/installation.rst rename to docs/source/intro/install.rst index 079e1b1f..161c7d61 100644 --- a/docs/source/start/installation.rst +++ b/docs/source/intro/install.rst @@ -1,8 +1,8 @@ -Installation -============ +Install Guide +============= Being a Python library, **Pyrogram** requires Python to be installed in your system. -We recommend using the latest version of Python 3 and pip. +We recommend using the latest versions of both Python 3 and pip. - Get **Python 3** from https://www.python.org/downloads/ (or with your package manager) - Get **pip** by following the instructions at https://pip.pypa.io/en/latest/installing/. @@ -88,5 +88,5 @@ If no error shows up you are good to go. >>> pyrogram.__version__ '0.12.0' -.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto +.. _TgCrypto: ../resources/tgcrypto.html .. _`Github repo`: http://github.com/pyrogram/pyrogram diff --git a/docs/source/intro/setup.rst b/docs/source/intro/setup.rst new file mode 100644 index 00000000..b318654d --- /dev/null +++ b/docs/source/intro/setup.rst @@ -0,0 +1,61 @@ +Project Setup +============= + +We have just `installed Pyrogram`_. In this page we'll discuss what you need to do in order to set up a project with +the library. Let's see how it's done. + +API Keys +-------- + +The very first step requires you to obtain a valid Telegram API key (API id/hash pair): + +#. Visit https://my.telegram.org/apps and log in with your Telegram Account. +#. Fill out the form to register a new Telegram application. +#. Done! The API key consists of two parts: **api_id** and **api_hash**. + +.. important:: + + The API key is personal and must be kept secret. + +.. note:: + + The API key is unique for each user, but defines a token for a Telegram *application* you are going to build. This + means that you are able to authorize multiple users (and bots too) to access the Telegram database through the + MTProto API by a single API key. + +Configuration +------------- + +Having the API key from the `previous step <#api-keys>`_ in handy, we can now begin to configure a Pyrogram project. +There are two ways to do so, and you can choose what fits better for you: + +- First option (recommended): create a new ``config.ini`` file at the root of your working directory, copy-paste the + following and replace the **api_id** and **api_hash** values with your own. This is the preferred method because + allows you to keep your credentials out of your code without having to deal with how to load them: + + .. code-block:: ini + + [pyrogram] + api_id = 12345 + api_hash = 0123456789abcdef0123456789abcdef + +- Alternatively, you can pass your API key to Pyrogram by simply using the *api_id* and *api_hash* parameters of the + Client class. This way you can have full control on how to store and load your credentials (e.g.:, you can load the + credentials from the environment variables and directly pass the values into Pyrogram): + + .. code-block:: python + + from pyrogram import Client + + app = Client( + "my_account", + api_id=12345, + api_hash="0123456789abcdef0123456789abcdef" + ) + +.. note:: + + To keep code snippets clean and concise, from now on it is assumed you are making use of the ``config.ini`` file, + thus, the *api_id* and *api_hash* parameters usage won't be shown anymore. + +.. _installed Pyrogram: install.html diff --git a/docs/source/intro/start.rst b/docs/source/intro/start.rst new file mode 100644 index 00000000..d6a8d5e3 --- /dev/null +++ b/docs/source/intro/start.rst @@ -0,0 +1,45 @@ +Quick Start +=========== + +The next few steps serve as a quick start for all new Pyrogrammers that want to get something done as fast as possible! + +Get Pyrogram Real Fast +---------------------- + +1. Install Pyrogram with ``pip3 install -U pyrogram``. + +2. Get your own Telegram API key from https://my.telegram.org/apps. + +3. Open your best text editor and paste the following: + + .. code-block:: python + + from pyrogram import Client + + api_id = 12345 + api_hash = "0123456789abcdef0123456789abcdef" + + with Client("my_account", api_id, api_hash) as app: + app.send_message("me", "Greetings from **Pyrogram**!") + +4. Replace *api_id* and *api_hash* values with your own. + +5. Save the file as ``pyro.py``. + +6. Run the script with ``python3 pyro.py`` + +7. Follow the instructions on your terminal to login. + +8. Watch Pyrogram send a message to yourself. + +9. Join our `community `_. + +10. Say, "hi!". + +Enjoy the API +------------- + +That was just a quick overview that barely scratched the surface! +In the next few pages of the introduction, we'll take a much more in-depth look of what we have just done. + +Feeling eager? You can take a shortcut to `API Usage <../topics/usage.html>`_ and come back later to learn some more details. diff --git a/docs/source/resources/update-handling.rst b/docs/source/resources/update-handling.rst deleted file mode 100644 index ed0ad909..00000000 --- a/docs/source/resources/update-handling.rst +++ /dev/null @@ -1,72 +0,0 @@ -Update Handling -=============== - -Let's now dive right into the core of the framework. - -Updates are events that happen in your Telegram account (incoming messages, new channel posts, new members join, ...) -and are handled by registering one or more callback functions in your app using `Handlers <../pyrogram/Handlers.html>`_. - -Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback -function will be called. - -Registering an Handler ----------------------- - -To explain how handlers work let's have a look at the most used one, the -:obj:`MessageHandler `, which will be in charge for handling :obj:`Message ` -updates coming from all around your chats. Every other handler shares the same setup logic; you should not have troubles -settings them up once you learn from this section. - -Using add_handler() -------------------- - -The :meth:`add_handler() ` method takes any handler instance that wraps around your defined -callback function and registers it in your Client. Here's a full example that prints out the content of a message as -soon as it arrives: - -.. code-block:: python - - from pyrogram import Client, MessageHandler - - - def my_function(client, message): - print(message) - - - app = Client("my_account") - - my_handler = MessageHandler(my_function) - app.add_handler(my_handler) - - app.run() - -Using Decorators ----------------- - -A much nicer way to register a MessageHandler is by decorating your callback function with the -:meth:`on_message() ` decorator, which will still make use of add_handler() under the hood. - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - - @app.on_message() - def my_handler(client, message): - print(message) - - - app.run() - - -.. note:: - - Due to how these decorators work in Pyrogram, they will wrap your defined callback function in a tuple consisting of - ``(handler, group)``; this will be the value held by your function identifier (e.g.: *my_function* from the example - above). - - In case, for some reason, you want to get your own function back after it has been decorated, you need to access - ``my_function[0].callback``, that is, the *callback* field of the *handler* object which is the first element in the - tuple. \ No newline at end of file diff --git a/docs/source/start/setup.rst b/docs/source/start/setup.rst deleted file mode 100644 index 45a40d16..00000000 --- a/docs/source/start/setup.rst +++ /dev/null @@ -1,120 +0,0 @@ -Setup -===== - -Once you successfully `installed Pyrogram`_, you will still have to follow a few steps before you can actually use -the library to make API calls. This section provides all the information you need in order to set up a project -with Pyrogram. - -API Keys --------- - -The very first step requires you to obtain a valid Telegram API key (API id/hash pair). -If you already have one you can skip this step, otherwise: - -#. Visit https://my.telegram.org/apps and log in with your Telegram Account. -#. Fill out the form to register a new Telegram application. -#. Done. The API key consists of two parts: **App api_id** and **App api_hash**. - -.. important:: - - This API key is personal and must be kept secret. - -Configuration -------------- - -The API key obtained in the `previous step <#api-keys>`_ defines a token for your application allowing you to access -the Telegram database using the MTProto API — **it is therefore required for all authorizations of both users and bots**. - -Having it handy, it's time to configure your Pyrogram project. There are two ways to do so, and you can choose what -fits better for you: - -- Create a new ``config.ini`` file at the root of your working directory, copy-paste the following and replace the - **api_id** and **api_hash** values with your own. This is the preferred method because allows you to keep your - credentials out of your code without having to deal with how to load them: - - .. code-block:: ini - - [pyrogram] - api_id = 12345 - api_hash = 0123456789abcdef0123456789abcdef - -- Alternatively, you can pass your API key to Pyrogram by simply using the *api_id* and *api_hash* parameters of the - Client class. This way you can have full control on how to store and load your credentials: - - .. code-block:: python - - from pyrogram import Client - - app = Client( - "my_account", - api_id=12345, - api_hash="0123456789abcdef0123456789abcdef" - ) - -.. note:: - - From now on, the code snippets assume you are using the ``config.ini`` file, thus they won't show the *api_id* and - *api_hash* parameters usage to keep them as clean as possible. - -User Authorization ------------------- - -In order to use the API, Telegram requires that users be authorized via their phone numbers. -Pyrogram automatically manages this access, all you need to do is create an instance of the -:class:`Client ` class by passing to it a ``session_name`` of your choice (e.g.: "my_account") and call -the :meth:`run() ` method: - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - app.run() - -This starts an interactive shell asking you to input your **phone number** (including your `Country Code`_) -and the **phone code** you will receive: - -.. code-block:: text - - Enter phone number: +39********** - Is "+39**********" correct? (y/n): y - Enter phone code: 32768 - Logged in successfully as Dan - -After successfully authorizing yourself, a new file called ``my_account.session`` will be created allowing Pyrogram -executing API calls with your identity. This file will be loaded again when you restart your app, and as long as you -keep the session alive, Pyrogram won't ask you again to enter your phone number. - -.. important:: - - Your ``*.session`` files are personal and must be kept secret. - -.. note:: - - The code above does nothing except asking for credentials and keeping the client online, hit ``CTRL+C`` now to stop - your application and keep reading. - -Bot Authorization ------------------ - -Bots are a special kind of users that are authorized via their tokens (instead of phone numbers), which are created by -BotFather_. Bot tokens replace the users' phone numbers only — you still need to -`configure a Telegram API key <#configuration>`_ with Pyrogram, even when using bots. - -The authorization process is automatically managed. All you need to do is choose a ``session_name`` (can be anything, -usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named -after the session name, which will be ``pyrogrambot.session`` for the example below. - -.. code-block:: python - - from pyrogram import Client - - app = Client( - "pyrogrambot", - bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" - ) - app.run() - -.. _installed Pyrogram: Installation.html -.. _`Country Code`: https://en.wikipedia.org/wiki/List_of_country_calling_codes -.. _BotFather: https://t.me/botfather \ No newline at end of file diff --git a/docs/source/start/usage.rst b/docs/source/start/usage.rst deleted file mode 100644 index 35ae79a0..00000000 --- a/docs/source/start/usage.rst +++ /dev/null @@ -1,51 +0,0 @@ -Usage -===== - -Having your `project set up`_ and your account authorized_, it's time to start playing with the API. Let's start! - -High-level API --------------- - -The easiest and recommended way to interact with Telegram is via the high-level Pyrogram methods_ and types_, which are -named after the `Telegram Bot API`_. - -Here's a simple example: - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - app.start() - - print(app.get_me()) - app.send_message("me", "Hi there! I'm using **Pyrogram**") - app.send_location("me", 51.500729, -0.124583) - app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") - - app.stop() - -You can also use Pyrogram in a context manager with the ``with`` statement. The Client will automatically -:meth:`start ` and :meth:`stop ` gracefully, even in case of unhandled -exceptions in your code: - -.. code-block:: python - - from pyrogram import Client - - app = Client("my_account") - - with app: - print(app.get_me()) - app.send_message("me", "Hi there! I'm using **Pyrogram**") - app.send_location("me", 51.500729, -0.124583) - app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") - -More examples on `GitHub `_. - -.. _project set up: Setup.html -.. _authorized: Setup.html#user-authorization -.. _Telegram Bot API: https://core.telegram.org/bots/api -.. _methods: ../pyrogram/Client.html#messages -.. _types: ../pyrogram/Types.html diff --git a/docs/source/resources/advanced-usage.rst b/docs/source/topics/advanced-usage.rst similarity index 100% rename from docs/source/resources/advanced-usage.rst rename to docs/source/topics/advanced-usage.rst diff --git a/docs/source/resources/auto-authorization.rst b/docs/source/topics/auto-authorization.rst similarity index 100% rename from docs/source/resources/auto-authorization.rst rename to docs/source/topics/auto-authorization.rst diff --git a/docs/source/resources/bots-interaction.rst b/docs/source/topics/bots-interaction.rst similarity index 100% rename from docs/source/resources/bots-interaction.rst rename to docs/source/topics/bots-interaction.rst diff --git a/docs/source/resources/changelog.rst b/docs/source/topics/changelog.rst similarity index 100% rename from docs/source/resources/changelog.rst rename to docs/source/topics/changelog.rst diff --git a/docs/source/resources/configuration-file.rst b/docs/source/topics/configuration-file.rst similarity index 100% rename from docs/source/resources/configuration-file.rst rename to docs/source/topics/configuration-file.rst diff --git a/docs/source/resources/customize-sessions.rst b/docs/source/topics/customize-sessions.rst similarity index 100% rename from docs/source/resources/customize-sessions.rst rename to docs/source/topics/customize-sessions.rst diff --git a/docs/source/resources/error-handling.rst b/docs/source/topics/error-handling.rst similarity index 100% rename from docs/source/resources/error-handling.rst rename to docs/source/topics/error-handling.rst diff --git a/docs/source/resources/more-on-updates.rst b/docs/source/topics/more-on-updates.rst similarity index 94% rename from docs/source/resources/more-on-updates.rst rename to docs/source/topics/more-on-updates.rst index f3658c6e..84086622 100644 --- a/docs/source/resources/more-on-updates.rst +++ b/docs/source/topics/more-on-updates.rst @@ -151,9 +151,9 @@ Continue Propagation As opposed to `stopping the update propagation <#stop-propagation>`_ and also as an alternative to the `handler groups <#handler-groups>`_, you can signal the internal dispatcher to continue the update propagation within -**the same group** regardless of the next handler's filters. This allows you to register multiple handlers with -overlapping filters in the same group; to let the dispatcher process the next handler you can do *one* of the following -in each handler you want to grant permission to continue: +**the same group** despite having conflicting filters in the next registered handler. This allows you to register +multiple handlers with overlapping filters in the same group; to let the dispatcher process the next handler you can do +*one* of the following in each handler you want to grant permission to continue: - Call the update's bound-method ``.continue_propagation()`` (preferred way). - Manually ``raise ContinuePropagation`` exception (more suitable for raw updates only). diff --git a/docs/source/resources/smart-plugins.rst b/docs/source/topics/smart-plugins.rst similarity index 100% rename from docs/source/resources/smart-plugins.rst rename to docs/source/topics/smart-plugins.rst diff --git a/docs/source/resources/socks5-proxy.rst b/docs/source/topics/socks5-proxy.rst similarity index 100% rename from docs/source/resources/socks5-proxy.rst rename to docs/source/topics/socks5-proxy.rst diff --git a/docs/source/resources/test-servers.rst b/docs/source/topics/test-servers.rst similarity index 100% rename from docs/source/resources/test-servers.rst rename to docs/source/topics/test-servers.rst diff --git a/docs/source/resources/text-formatting.rst b/docs/source/topics/text-formatting.rst similarity index 100% rename from docs/source/resources/text-formatting.rst rename to docs/source/topics/text-formatting.rst diff --git a/docs/source/resources/tgcrypto.rst b/docs/source/topics/tgcrypto.rst similarity index 100% rename from docs/source/resources/tgcrypto.rst rename to docs/source/topics/tgcrypto.rst diff --git a/docs/source/topics/update-handling.rst b/docs/source/topics/update-handling.rst new file mode 100644 index 00000000..c32bc2be --- /dev/null +++ b/docs/source/topics/update-handling.rst @@ -0,0 +1,109 @@ +Update Handling +=============== + +Calling `API methods`_ sequentially is cool, but how to react when, for example, a new message arrives? This page deals +with updates and how to handle them in Pyrogram. Let's have a look at how they work. + +First, let's define what are these updates. Updates are simply events that happen in your Telegram account (incoming +messages, new members join, button presses, etc...), which are meant to notify you about a new specific state that +changed. These updates are handled by registering one or more callback functions in your app using +`Handlers <../pyrogram/Handlers.html>`_. + +Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback +function will be called and its body executed. + +Registering an Handler +---------------------- + +To explain how handlers work let's have a look at the most used one, the +:obj:`MessageHandler `, which will be in charge for handling :obj:`Message ` +updates coming from all around your chats. Every other handler shares the same setup logic; you should not have troubles +settings them up once you learn from this section. + +Using add_handler() +------------------- + +The :meth:`add_handler() ` method takes any handler instance that wraps around your defined +callback function and registers it in your Client. Here's a full example that prints out the content of a message as +soon as it arrives: + +.. code-block:: python + + from pyrogram import Client, MessageHandler + + + def my_function(client, message): + print(message) + + + app = Client("my_account") + + my_handler = MessageHandler(my_function) + app.add_handler(my_handler) + + app.run() + +Let's examine these four new pieces. First one: a callback function we defined which accepts two arguments - +*(client, message)*. This will be the function that gets executed every time a new message arrives and Pyrogram will +call that function by passing the client instance and the new message instance as argument. + +.. code-block:: python + + def my_function(client, message): + print(message) + +Second one: the :obj:`MessageHandler `. This object tells Pyrogram the function we defined +above must only handle updates that are in form of a :obj:`Message `: + +.. code-block:: python + + my_handler = MessageHandler(my_function) + +Third: the method :meth:`add_handler() `. This method is used to actually register the +handler and let Pyrogram know it needs to be taken into consideration when new updates arrive and the dispatching phase +begins. + +.. code-block:: python + + app.add_handler(my_handler) + +Last one, the :meth:`run() ` method. What this does is simply calling +:meth:`start() ` and a special method :meth:`idle() ` that keeps your main +scripts alive until you press ``CTRL+C``; the client will be automatically stopped after that. + +.. code-block:: python + + app.run() + +Using Decorators +---------------- + +All of the above will become quite verbose, especially in case you have lots of handlers to register. A much nicer way +to do so is by decorating your callback function with the :meth:`on_message() ` decorator. + +.. code-block:: python + + from pyrogram import Client + + app = Client("my_account") + + + @app.on_message() + def my_handler(client, message): + print(message) + + + app.run() + + +.. note:: + + Due to how these decorators work in Pyrogram, they will wrap your defined callback function in a tuple consisting of + ``(handler, group)``; this will be the value held by your function identifier (e.g.: *my_function* from the example + above). + + In case, for some reason, you want to get your own function back after it has been decorated, you need to access + ``my_function[0].callback``, that is, the *callback* field of the *handler* object which is the first element in the + tuple, accessed by bracket notation *[0]*. + +.. _API methods: usage.html \ No newline at end of file diff --git a/docs/source/topics/usage.rst b/docs/source/topics/usage.rst new file mode 100644 index 00000000..34f57876 --- /dev/null +++ b/docs/source/topics/usage.rst @@ -0,0 +1,85 @@ +API Usage +========= + +At this point, we have successfully `installed Pyrogram`_ and authorized_ our account and we are now pointing towards +the core of the library. It's time to start playing with the API! + +Make API Method Calls +--------------------- + +Making API method calls with Pyrogram is very simple. +Here's an example we are going to examine: + +.. code-block:: python + + from pyrogram import Client + + app = Client("my_account") + + app.start() + + print(app.get_me()) + app.send_message("me", "Hi, it's me!") + app.send_location("me", 51.500729, -0.124583) + app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") + + app.stop() + +Let's begin by importing the Client class from the Pyrogram package: + +.. code-block:: python + + from pyrogram import Client + +Now instantiate a new Client object, "my_account" is a session name of your choice: + +.. code-block:: python + + app = Client("my_account") + +To actually make use of any method, the client has to be started: + +.. code-block:: python + + app.start() + +Now, you can call any method you like: + +.. code-block:: python + + print(app.get_me()) # Print information about yourself + + # Send messages to yourself: + app.send_message("me", "Hi!") # Text message + app.send_location("me", 51.500729, -0.124583) # Location + app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") # Sticker + +Finally, when done, simply stop the client: + +.. code-block:: python + + app.stop() + +Context Manager +--------------- + +You can also use Pyrogram's Client in a context manager with the ``with`` statement. The client will automatically +:meth:`start ` and :meth:`stop ` gracefully, even in case of unhandled +exceptions in your code. The example above can be therefore rewritten in a much nicer way, this way: + +.. code-block:: python + + from pyrogram import Client + + app = Client("my_account") + + with app: + print(app.get_me()) + app.send_message("me", "Hi there! I'm using **Pyrogram**") + app.send_location("me", 51.500729, -0.124583) + app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") + +More examples can be found on `GitHub `_. + +.. _installed Pyrogram: ../intro/install.html +.. _authorized: ../intro/setup.html diff --git a/docs/source/resources/using-filters.rst b/docs/source/topics/using-filters.rst similarity index 100% rename from docs/source/resources/using-filters.rst rename to docs/source/topics/using-filters.rst diff --git a/docs/source/resources/voice-calls.rst b/docs/source/topics/voice-calls.rst similarity index 100% rename from docs/source/resources/voice-calls.rst rename to docs/source/topics/voice-calls.rst diff --git a/pyrogram/client/methods/users/get_users.py b/pyrogram/client/methods/users/get_users.py index b1314349..bbcdebae 100644 --- a/pyrogram/client/methods/users/get_users.py +++ b/pyrogram/client/methods/users/get_users.py @@ -26,7 +26,7 @@ from ...ext import BaseClient class GetUsers(BaseClient): def get_users( self, - user_ids: Iterable[Union[int, str]] + user_ids: Union[Iterable[Union[int, str]], int, str] ) -> Union["pyrogram.User", List["pyrogram.User"]]: """Use this method to get information about a user. You can retrieve up to 200 users at once. From 9c505b3c26ea54c07de02490a4cffdd9d0d468d9 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 16:19:59 +0200 Subject: [PATCH 046/202] Create question.md Swapped feature_requests with question. This commit also fixes the mess --- .github/ISSUE_TEMPLATE/feature_request.md | 6 +++--- .github/ISSUE_TEMPLATE/question.md | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/question.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index fda9f94c..6f6807b6 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,5 +1,5 @@ --- -name: Question -about: Ask a question -labels: "question" +name: Feature request +about: Suggest a new feature or enhancement +labels: "enhancement" --- diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 00000000..fda9f94c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,5 @@ +--- +name: Question +about: Ask a question +labels: "question" +--- From 64fa7ee5d62cbe2cdb2dced77f761c4f060eebf0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 16:23:12 +0200 Subject: [PATCH 047/202] Create CODE_OF_CONDUCT.md --- .github/CODE_OF_CONDUCT.md | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..27bb02a3 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at admin@pyrogram.ml. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq From 030b5261d20c39f519e7500b01343c80aab06e04 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 16:55:20 +0200 Subject: [PATCH 048/202] Remove duplicated entry Thanks Colin --- docs/source/core/methods.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/source/core/methods.rst b/docs/source/core/methods.rst index 24210c2f..609a38a8 100644 --- a/docs/source/core/methods.rst +++ b/docs/source/core/methods.rst @@ -151,7 +151,6 @@ Bots send_game set_game_score get_game_high_scores - answer_inline_query .. Utilities --------- @@ -267,4 +266,3 @@ Bots .. automethod:: pyrogram.Client.send_game() .. automethod:: pyrogram.Client.set_game_score() .. automethod:: pyrogram.Client.get_game_high_scores() -.. automethod:: pyrogram.Client.answer_inline_query() \ No newline at end of file From f16ed40532059bf3ab2f06673bbcca7aeae7396b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 10 May 2019 17:15:46 +0200 Subject: [PATCH 049/202] Update examples --- examples/README.md | 16 ++++++++-------- examples/{keyboards.py => bot_keyboards.py} | 2 +- .../{chat_members.py => get_chat_members.py} | 0 examples/{dialogs.py => get_dialogs.py} | 2 +- examples/{history.py => get_history.py} | 0 examples/use_inline_bots.py | 13 +++++++++++++ examples/using_inline_bots.py | 17 ----------------- examples/{welcome.py => welcomebot.py} | 0 8 files changed, 23 insertions(+), 27 deletions(-) rename examples/{keyboards.py => bot_keyboards.py} (99%) rename examples/{chat_members.py => get_chat_members.py} (100%) rename examples/{dialogs.py => get_dialogs.py} (72%) rename examples/{history.py => get_history.py} (100%) create mode 100644 examples/use_inline_bots.py delete mode 100644 examples/using_inline_bots.py rename examples/{welcome.py => welcomebot.py} (100%) diff --git a/examples/README.md b/examples/README.md index 643fe56d..b8898a71 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,12 +12,12 @@ Example | Description ---: | :--- [**hello_world**](hello_world.py) | Demonstration of basic API usage [**echobot**](echobot.py) | Echo every private text message -[**welcome**](welcome.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat) -[**history**](history.py) | Get the full message history of a chat -[**chat_members**](chat_members.py) | Get all the members of a chat -[**dialogs**](dialogs.py) | Get all of your dialog chats -[**using_inline_bots**](using_inline_bots.py) | Query an inline bot (as user) and send a result to a chat -[**keyboards**](keyboards.py) | Send normal and inline keyboards using regular bots -[**callback_queries**](callback_queries.py) | Handle queries coming from inline button presses -[**inline_queries**](inline_queries.py) | Handle inline queries +[**welcomebot**](welcomebot.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat) +[**get_history**](get_history.py) | Get the full message history of a chat +[**get_chat_members**](get_chat_members.py) | Get all the members of a chat +[**get_dialogs**](get_dialogs.py) | Get all of your dialog chats +[**callback_queries**](callback_queries.py) | Handle callback queries (as bot) coming from inline button presses +[**inline_queries**](inline_queries.py) | Handle inline queries (as bot) and answer with results +[**use_inline_bots**](use_inline_bots.py) | Query an inline bot (as user) and send a result to a chat +[**bot_keyboards**](bot_keyboards.py) | Send normal and inline keyboards using regular bots [**raw_updates**](raw_updates.py) | Handle raw updates (old, should be avoided) diff --git a/examples/keyboards.py b/examples/bot_keyboards.py similarity index 99% rename from examples/keyboards.py rename to examples/bot_keyboards.py index 1a1140b6..4cbe8eaa 100644 --- a/examples/keyboards.py +++ b/examples/bot_keyboards.py @@ -1,4 +1,4 @@ -"""This example will show you how to send normal and inline keyboards. +"""This example will show you how to send normal and inline keyboards (as bot). You must log-in as a regular bot in order to send keyboards (use the token from @BotFather). Any attempt in sending keyboards with a user account will be simply ignored by the server. diff --git a/examples/chat_members.py b/examples/get_chat_members.py similarity index 100% rename from examples/chat_members.py rename to examples/get_chat_members.py diff --git a/examples/dialogs.py b/examples/get_dialogs.py similarity index 72% rename from examples/dialogs.py rename to examples/get_dialogs.py index 08c769e2..92da8834 100644 --- a/examples/dialogs.py +++ b/examples/get_dialogs.py @@ -1,4 +1,4 @@ -"""This example shows how to get the full dialogs list of a user.""" +"""This example shows how to get the full dialogs list (as user).""" from pyrogram import Client diff --git a/examples/history.py b/examples/get_history.py similarity index 100% rename from examples/history.py rename to examples/get_history.py diff --git a/examples/use_inline_bots.py b/examples/use_inline_bots.py new file mode 100644 index 00000000..5681df87 --- /dev/null +++ b/examples/use_inline_bots.py @@ -0,0 +1,13 @@ +"""This example shows how to query an inline bot (as user)""" + +from pyrogram import Client + +# Create a new Client +app = Client("my_account") + +with app: + # Get bot results for "Fuzz Universe" from the inline bot @vid + bot_results = app.get_inline_bot_results("vid", "Fuzz Universe") + + # Send the first result (bot_results.results[0]) to your own chat (Saved Messages) + app.send_inline_bot_result("me", bot_results.query_id, bot_results.results[0].id) diff --git a/examples/using_inline_bots.py b/examples/using_inline_bots.py deleted file mode 100644 index c3b48874..00000000 --- a/examples/using_inline_bots.py +++ /dev/null @@ -1,17 +0,0 @@ -"""This example shows how to query an inline bot""" - -from pyrogram import Client - -# Create a new Client -app = Client("my_account") - -# Start the Client -app.start() - -# Get bot results for "Fuzz Universe" from the inline bot @vid -bot_results = app.get_inline_bot_results("vid", "Fuzz Universe") -# Send the first result (bot_results.results[0]) to your own chat (Saved Messages) -app.send_inline_bot_result("me", bot_results.query_id, bot_results.results[0].id) - -# Stop the client -app.stop() diff --git a/examples/welcome.py b/examples/welcomebot.py similarity index 100% rename from examples/welcome.py rename to examples/welcomebot.py From cb2af5d05a9ddaa79c613cffdaab2464fec2e671 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 11 May 2019 16:40:56 +0200 Subject: [PATCH 050/202] Use a better qualified name for both raw types and functions --- compiler/api/compiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 992548fd..53b35929 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -463,7 +463,7 @@ def start(): ["{0}={0}".format(i[0]) for i in sorted_args if i != ("flags", "#")] ), slots=", ".join(['"{}"'.format(i[0]) for i in sorted_args if i != ("flags", "#")]), - qualname="{}{}".format("{}.".format(c.namespace) if c.namespace else "", c.name) + qualname="{}.{}{}".format(c.section, "{}.".format(c.namespace) if c.namespace else "", c.name) ) ) From f7cdc7ac3c664b6506c915c9e38885ecb4670ef0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 12 May 2019 00:18:59 +0200 Subject: [PATCH 051/202] Improve issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 34 +++++++++-------------- .github/ISSUE_TEMPLATE/feature_request.md | 13 +++++++-- .github/ISSUE_TEMPLATE/question.md | 14 ++++++++-- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 25c58a29..e0556d54 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,29 +1,21 @@ --- -name: Bug report -about: Create a bug report to help us improve +name: Bug Report +about: Create a bug report affecting the library labels: "bug" --- -## Summary + + +## Checklist +- [ ] I am sure the error is coming from Pyrogram's code and not elsewhere. +- [ ] I have searched in the issue tracker for similar bug reports, including closed ones. +- [ ] I ran `pip3 install -U https://github.com/pyrogram/pyrogram/archive/develop.zip` and reproduced the issue using the latest development version. + +## Description A clear and concise description of the problem. ## Steps to Reproduce -A minimal, complete and verifiable example (https://stackoverflow.com/help/mcve). +[A minimal, complete and verifiable example](https://stackoverflow.com/help/mcve). -## Expected Results -A description of what should happen. - -## Actual Results -A description of what actually happened. - -## Environment info -- **OS**: [e.g. Linux/macOS/Windows] -- **Python version**: [e.g. 3.7.2] -- **Pyrogram version**: [e.g. 0.12.0/develop] - -## Extra details -Other details about the problem. - -
Logs: -Insert logs here (if necessary) -
+## Traceback +The full traceback (if applicable). \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 6f6807b6..70a39192 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,5 +1,14 @@ --- -name: Feature request -about: Suggest a new feature or enhancement +name: Feature Request +about: Suggest ideas, new features or enhancements labels: "enhancement" --- + + + +## Checklist +- [ ] I believe the idea is awesome and would benefit the library. +- [ ] I have searched in the issue tracker for similar requests, including closed ones. + +## Description +A detailed description of the request. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index fda9f94c..737304d9 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,5 +1,15 @@ --- -name: Question -about: Ask a question +name: Ask Question +about: Ask a Pyrogram related question +title: For Q&A purposes, please read this template body labels: "question" --- + + + +# Important +This place is for issues about Pyrogram, it's **not a forum**. + +If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community by following the description in https://t.me/pyrogram. + +Thanks. \ No newline at end of file From eadda551c6f6c90a89b537c541df27903bcc24b2 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 12 May 2019 19:26:55 +0200 Subject: [PATCH 052/202] Docs revamp. Part 3 --- compiler/docs/compiler.py | 4 +- docs/source/api/client.rst | 7 + docs/source/{core => api}/decorators.rst | 0 docs/source/{core => api}/errors.rst | 4 +- docs/source/{core => api}/filters.rst | 4 +- docs/source/{core => api}/handlers.rst | 0 docs/source/{core => api}/methods.rst | 0 docs/source/{core => api}/types.rst | 0 docs/source/core/client.rst | 12 -- docs/source/index.rst | 128 +++++++++++------- docs/source/intro/start.rst | 8 +- .../error-handling.rst => start/errors.rst} | 3 +- .../{topics/usage.rst => start/invoking.rst} | 14 +- .../update-handling.rst => start/updates.rst} | 12 +- .../{auto-authorization.rst => auto-auth.rst} | 0 docs/source/topics/changelog.rst | 11 -- ...configuration-file.rst => config-file.rst} | 0 docs/source/topics/faq.rst | 107 +++++++++++++++ .../topics/{using-filters.rst => filters.rst} | 0 .../topics/{socks5-proxy.rst => proxy.rst} | 0 docs/source/topics/releases.rst | 13 ++ ...mize-sessions.rst => session-settings.rst} | 5 +- docs/source/topics/text-formatting.rst | 6 +- pyrogram/client/client.py | 4 +- setup.py | 2 +- 25 files changed, 235 insertions(+), 109 deletions(-) create mode 100644 docs/source/api/client.rst rename docs/source/{core => api}/decorators.rst (100%) rename docs/source/{core => api}/errors.rst (95%) rename docs/source/{core => api}/filters.rst (61%) rename docs/source/{core => api}/handlers.rst (100%) rename docs/source/{core => api}/methods.rst (100%) rename docs/source/{core => api}/types.rst (100%) delete mode 100644 docs/source/core/client.rst rename docs/source/{topics/error-handling.rst => start/errors.rst} (94%) rename docs/source/{topics/usage.rst => start/invoking.rst} (87%) rename docs/source/{topics/update-handling.rst => start/updates.rst} (87%) rename docs/source/topics/{auto-authorization.rst => auto-auth.rst} (100%) delete mode 100644 docs/source/topics/changelog.rst rename docs/source/topics/{configuration-file.rst => config-file.rst} (100%) create mode 100644 docs/source/topics/faq.rst rename docs/source/topics/{using-filters.rst => filters.rst} (100%) rename docs/source/topics/{socks5-proxy.rst => proxy.rst} (100%) create mode 100644 docs/source/topics/releases.rst rename docs/source/topics/{customize-sessions.rst => session-settings.rst} (97%) diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 6ea2240d..2c67e66c 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -21,7 +21,7 @@ import os import shutil HOME = "compiler/docs" -DESTINATION = "docs/source" +DESTINATION = "docs/source/telegram" FUNCTIONS_PATH = "pyrogram/api/functions" TYPES_PATH = "pyrogram/api/types" @@ -129,6 +129,6 @@ if "__main__" == __name__: FUNCTIONS_PATH = "../../pyrogram/api/functions" TYPES_PATH = "../../pyrogram/api/types" HOME = "." - DESTINATION = "../../docs/source" + DESTINATION = "../../docs/source/telegram" start() diff --git a/docs/source/api/client.rst b/docs/source/api/client.rst new file mode 100644 index 00000000..05c5cd0c --- /dev/null +++ b/docs/source/api/client.rst @@ -0,0 +1,7 @@ +Pyrogram Client +=============== + +The :class:`Client ` is the main class. It exposes easy-to-use methods that are named +after the well established Telegram Bot API methods, thus offering a familiar look to Bot developers. + +.. autoclass:: pyrogram.Client() diff --git a/docs/source/core/decorators.rst b/docs/source/api/decorators.rst similarity index 100% rename from docs/source/core/decorators.rst rename to docs/source/api/decorators.rst diff --git a/docs/source/core/errors.rst b/docs/source/api/errors.rst similarity index 95% rename from docs/source/core/errors.rst rename to docs/source/api/errors.rst index 68313bdd..51d1fcd3 100644 --- a/docs/source/core/errors.rst +++ b/docs/source/api/errors.rst @@ -1,5 +1,5 @@ -Errors -====== +RPC Errors +========== All the Pyrogram errors listed here live inside the ``errors`` sub-package. diff --git a/docs/source/core/filters.rst b/docs/source/api/filters.rst similarity index 61% rename from docs/source/core/filters.rst rename to docs/source/api/filters.rst index 091031ae..87faa801 100644 --- a/docs/source/core/filters.rst +++ b/docs/source/api/filters.rst @@ -1,5 +1,5 @@ -Filters -======= +Update Filters +============== .. autoclass:: pyrogram.Filters :members: diff --git a/docs/source/core/handlers.rst b/docs/source/api/handlers.rst similarity index 100% rename from docs/source/core/handlers.rst rename to docs/source/api/handlers.rst diff --git a/docs/source/core/methods.rst b/docs/source/api/methods.rst similarity index 100% rename from docs/source/core/methods.rst rename to docs/source/api/methods.rst diff --git a/docs/source/core/types.rst b/docs/source/api/types.rst similarity index 100% rename from docs/source/core/types.rst rename to docs/source/api/types.rst diff --git a/docs/source/core/client.rst b/docs/source/core/client.rst deleted file mode 100644 index 43524cb3..00000000 --- a/docs/source/core/client.rst +++ /dev/null @@ -1,12 +0,0 @@ -Pyrogram -======== - -In this section you can find a detailed description of the Pyrogram package and its API. - -:class:`Client ` is the main class. It exposes easy-to-use methods that are named -after the well established Telegram Bot API methods, thus offering a familiar look to Bot developers. - -Client ------- - -.. autoclass:: pyrogram.Client() diff --git a/docs/source/index.rst b/docs/source/index.rst index 74f68433..ae6a2fda 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -54,26 +54,54 @@ Welcome to Pyrogram app.run() -**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and C. -It enables you to easily create custom apps using both user and bot identities (bot API alternative) via the `MTProto API`_. +**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and +C. It enables you to easily create custom apps using both user and bot identities (bot API alternative) via the +`MTProto API`_. -How the documentation is organized +.. _Telegram: https://telegram.org +.. _MTProto API: https://core.telegram.org/api#telegram-api + +How the Documentation is Organized ---------------------------------- -Contents are organized into self-contained topics and can be accessed from the sidebar, or by following them in order -using the Next button at the end of each page. +Contents are organized into self-contained topics and can be all accessed from the sidebar, or by following them in +order using the Next button at the end of each page. Here below you can find a list of the most relevant pages. -Relevant Pages -^^^^^^^^^^^^^^ +Getting Started +^^^^^^^^^^^^^^^ -- `Quick Start`_ - Concise steps to get you started as fast as possible. -- `API Usage`_ - Guide on how to use Pyrogram's API. -- `Update Handling`_ - Guide on how to handle Telegram updates. -- Client_ - Reference details about the Client class. -- Types_ - All the available Pyrogram types. -- Methods_ - All the available Pyrogram methods. +- `Quick Start`_ - Overview to get you started as fast as possible. +- `Calling Methods`_ - How to use Pyrogram's API. +- `Handling Updates`_ - How to handle Telegram updates. +- `Error Handling`_ - How to handle API errors correctly. -**To get started, press the Next button** +.. _Quick Start: intro/start +.. _Calling Methods: start/invoking +.. _Handling Updates: start/updates +.. _Error Handling: start/errors + +API Reference +^^^^^^^^^^^^^ +- `Client Class`_ - Details about the Client class. +- `Available Methods`_ - A list of available high-level methods. +- `Available Types`_ - A list of available high-level types. + +.. _Client Class: core/client +.. _Available Methods: core/methods +.. _Available Types: core/types + +Topics +^^^^^^ + +- `Smart Plugins`_ - How to modularize your application. +- `Advanced Usage`_ - How to use Telegram's raw API. +- `Release Notes`_ - Release notes for Pyrogram releases. +- `Pyrogram FAQ`_ - Answers to common Pyrogram questions. + +.. _Smart Plugins: topics/smart-plugins +.. _Advanced Usage: topics/advanced-usage +.. _Release Notes: topics/releases +.. _Pyrogram FAQ: topics/faq .. toctree:: :hidden: @@ -82,55 +110,51 @@ Relevant Pages intro/start intro/install intro/setup - intro/auth .. toctree:: :hidden: - :caption: Topic Guides + :caption: Getting Started - topics/usage - topics/update-handling - topics/using-filters - topics/more-on-updates - topics/configuration-file - topics/smart-plugins - topics/auto-authorization - topics/customize-sessions - topics/tgcrypto - topics/text-formatting - topics/socks5-proxy - topics/bots-interaction - topics/error-handling - topics/test-servers - topics/advanced-usage - topics/voice-calls - topics/changelog + intro/auth + start/invoking + start/updates + start/errors .. toctree:: :hidden: :caption: API Reference - core/client - core/types - core/methods - core/handlers - core/decorators - core/filters - core/errors + api/client + api/methods + api/types + api/handlers + api/decorators + api/filters + api/errors + +.. toctree:: + :hidden: + :caption: Topic Guides + + topics/filters + topics/more-on-updates + topics/config-file + topics/smart-plugins + topics/auto-auth + topics/session-settings + topics/tgcrypto + topics/text-formatting + topics/proxy + topics/bots-interaction + topics/test-servers + topics/advanced-usage + topics/voice-calls + topics/releases + topics/faq .. toctree:: :hidden: :caption: Telegram API - functions/index - types/index - -.. _Telegram: https://telegram.org -.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto -.. _MTProto API: https://core.telegram.org/api#telegram-api -.. _Quick Start: intro/start.html -.. _API Usage: topics/usage.html -.. _Update Handling: topics/update-handling.html -.. _Client: core/client.html -.. _Types: core/types.html -.. _Methods: core/methods + telegram/functions/index + telegram/types/index diff --git a/docs/source/intro/start.rst b/docs/source/intro/start.rst index d6a8d5e3..7d6f0150 100644 --- a/docs/source/intro/start.rst +++ b/docs/source/intro/start.rst @@ -32,7 +32,7 @@ Get Pyrogram Real Fast 8. Watch Pyrogram send a message to yourself. -9. Join our `community `_. +9. Join our `community`_. 10. Say, "hi!". @@ -42,4 +42,8 @@ Enjoy the API That was just a quick overview that barely scratched the surface! In the next few pages of the introduction, we'll take a much more in-depth look of what we have just done. -Feeling eager? You can take a shortcut to `API Usage <../topics/usage.html>`_ and come back later to learn some more details. +Feeling eager? You can take a shortcut to `Calling Methods`_ and come back later to learn some more +details. + +.. _community: //t.me/pyrogramchat +.. _Calling Methods: ../start/invoking \ No newline at end of file diff --git a/docs/source/topics/error-handling.rst b/docs/source/start/errors.rst similarity index 94% rename from docs/source/topics/error-handling.rst rename to docs/source/start/errors.rst index 7e87b94a..d05206c9 100644 --- a/docs/source/topics/error-handling.rst +++ b/docs/source/start/errors.rst @@ -16,8 +16,7 @@ There are many errors that Telegram could return, but they all fall in one of th As stated above, there are really many (too many) errors, and in case Pyrogram does not know anything yet about a specific one, it raises a special :obj:`520 Unknown Error ` exception and logs it -in the ``unknown_errors.txt`` file. Users are invited to report these unknown errors; in later versions of Pyrogram -some kind of automatic error reporting module might be implemented. +in the ``unknown_errors.txt`` file. Users are invited to report these unknown errors. Examples -------- diff --git a/docs/source/topics/usage.rst b/docs/source/start/invoking.rst similarity index 87% rename from docs/source/topics/usage.rst rename to docs/source/start/invoking.rst index 34f57876..c27e86c3 100644 --- a/docs/source/topics/usage.rst +++ b/docs/source/start/invoking.rst @@ -1,14 +1,10 @@ -API Usage -========= +Calling Methods +=============== -At this point, we have successfully `installed Pyrogram`_ and authorized_ our account and we are now pointing towards -the core of the library. It's time to start playing with the API! +At this point, we have successfully `installed Pyrogram`_ and authorized_ our account; we are now pointing towards the +core of the library. It's time to start playing with the API! -Make API Method Calls ---------------------- - -Making API method calls with Pyrogram is very simple. -Here's an example we are going to examine: +Making API method calls with Pyrogram is very simple. Here's an example we are going to examine: .. code-block:: python diff --git a/docs/source/topics/update-handling.rst b/docs/source/start/updates.rst similarity index 87% rename from docs/source/topics/update-handling.rst rename to docs/source/start/updates.rst index c32bc2be..0dcb08ad 100644 --- a/docs/source/topics/update-handling.rst +++ b/docs/source/start/updates.rst @@ -1,12 +1,12 @@ -Update Handling -=============== +Handling Updates +================ Calling `API methods`_ sequentially is cool, but how to react when, for example, a new message arrives? This page deals -with updates and how to handle them in Pyrogram. Let's have a look at how they work. +with updates and how to handle such events in Pyrogram. Let's have a look at how they work. -First, let's define what are these updates. Updates are simply events that happen in your Telegram account (incoming -messages, new members join, button presses, etc...), which are meant to notify you about a new specific state that -changed. These updates are handled by registering one or more callback functions in your app using +First, let's define what are these updates. As hinted already, updates are simply events that happen in your Telegram +account (incoming messages, new members join, button presses, etc...), which are meant to notify you about a new +specific state that changed. These updates are handled by registering one or more callback functions in your app using `Handlers <../pyrogram/Handlers.html>`_. Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback diff --git a/docs/source/topics/auto-authorization.rst b/docs/source/topics/auto-auth.rst similarity index 100% rename from docs/source/topics/auto-authorization.rst rename to docs/source/topics/auto-auth.rst diff --git a/docs/source/topics/changelog.rst b/docs/source/topics/changelog.rst deleted file mode 100644 index 732a1311..00000000 --- a/docs/source/topics/changelog.rst +++ /dev/null @@ -1,11 +0,0 @@ -Changelog -========= - -Currently, all Pyrogram release notes live inside the GitHub repository web page: -https://github.com/pyrogram/pyrogram/releases - -(You will be automatically redirected in 10 seconds.) - -.. raw:: html - - \ No newline at end of file diff --git a/docs/source/topics/configuration-file.rst b/docs/source/topics/config-file.rst similarity index 100% rename from docs/source/topics/configuration-file.rst rename to docs/source/topics/config-file.rst diff --git a/docs/source/topics/faq.rst b/docs/source/topics/faq.rst new file mode 100644 index 00000000..f647e261 --- /dev/null +++ b/docs/source/topics/faq.rst @@ -0,0 +1,107 @@ +Pyrogram FAQ +============ + +This FAQ page provides answers to common questions about Pyrogram and, to some extent, Telegram in general. + +.. contents:: Contents + :backlinks: none + :local: + +What is Pyrogram? +----------------- + +**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and +C. It enables you to easily create custom applications using both user and bot identities (bot API alternative) via the +`MTProto API`_ with the Python programming language. + +.. _Telegram: https://telegram.org +.. _MTProto API: https://core.telegram.org/api#telegram-api + +What does "Pyrogram" mean? +-------------------------- + +The word "Pyrogram" is composed by **pyro**, which comes from the Greek word *πῦρ (pyr)*, meaning fire, and **gram**, +from *Telegram*. The word *pyro* itself is built from *Python*, **py** for short, and the suffix **ro** to come up with +the word *fire*, which also inspired the project logo. + +How old is Pyrogram? +-------------------- + +Pyrogram was first released on December 12, 2017. The actual work on the framework began roughly three months prior the +initial public release on `GitHub`_. + +.. _GitHub: + +Why do I need an API key for bots? +---------------------------------- + +Requests against the official bot API endpoint are made via JSON/HTTP, but are handled by a backend application that +implements the MTProto protocol -- just like Pyrogram -- and uses its own API key, which is always required, but hidden +to the public. + +.. figure:: https://i.imgur.com/C108qkX.png + :align: center + +Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to +identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone +number only. + +I started a client but nothing happens! +--------------------------------------- + +If you are connecting from Russia, China or Iran `you need a proxy`_, because Telegram could be partially or +totally blocked in those countries. + +Another possible cause might be network issues, either yours or Telegram's. To confirm this, add the following code on +the top of your script and run it again. You should see some error mentioning a socket timeout or an unreachable network +in a bunch of seconds: + +.. code-block:: python + + import logging + logging.basicConfig(level=logging.INFO) + +|bug report| + +.. _you need a proxy: proxy + +I keep getting [400 PEER_ID_INVALID] error! +------------------------------------------- + +The error in question is ``[400 PEER_ID_INVALID]: The id/access_hash combination is invalid``, and could mean several +things: + +- 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). + +|bug report| + +.. |bug report| replace:: + + **Note:** If you really believe this should not happen, kindly open a `Bug Report`_. + +.. _Bug Report: https://github.com/pyrogram/pyrogram/issues/new?labels=bug&template=bug_report.md + +My account has been deactivated/limited! +---------------------------------------- + +First of all, you should understand that Telegram wants to be a safe place for people to stay in, and to pursue this +goal there are automatic protection systems running to prevent flood and spam, as well as a moderation team of humans +who reviews reports. + +**Pyrogram is a tool at your commands; it only does what you tell it to do, the rest is up to you.** + +Having said that, here's how a list of what Telegram definitely doesn't like: + +- Flood, abusing the API. +- Spam, sending unsolicited messages or adding people to unwanted groups and channels. +- Virtual/VoIP and cheap real numbers, because they are relatively easy to get and likely used for spam/flood. + +However, you might be right, and your account was deactivated/limited without any reason. This could happen because of +mistakes by either the automatic systems or a moderator. In such cases you can kindly email Telegram at +recover@telegram.org, contact `@smstelegram`_ on Twitter or use `this form`_. + +.. _@smstelegram: https://twitter.com/smstelegram +.. _this form: https://telegram.org/support \ No newline at end of file diff --git a/docs/source/topics/using-filters.rst b/docs/source/topics/filters.rst similarity index 100% rename from docs/source/topics/using-filters.rst rename to docs/source/topics/filters.rst diff --git a/docs/source/topics/socks5-proxy.rst b/docs/source/topics/proxy.rst similarity index 100% rename from docs/source/topics/socks5-proxy.rst rename to docs/source/topics/proxy.rst diff --git a/docs/source/topics/releases.rst b/docs/source/topics/releases.rst new file mode 100644 index 00000000..6c3b5b75 --- /dev/null +++ b/docs/source/topics/releases.rst @@ -0,0 +1,13 @@ +Release Notes +============= + +Release notes for Pyrogram releases will describe what's new in each version, and will also make you aware of any +backwards-incompatible changes made in that version. + +When upgrading to a new version of Pyrogram, you will need to check all the breaking changes in order to find +incompatible code in your application, but also to take advantage of new features and improvements. + +.. note:: + + Currently, all Pyrogram release notes live inside the GitHub repository web page: + https://github.com/pyrogram/pyrogram/releases. diff --git a/docs/source/topics/customize-sessions.rst b/docs/source/topics/session-settings.rst similarity index 97% rename from docs/source/topics/customize-sessions.rst rename to docs/source/topics/session-settings.rst index 77765287..47c6872e 100644 --- a/docs/source/topics/customize-sessions.rst +++ b/docs/source/topics/session-settings.rst @@ -1,5 +1,5 @@ -Customize Sessions -================== +Session Settings +================ As you may probably know, Telegram allows users (and bots) having more than one session (authorizations) registered in the system at the same time. @@ -8,7 +8,6 @@ Briefly explaining, sessions are simply new logins in your account. They can be app (or by invoking `GetAuthorizations <../functions/account/GetAuthorizations.html>`_ with Pyrogram). They store some useful information such as the client who's using them and from which country and IP address. - .. figure:: https://i.imgur.com/lzGPCdZ.png :width: 70% :align: center diff --git a/docs/source/topics/text-formatting.rst b/docs/source/topics/text-formatting.rst index 0ab08694..535fec31 100644 --- a/docs/source/topics/text-formatting.rst +++ b/docs/source/topics/text-formatting.rst @@ -11,7 +11,7 @@ Beside bold, italic, and pre-formatted code, **Pyrogram does also support inline Markdown Style -------------- -To use this mode, pass :obj:`MARKDOWN ` or "markdown" in the *parse_mode* field when using +To use this mode, pass "markdown" in the *parse_mode* field when using :obj:`send_message() `. Use the following syntax in your message: .. code-block:: text @@ -34,8 +34,8 @@ To use this mode, pass :obj:`MARKDOWN ` or "markdow HTML Style ---------- -To use this mode, pass :obj:`HTML ` or "html" in the *parse_mode* field when using -:obj:`send_message() `. The following tags are currently supported: +To use this mode, pass "html" in the *parse_mode* field when using :obj:`send_message() `. +The following tags are currently supported: .. code-block:: text diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 823faf27..24373ce1 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -60,7 +60,7 @@ log = logging.getLogger(__name__) class Client(Methods, BaseClient): - """This class represents a Client, the main mean for interacting with Telegram. + """This class represents a Client, the main means for interacting with Telegram. It exposes bot-like methods for an easy access to the API as well as a simple way to invoke every single Telegram API method available. @@ -438,7 +438,7 @@ class Client(Methods, BaseClient): self.stop() def run(self): - """Use this method as a convenience shortcut to automatically start the Client and idle the main script. + """Use this method to start the Client and automatically idle the main script. This is a convenience method that literally just calls :meth:`start` and :meth:`idle`. It makes running a client less verbose, but is not suitable in case you want to run more than one client in a single main script, diff --git a/setup.py b/setup.py index ef02c428..437ba39a 100644 --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ def get_readme(): class Clean(Command): DIST = ["./build", "./dist", "./Pyrogram.egg-info"] API = ["pyrogram/api/errors/exceptions", "pyrogram/api/functions", "pyrogram/api/types", "pyrogram/api/all.py"] - DOCS = ["docs/source/functions", "docs/source/types", "docs/build"] + DOCS = ["docs/source/telegram", "docs/build"] ALL = DIST + API + DOCS description = "Clean generated files" From ef912d21efd3d44e2a7181fe701aca79bd1b1c70 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 12 May 2019 19:49:06 +0200 Subject: [PATCH 053/202] Use more concise and cleaner description of a method and a type --- pyrogram/client/client.py | 22 +++++++++---------- pyrogram/client/filters/filters.py | 2 +- .../methods/bots/answer_callback_query.py | 2 +- .../methods/bots/answer_inline_query.py | 2 +- .../methods/bots/get_game_high_scores.py | 2 +- .../methods/bots/get_inline_bot_results.py | 2 +- .../methods/bots/request_callback_answer.py | 2 +- pyrogram/client/methods/bots/send_game.py | 2 +- .../methods/bots/send_inline_bot_result.py | 2 +- .../client/methods/bots/set_game_score.py | 2 +- .../client/methods/chats/delete_chat_photo.py | 2 +- .../methods/chats/export_chat_invite_link.py | 2 +- pyrogram/client/methods/chats/get_chat.py | 2 +- .../client/methods/chats/get_chat_member.py | 2 +- .../client/methods/chats/get_chat_members.py | 2 +- .../methods/chats/get_chat_members_count.py | 2 +- .../client/methods/chats/get_chat_preview.py | 2 +- pyrogram/client/methods/chats/get_dialogs.py | 2 +- .../client/methods/chats/get_dialogs_count.py | 2 +- .../client/methods/chats/iter_chat_members.py | 2 +- pyrogram/client/methods/chats/iter_dialogs.py | 2 +- pyrogram/client/methods/chats/join_chat.py | 2 +- .../client/methods/chats/kick_chat_member.py | 2 +- pyrogram/client/methods/chats/leave_chat.py | 2 +- .../client/methods/chats/pin_chat_message.py | 2 +- .../methods/chats/promote_chat_member.py | 2 +- .../client/methods/chats/restrict_chat.py | 2 +- .../methods/chats/restrict_chat_member.py | 2 +- .../methods/chats/set_chat_description.py | 2 +- .../client/methods/chats/set_chat_photo.py | 2 +- .../client/methods/chats/set_chat_title.py | 2 +- .../client/methods/chats/unban_chat_member.py | 2 +- .../methods/chats/unpin_chat_message.py | 2 +- .../methods/chats/update_chat_username.py | 2 +- .../client/methods/contacts/add_contacts.py | 2 +- .../methods/contacts/delete_contacts.py | 2 +- .../client/methods/contacts/get_contacts.py | 2 +- .../methods/contacts/get_contacts_count.py | 2 +- .../methods/messages/delete_messages.py | 2 +- .../client/methods/messages/download_media.py | 2 +- .../methods/messages/edit_message_caption.py | 2 +- .../methods/messages/edit_message_media.py | 2 +- .../messages/edit_message_reply_markup.py | 2 +- .../methods/messages/edit_message_text.py | 2 +- .../methods/messages/forward_messages.py | 2 +- .../client/methods/messages/get_history.py | 2 +- .../methods/messages/get_history_count.py | 2 +- .../client/methods/messages/get_messages.py | 2 +- .../client/methods/messages/iter_history.py | 2 +- .../client/methods/messages/retract_vote.py | 2 +- .../client/methods/messages/send_animation.py | 2 +- .../client/methods/messages/send_audio.py | 2 +- .../methods/messages/send_cached_media.py | 2 +- .../methods/messages/send_chat_action.py | 2 +- .../client/methods/messages/send_contact.py | 2 +- .../client/methods/messages/send_document.py | 2 +- .../client/methods/messages/send_location.py | 2 +- .../methods/messages/send_media_group.py | 2 +- .../client/methods/messages/send_message.py | 2 +- .../client/methods/messages/send_photo.py | 2 +- pyrogram/client/methods/messages/send_poll.py | 2 +- .../client/methods/messages/send_sticker.py | 2 +- .../client/methods/messages/send_venue.py | 2 +- .../client/methods/messages/send_video.py | 2 +- .../methods/messages/send_video_note.py | 2 +- .../client/methods/messages/send_voice.py | 2 +- pyrogram/client/methods/messages/stop_poll.py | 2 +- pyrogram/client/methods/messages/vote_poll.py | 2 +- .../methods/password/change_cloud_password.py | 2 +- .../methods/password/enable_cloud_password.py | 2 +- .../methods/password/remove_cloud_password.py | 2 +- .../users/delete_user_profile_photos.py | 2 +- pyrogram/client/methods/users/get_me.py | 2 +- .../methods/users/get_user_profile_photos.py | 2 +- .../users/get_user_profile_photos_count.py | 2 +- pyrogram/client/methods/users/get_users.py | 2 +- .../methods/users/set_user_profile_photo.py | 2 +- .../client/methods/users/update_username.py | 2 +- .../client/types/inline_mode/inline_query.py | 3 ++- .../types/inline_mode/inline_query_result.py | 2 +- .../inline_query_result_article.py | 2 +- .../client/types/input_media/input_media.py | 4 +++- .../input_media/input_media_animation.py | 2 +- .../types/input_media/input_media_audio.py | 3 ++- .../types/input_media/input_media_document.py | 2 +- .../types/input_media/input_media_photo.py | 2 +- .../types/input_media/input_media_video.py | 2 +- .../types/input_media/input_phone_contact.py | 2 +- .../input_message_content.py | 2 +- .../input_text_message_content.py | 2 +- .../client/types/keyboards/callback_game.py | 2 +- .../client/types/keyboards/callback_query.py | 3 ++- .../client/types/keyboards/force_reply.py | 4 +++- .../client/types/keyboards/game_high_score.py | 2 +- .../types/keyboards/game_high_scores.py | 2 +- .../types/keyboards/inline_keyboard_button.py | 4 +++- .../types/keyboards/inline_keyboard_markup.py | 2 +- .../client/types/keyboards/keyboard_button.py | 2 +- .../types/keyboards/reply_keyboard_markup.py | 2 +- .../types/keyboards/reply_keyboard_remove.py | 9 +++++--- .../types/messages_and_media/animation.py | 2 +- .../client/types/messages_and_media/audio.py | 2 +- .../types/messages_and_media/contact.py | 2 +- .../types/messages_and_media/document.py | 2 +- .../client/types/messages_and_media/game.py | 2 +- .../types/messages_and_media/location.py | 2 +- .../types/messages_and_media/message.py | 2 +- .../messages_and_media/message_entity.py | 2 +- .../types/messages_and_media/messages.py | 2 +- .../client/types/messages_and_media/photo.py | 2 +- .../types/messages_and_media/photo_size.py | 2 +- .../client/types/messages_and_media/poll.py | 2 +- .../types/messages_and_media/poll_option.py | 2 +- .../types/messages_and_media/sticker.py | 2 +- .../messages_and_media/user_profile_photos.py | 2 +- .../client/types/messages_and_media/venue.py | 2 +- .../client/types/messages_and_media/video.py | 2 +- .../types/messages_and_media/video_note.py | 2 +- .../client/types/messages_and_media/voice.py | 2 +- pyrogram/client/types/user_and_chats/chat.py | 2 +- .../types/user_and_chats/chat_member.py | 2 +- .../types/user_and_chats/chat_members.py | 2 +- .../types/user_and_chats/chat_permissions.py | 2 +- .../client/types/user_and_chats/chat_photo.py | 2 +- .../types/user_and_chats/chat_preview.py | 2 +- .../client/types/user_and_chats/dialog.py | 2 +- .../client/types/user_and_chats/dialogs.py | 2 +- pyrogram/client/types/user_and_chats/user.py | 2 +- .../types/user_and_chats/user_status.py | 2 +- 129 files changed, 153 insertions(+), 141 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 24373ce1..f65ef231 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -261,7 +261,7 @@ class Client(Methods, BaseClient): self._proxy.update(value) def start(self): - """Use this method to start the Client. + """Start the Client. Raises: RPCError: In case of a Telegram RPC error. @@ -354,7 +354,7 @@ class Client(Methods, BaseClient): return self def stop(self): - """Use this method to stop the Client. + """Stop the Client. Raises: ConnectionError: In case you try to stop an already stopped Client. @@ -396,7 +396,7 @@ class Client(Methods, BaseClient): return self def restart(self): - """Use this method to restart the Client. + """Restart the Client. Raises: ConnectionError: In case you try to restart a stopped Client. @@ -405,7 +405,7 @@ class Client(Methods, BaseClient): self.start() def idle(self, stop_signals: tuple = (SIGINT, SIGTERM, SIGABRT)): - """Use this method to block the main script execution until a signal (e.g.: from CTRL+C) is received. + """Block the main script execution until a signal (e.g.: from CTRL+C) is received. Once the signal is received, the client will automatically stop and the main script will continue its execution. This is used after starting one or more clients and is useful for event-driven applications only, that are, @@ -438,7 +438,7 @@ class Client(Methods, BaseClient): self.stop() def run(self): - """Use this method to start the Client and automatically idle the main script. + """Start the Client and automatically idle the main script. This is a convenience method that literally just calls :meth:`start` and :meth:`idle`. It makes running a client less verbose, but is not suitable in case you want to run more than one client in a single main script, @@ -451,7 +451,7 @@ class Client(Methods, BaseClient): self.idle() def add_handler(self, handler: Handler, group: int = 0): - """Use this method to register an update handler. + """Register an update handler. You can register multiple handlers, but at most one handler within a group will be used for a single update. To handle the same update more than once, register @@ -475,7 +475,7 @@ class Client(Methods, BaseClient): return handler, group def remove_handler(self, handler: Handler, group: int = 0): - """Use this method to remove a previously-registered update handler. + """Remove a previously-registered update handler. Make sure to provide the right group that the handler was added in. You can use the return value of the :meth:`add_handler` method, a tuple of (handler, group), and @@ -494,7 +494,7 @@ class Client(Methods, BaseClient): self.dispatcher.remove_handler(handler, group) def stop_transmission(self): - """Use this method to stop downloading or uploading a file. + """Stop downloading or uploading a file. Must be called inside a progress callback function. """ raise Client.StopTransmission @@ -1036,7 +1036,7 @@ class Client(Methods, BaseClient): log.debug("{} stopped".format(name)) def send(self, data: Object, retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT): - """Use this method to send raw Telegram queries. + """Send raw Telegram queries. This method makes it possible to manually call every single Telegram API method in a low-level manner. Available functions are listed in the :obj:`functions ` package and may accept compound @@ -1341,7 +1341,7 @@ class Client(Methods, BaseClient): self.get_initial_dialogs_chunk() def resolve_peer(self, peer_id: Union[int, str]): - """Use this method to get the InputPeer of a known peer id. + """Get the InputPeer of a known peer id. Useful whenever an InputPeer type is required. .. note:: @@ -1423,7 +1423,7 @@ class Client(Methods, BaseClient): progress: callable = None, progress_args: tuple = () ): - """Use this method to upload a file onto Telegram servers, without actually sending the message to anyone. + """Upload a file onto Telegram servers, without actually sending the message to anyone. Useful whenever an InputFile type is required. .. note:: diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 5070bd52..2117ec6e 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -23,7 +23,7 @@ from ..types.keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup def create(name: str, func: callable, **kwargs) -> type: - """Use this method to create a Filter. + """Create a Filter. Custom filters give you extra control over which updates are allowed or not to be processed by your handlers. diff --git a/pyrogram/client/methods/bots/answer_callback_query.py b/pyrogram/client/methods/bots/answer_callback_query.py index 12effe47..010c29ea 100644 --- a/pyrogram/client/methods/bots/answer_callback_query.py +++ b/pyrogram/client/methods/bots/answer_callback_query.py @@ -29,7 +29,7 @@ class AnswerCallbackQuery(BaseClient): url: str = None, cache_time: int = 0 ): - """Use this method to send answers to callback queries sent from inline keyboards. + """Send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. Parameters: diff --git a/pyrogram/client/methods/bots/answer_inline_query.py b/pyrogram/client/methods/bots/answer_inline_query.py index 7a1b14c8..62344f20 100644 --- a/pyrogram/client/methods/bots/answer_inline_query.py +++ b/pyrogram/client/methods/bots/answer_inline_query.py @@ -34,7 +34,7 @@ class AnswerInlineQuery(BaseClient): switch_pm_text: str = "", switch_pm_parameter: str = "" ): - """Use this method to send answers to an inline query. + """Send answers to an inline query. No more than 50 results per query are allowed. Parameters: diff --git a/pyrogram/client/methods/bots/get_game_high_scores.py b/pyrogram/client/methods/bots/get_game_high_scores.py index 64901fea..e1472b9e 100644 --- a/pyrogram/client/methods/bots/get_game_high_scores.py +++ b/pyrogram/client/methods/bots/get_game_high_scores.py @@ -30,7 +30,7 @@ class GetGameHighScores(BaseClient): chat_id: Union[int, str], message_id: int = None ) -> "pyrogram.GameHighScores": - """Use this method to get data for high score tables. + """Get data for high score tables. Parameters: user_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/bots/get_inline_bot_results.py b/pyrogram/client/methods/bots/get_inline_bot_results.py index 14628b64..307238e3 100644 --- a/pyrogram/client/methods/bots/get_inline_bot_results.py +++ b/pyrogram/client/methods/bots/get_inline_bot_results.py @@ -32,7 +32,7 @@ class GetInlineBotResults(BaseClient): latitude: float = None, longitude: float = None ): - """Use this method to get bot results via inline queries. + """Get bot results via inline queries. You can then send a result using :obj:`send_inline_bot_result ` Parameters: diff --git a/pyrogram/client/methods/bots/request_callback_answer.py b/pyrogram/client/methods/bots/request_callback_answer.py index 7e57b39b..443cb825 100644 --- a/pyrogram/client/methods/bots/request_callback_answer.py +++ b/pyrogram/client/methods/bots/request_callback_answer.py @@ -30,7 +30,7 @@ class RequestCallbackAnswer(BaseClient): callback_data: bytes, timeout: int = 10 ): - """Use this method to request a callback answer from bots. + """Request a callback answer from bots. This is the equivalent of clicking an inline button containing callback data. Parameters: diff --git a/pyrogram/client/methods/bots/send_game.py b/pyrogram/client/methods/bots/send_game.py index 03593a56..c10d328a 100644 --- a/pyrogram/client/methods/bots/send_game.py +++ b/pyrogram/client/methods/bots/send_game.py @@ -37,7 +37,7 @@ class SendGame(BaseClient): "pyrogram.ForceReply" ] = None ) -> "pyrogram.Message": - """Use this method to send a game. + """Send a game. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/bots/send_inline_bot_result.py b/pyrogram/client/methods/bots/send_inline_bot_result.py index 49dc11ee..031591db 100644 --- a/pyrogram/client/methods/bots/send_inline_bot_result.py +++ b/pyrogram/client/methods/bots/send_inline_bot_result.py @@ -32,7 +32,7 @@ class SendInlineBotResult(BaseClient): reply_to_message_id: int = None, hide_via: bool = None ): - """Use this method to send an inline bot result. + """Send an inline bot result. Bot results can be retrieved using :obj:`get_inline_bot_results ` Parameters: diff --git a/pyrogram/client/methods/bots/set_game_score.py b/pyrogram/client/methods/bots/set_game_score.py index f5658542..3b0e97e2 100644 --- a/pyrogram/client/methods/bots/set_game_score.py +++ b/pyrogram/client/methods/bots/set_game_score.py @@ -34,7 +34,7 @@ class SetGameScore(BaseClient): message_id: int = None ): # inline_message_id: str = None): TODO Add inline_message_id - """Use this method to set the score of the specified user in a game. + """Set the score of the specified user in a game. Parameters: user_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/chats/delete_chat_photo.py b/pyrogram/client/methods/chats/delete_chat_photo.py index f45a7dc2..88d97506 100644 --- a/pyrogram/client/methods/chats/delete_chat_photo.py +++ b/pyrogram/client/methods/chats/delete_chat_photo.py @@ -27,7 +27,7 @@ class DeleteChatPhoto(BaseClient): self, chat_id: Union[int, str] ) -> bool: - """Use this method to delete a chat photo. + """Delete a chat photo. Photos can't be changed for private chats. You must be an administrator in the chat for this to work and must have the appropriate admin rights. diff --git a/pyrogram/client/methods/chats/export_chat_invite_link.py b/pyrogram/client/methods/chats/export_chat_invite_link.py index e1ca27c2..a223a000 100644 --- a/pyrogram/client/methods/chats/export_chat_invite_link.py +++ b/pyrogram/client/methods/chats/export_chat_invite_link.py @@ -27,7 +27,7 @@ class ExportChatInviteLink(BaseClient): self, chat_id: Union[int, str] ) -> str: - """Use this method to generate a new invite link for a chat; any previously generated link is revoked. + """Generate a new invite link for a chat; any previously generated link is revoked. You must be an administrator in the chat for this to work and have the appropriate admin rights. diff --git a/pyrogram/client/methods/chats/get_chat.py b/pyrogram/client/methods/chats/get_chat.py index bf4c4cea..96bc9eaf 100644 --- a/pyrogram/client/methods/chats/get_chat.py +++ b/pyrogram/client/methods/chats/get_chat.py @@ -28,7 +28,7 @@ class GetChat(BaseClient): self, chat_id: Union[int, str] ) -> "pyrogram.Chat": - """Use this method to get up to date information about the chat. + """Get up to date information about the chat. Information include current name of the user for one-on-one conversations, current username of a user, group or channel, etc. diff --git a/pyrogram/client/methods/chats/get_chat_member.py b/pyrogram/client/methods/chats/get_chat_member.py index b625e32f..c77e46b6 100644 --- a/pyrogram/client/methods/chats/get_chat_member.py +++ b/pyrogram/client/methods/chats/get_chat_member.py @@ -30,7 +30,7 @@ class GetChatMember(BaseClient): chat_id: Union[int, str], user_id: Union[int, str] ) -> "pyrogram.ChatMember": - """Use this method to get information about one member of a chat. + """Get information about one member of a chat. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/chats/get_chat_members.py b/pyrogram/client/methods/chats/get_chat_members.py index 79001614..10f76dcf 100644 --- a/pyrogram/client/methods/chats/get_chat_members.py +++ b/pyrogram/client/methods/chats/get_chat_members.py @@ -46,7 +46,7 @@ class GetChatMembers(BaseClient): query: str = "", filter: str = Filters.ALL ) -> "pyrogram.ChatMembers": - """Use this method to get a chunk of the members list of a chat. + """Get a chunk of the members list of a chat. You can get up to 200 chat members at once. A chat can be either a basic group, a supergroup or a channel. diff --git a/pyrogram/client/methods/chats/get_chat_members_count.py b/pyrogram/client/methods/chats/get_chat_members_count.py index d40585f5..c8bd6deb 100644 --- a/pyrogram/client/methods/chats/get_chat_members_count.py +++ b/pyrogram/client/methods/chats/get_chat_members_count.py @@ -27,7 +27,7 @@ class GetChatMembersCount(BaseClient): self, chat_id: Union[int, str] ) -> int: - """Use this method to get the number of members in a chat. + """Get the number of members in a chat. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/chats/get_chat_preview.py b/pyrogram/client/methods/chats/get_chat_preview.py index fd00c374..8551aaf4 100644 --- a/pyrogram/client/methods/chats/get_chat_preview.py +++ b/pyrogram/client/methods/chats/get_chat_preview.py @@ -26,7 +26,7 @@ class GetChatPreview(BaseClient): self, invite_link: str ): - """Use this method to get the preview of a chat using the invite link. + """Get the preview of a chat using the invite link. This method only returns a chat preview, if you want to join a chat use :meth:`join_chat` diff --git a/pyrogram/client/methods/chats/get_dialogs.py b/pyrogram/client/methods/chats/get_dialogs.py index 83732d07..605ee782 100644 --- a/pyrogram/client/methods/chats/get_dialogs.py +++ b/pyrogram/client/methods/chats/get_dialogs.py @@ -34,7 +34,7 @@ class GetDialogs(BaseClient): limit: int = 100, pinned_only: bool = False ) -> "pyrogram.Dialogs": - """Use this method to get a chunk of the user's dialogs. + """Get a chunk of the user's dialogs. You can get up to 100 dialogs at once. For a more convenient way of getting a user's dialogs see :meth:`iter_dialogs`. diff --git a/pyrogram/client/methods/chats/get_dialogs_count.py b/pyrogram/client/methods/chats/get_dialogs_count.py index eea327da..1a307433 100644 --- a/pyrogram/client/methods/chats/get_dialogs_count.py +++ b/pyrogram/client/methods/chats/get_dialogs_count.py @@ -22,7 +22,7 @@ from ...ext import BaseClient class GetDialogsCount(BaseClient): def get_dialogs_count(self, pinned_only: bool = False) -> int: - """Use this method to get the total count of your dialogs. + """Get the total count of your dialogs. pinned_only (``bool``, *optional*): Pass True if you want to count only pinned dialogs. diff --git a/pyrogram/client/methods/chats/iter_chat_members.py b/pyrogram/client/methods/chats/iter_chat_members.py index f735da48..330eed7b 100644 --- a/pyrogram/client/methods/chats/iter_chat_members.py +++ b/pyrogram/client/methods/chats/iter_chat_members.py @@ -45,7 +45,7 @@ class IterChatMembers(BaseClient): query: str = "", filter: str = Filters.ALL ) -> Generator["pyrogram.ChatMember", None, None]: - """Use this method to iterate through the members of a chat sequentially. + """Iterate through the members of a chat sequentially. This convenience method does the same as repeatedly calling :meth:`get_chat_members` in a loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting the whole members list of a chat with diff --git a/pyrogram/client/methods/chats/iter_dialogs.py b/pyrogram/client/methods/chats/iter_dialogs.py index 6fc9f81c..1209a5df 100644 --- a/pyrogram/client/methods/chats/iter_dialogs.py +++ b/pyrogram/client/methods/chats/iter_dialogs.py @@ -28,7 +28,7 @@ class IterDialogs(BaseClient): offset_date: int = 0, limit: int = 0 ) -> Generator["pyrogram.Dialog", None, None]: - """Use this method to iterate through a user's dialogs sequentially. + """Iterate through a user's dialogs sequentially. This convenience method does the same as repeatedly calling :meth:`get_dialogs` in a loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting the whole dialogs list with a single call. diff --git a/pyrogram/client/methods/chats/join_chat.py b/pyrogram/client/methods/chats/join_chat.py index 77b2ee50..ed6c69ce 100644 --- a/pyrogram/client/methods/chats/join_chat.py +++ b/pyrogram/client/methods/chats/join_chat.py @@ -26,7 +26,7 @@ class JoinChat(BaseClient): self, chat_id: str ): - """Use this method to join a group chat or channel. + """Join a group chat or channel. Parameters: chat_id (``str``): diff --git a/pyrogram/client/methods/chats/kick_chat_member.py b/pyrogram/client/methods/chats/kick_chat_member.py index dbd095ad..f5058829 100644 --- a/pyrogram/client/methods/chats/kick_chat_member.py +++ b/pyrogram/client/methods/chats/kick_chat_member.py @@ -30,7 +30,7 @@ class KickChatMember(BaseClient): user_id: Union[int, str], until_date: int = 0 ) -> Union["pyrogram.Message", bool]: - """Use this method to kick a user from a group, a supergroup or a channel. + """Kick a user from a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the group on their own using invite links, etc., unless unbanned first. You must be an administrator in the chat for this to work and must have the appropriate admin rights. diff --git a/pyrogram/client/methods/chats/leave_chat.py b/pyrogram/client/methods/chats/leave_chat.py index 57cc1090..3ed6f10f 100644 --- a/pyrogram/client/methods/chats/leave_chat.py +++ b/pyrogram/client/methods/chats/leave_chat.py @@ -28,7 +28,7 @@ class LeaveChat(BaseClient): chat_id: Union[int, str], delete: bool = False ): - """Use this method to leave a group chat or channel. + """Leave a group chat or channel. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/chats/pin_chat_message.py b/pyrogram/client/methods/chats/pin_chat_message.py index 2c485dab..efb41e67 100644 --- a/pyrogram/client/methods/chats/pin_chat_message.py +++ b/pyrogram/client/methods/chats/pin_chat_message.py @@ -29,7 +29,7 @@ class PinChatMessage(BaseClient): message_id: int, disable_notification: bool = None ) -> bool: - """Use this method to pin a message in a group, channel or your own chat. + """Pin a message in a group, channel or your own chat. You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin right in the supergroup or "can_edit_messages" admin right in the channel. diff --git a/pyrogram/client/methods/chats/promote_chat_member.py b/pyrogram/client/methods/chats/promote_chat_member.py index 0b93576a..700b3a68 100644 --- a/pyrogram/client/methods/chats/promote_chat_member.py +++ b/pyrogram/client/methods/chats/promote_chat_member.py @@ -36,7 +36,7 @@ class PromoteChatMember(BaseClient): can_pin_messages: bool = False, can_promote_members: bool = False ) -> bool: - """Use this method to promote or demote a user in a supergroup or a channel. + """Promote or demote a user in a supergroup or a channel. You must be an administrator in the chat for this to work and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user. diff --git a/pyrogram/client/methods/chats/restrict_chat.py b/pyrogram/client/methods/chats/restrict_chat.py index 9f6d2910..8e63a9b2 100644 --- a/pyrogram/client/methods/chats/restrict_chat.py +++ b/pyrogram/client/methods/chats/restrict_chat.py @@ -36,7 +36,7 @@ class RestrictChat(BaseClient): can_invite_users: bool = False, can_pin_messages: bool = False ) -> Chat: - """Use this method to restrict a chat. + """Restrict a chat. Pass True for all boolean parameters to lift restrictions from a chat. Parameters: diff --git a/pyrogram/client/methods/chats/restrict_chat_member.py b/pyrogram/client/methods/chats/restrict_chat_member.py index 1f31d8eb..96e07d18 100644 --- a/pyrogram/client/methods/chats/restrict_chat_member.py +++ b/pyrogram/client/methods/chats/restrict_chat_member.py @@ -38,7 +38,7 @@ class RestrictChatMember(BaseClient): can_invite_users: bool = False, can_pin_messages: bool = False ) -> Chat: - """Use this method to restrict a user in a supergroup. + """Restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights. Pass True for all boolean parameters to lift restrictions from a user. diff --git a/pyrogram/client/methods/chats/set_chat_description.py b/pyrogram/client/methods/chats/set_chat_description.py index 6cc3bbd3..68bf9fa2 100644 --- a/pyrogram/client/methods/chats/set_chat_description.py +++ b/pyrogram/client/methods/chats/set_chat_description.py @@ -28,7 +28,7 @@ class SetChatDescription(BaseClient): chat_id: Union[int, str], description: str ) -> bool: - """Use this method to change the description of a supergroup or a channel. + """Change the description of a supergroup or a channel. You must be an administrator in the chat for this to work and must have the appropriate admin rights. Parameters: diff --git a/pyrogram/client/methods/chats/set_chat_photo.py b/pyrogram/client/methods/chats/set_chat_photo.py index 7248a265..4a2f6cf1 100644 --- a/pyrogram/client/methods/chats/set_chat_photo.py +++ b/pyrogram/client/methods/chats/set_chat_photo.py @@ -31,7 +31,7 @@ class SetChatPhoto(BaseClient): chat_id: Union[int, str], photo: str ) -> bool: - """Use this method to set a new profile photo for the chat. + """Set a new profile photo for the chat. Photos can't be changed for private chats. You must be an administrator in the chat for this to work and must have the appropriate admin rights. diff --git a/pyrogram/client/methods/chats/set_chat_title.py b/pyrogram/client/methods/chats/set_chat_title.py index a159d2cc..f70fa5da 100644 --- a/pyrogram/client/methods/chats/set_chat_title.py +++ b/pyrogram/client/methods/chats/set_chat_title.py @@ -28,7 +28,7 @@ class SetChatTitle(BaseClient): chat_id: Union[int, str], title: str ) -> bool: - """Use this method to change the title of a chat. + """Change the title of a chat. Titles can't be changed for private chats. You must be an administrator in the chat for this to work and must have the appropriate admin rights. diff --git a/pyrogram/client/methods/chats/unban_chat_member.py b/pyrogram/client/methods/chats/unban_chat_member.py index 35ea0343..7e4205c9 100644 --- a/pyrogram/client/methods/chats/unban_chat_member.py +++ b/pyrogram/client/methods/chats/unban_chat_member.py @@ -28,7 +28,7 @@ class UnbanChatMember(BaseClient): chat_id: Union[int, str], user_id: Union[int, str] ) -> bool: - """Use this method to unban a previously kicked user in a supergroup or channel. + """Unban a previously kicked user in a supergroup or channel. The user will **not** return to the group or channel automatically, but will be able to join via link, etc. You must be an administrator for this to work. diff --git a/pyrogram/client/methods/chats/unpin_chat_message.py b/pyrogram/client/methods/chats/unpin_chat_message.py index 4e2531fd..22639315 100644 --- a/pyrogram/client/methods/chats/unpin_chat_message.py +++ b/pyrogram/client/methods/chats/unpin_chat_message.py @@ -27,7 +27,7 @@ class UnpinChatMessage(BaseClient): self, chat_id: Union[int, str] ) -> bool: - """Use this method to unpin a message in a group, channel or your own chat. + """Unpin a message in a group, channel or your own chat. You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin right in the supergroup or "can_edit_messages" admin right in the channel. diff --git a/pyrogram/client/methods/chats/update_chat_username.py b/pyrogram/client/methods/chats/update_chat_username.py index 2e8adb05..de5015ea 100644 --- a/pyrogram/client/methods/chats/update_chat_username.py +++ b/pyrogram/client/methods/chats/update_chat_username.py @@ -28,7 +28,7 @@ class UpdateChatUsername(BaseClient): chat_id: Union[int, str], username: Union[str, None] ) -> bool: - """Use this method to update a channel or a supergroup username. + """Update a channel or a supergroup username. To update your own username (for users only, not bots) you can use :meth:`update_username`. diff --git a/pyrogram/client/methods/contacts/add_contacts.py b/pyrogram/client/methods/contacts/add_contacts.py index aa8e1fd5..c7e647b0 100644 --- a/pyrogram/client/methods/contacts/add_contacts.py +++ b/pyrogram/client/methods/contacts/add_contacts.py @@ -28,7 +28,7 @@ class AddContacts(BaseClient): self, contacts: List["pyrogram.InputPhoneContact"] ): - """Use this method to add contacts to your Telegram address book. + """Add contacts to your Telegram address book. Parameters: contacts (List of :obj:`InputPhoneContact`): diff --git a/pyrogram/client/methods/contacts/delete_contacts.py b/pyrogram/client/methods/contacts/delete_contacts.py index db5b9df1..7a5ecf55 100644 --- a/pyrogram/client/methods/contacts/delete_contacts.py +++ b/pyrogram/client/methods/contacts/delete_contacts.py @@ -28,7 +28,7 @@ class DeleteContacts(BaseClient): self, ids: List[int] ): - """Use this method to delete contacts from your Telegram address book. + """Delete contacts from your Telegram address book. Parameters: ids (List of ``int``): diff --git a/pyrogram/client/methods/contacts/get_contacts.py b/pyrogram/client/methods/contacts/get_contacts.py index 7e607e77..1fa5b738 100644 --- a/pyrogram/client/methods/contacts/get_contacts.py +++ b/pyrogram/client/methods/contacts/get_contacts.py @@ -30,7 +30,7 @@ log = logging.getLogger(__name__) class GetContacts(BaseClient): def get_contacts(self) -> List["pyrogram.User"]: - """Use this method to get contacts from your Telegram address book. + """Get contacts from your Telegram address book. Returns: List of :obj:`User`: On success, a list of users is returned. diff --git a/pyrogram/client/methods/contacts/get_contacts_count.py b/pyrogram/client/methods/contacts/get_contacts_count.py index b9e6f6c4..01fb0789 100644 --- a/pyrogram/client/methods/contacts/get_contacts_count.py +++ b/pyrogram/client/methods/contacts/get_contacts_count.py @@ -22,7 +22,7 @@ from ...ext import BaseClient class GetContactsCount(BaseClient): def get_contacts_count(self) -> int: - """Use this method to get the total count of contacts from your Telegram address book. + """Get the total count of contacts from your Telegram address book. Returns: ``int``: On success, an integer is returned. diff --git a/pyrogram/client/methods/messages/delete_messages.py b/pyrogram/client/methods/messages/delete_messages.py index 067d2fae..3667c8ee 100644 --- a/pyrogram/client/methods/messages/delete_messages.py +++ b/pyrogram/client/methods/messages/delete_messages.py @@ -29,7 +29,7 @@ class DeleteMessages(BaseClient): message_ids: Iterable[int], revoke: bool = True ) -> bool: - """Use this method to delete messages, including service messages. + """Delete messages, including service messages. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index 04a5ec57..5c440173 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -32,7 +32,7 @@ class DownloadMedia(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union[str, None]: - """Use this method to download the media from a message. + """Download the media from a message. Parameters: message (:obj:`Message` | ``str``): diff --git a/pyrogram/client/methods/messages/edit_message_caption.py b/pyrogram/client/methods/messages/edit_message_caption.py index fe19dcc9..cfe5b236 100644 --- a/pyrogram/client/methods/messages/edit_message_caption.py +++ b/pyrogram/client/methods/messages/edit_message_caption.py @@ -32,7 +32,7 @@ class EditMessageCaption(BaseClient): parse_mode: str = "", reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": - """Use this method to edit captions of messages. + """Edit captions of messages. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/edit_message_media.py b/pyrogram/client/methods/messages/edit_message_media.py index b03fb1e0..b15daa9b 100644 --- a/pyrogram/client/methods/messages/edit_message_media.py +++ b/pyrogram/client/methods/messages/edit_message_media.py @@ -40,7 +40,7 @@ class EditMessageMedia(BaseClient): media: InputMedia, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": - """Use this method to edit audio, document, photo, or video messages. + """Edit audio, document, photo, or video messages. If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. diff --git a/pyrogram/client/methods/messages/edit_message_reply_markup.py b/pyrogram/client/methods/messages/edit_message_reply_markup.py index 73561451..8d2b82af 100644 --- a/pyrogram/client/methods/messages/edit_message_reply_markup.py +++ b/pyrogram/client/methods/messages/edit_message_reply_markup.py @@ -30,7 +30,7 @@ class EditMessageReplyMarkup(BaseClient): message_id: int, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": - """Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). + """Edit only the reply markup of messages sent by the bot or via the bot (for inline bots). Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/edit_message_text.py b/pyrogram/client/methods/messages/edit_message_text.py index 30b58b68..69283e89 100644 --- a/pyrogram/client/methods/messages/edit_message_text.py +++ b/pyrogram/client/methods/messages/edit_message_text.py @@ -33,7 +33,7 @@ class EditMessageText(BaseClient): disable_web_page_preview: bool = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": - """Use this method to edit text messages. + """Edit text messages. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/forward_messages.py b/pyrogram/client/methods/messages/forward_messages.py index 08cc48ea..a3e161fb 100644 --- a/pyrogram/client/methods/messages/forward_messages.py +++ b/pyrogram/client/methods/messages/forward_messages.py @@ -33,7 +33,7 @@ class ForwardMessages(BaseClient): as_copy: bool = False, remove_caption: bool = False ) -> "pyrogram.Messages": - """Use this method to forward messages of any kind. + """Forward messages of any kind. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/get_history.py b/pyrogram/client/methods/messages/get_history.py index ffd8f9e0..3933e729 100644 --- a/pyrogram/client/methods/messages/get_history.py +++ b/pyrogram/client/methods/messages/get_history.py @@ -38,7 +38,7 @@ class GetHistory(BaseClient): offset_date: int = 0, reverse: bool = False ) -> "pyrogram.Messages": - """Use this method to retrieve a chunk of the history of a chat. + """Retrieve a chunk of the history of a chat. You can get up to 100 messages at once. For a more convenient way of getting a chat history see :meth:`iter_history`. diff --git a/pyrogram/client/methods/messages/get_history_count.py b/pyrogram/client/methods/messages/get_history_count.py index b4812d26..ced46799 100644 --- a/pyrogram/client/methods/messages/get_history_count.py +++ b/pyrogram/client/methods/messages/get_history_count.py @@ -32,7 +32,7 @@ class GetHistoryCount(BaseClient): self, chat_id: Union[int, str] ) -> int: - """Use this method to get the total count of messages in a chat. + """Get the total count of messages in a chat. .. note:: diff --git a/pyrogram/client/methods/messages/get_messages.py b/pyrogram/client/methods/messages/get_messages.py index 391c251c..51f71352 100644 --- a/pyrogram/client/methods/messages/get_messages.py +++ b/pyrogram/client/methods/messages/get_messages.py @@ -36,7 +36,7 @@ class GetMessages(BaseClient): reply_to_message_ids: Union[int, Iterable[int]] = None, replies: int = 1 ) -> Union["pyrogram.Message", "pyrogram.Messages"]: - """Use this method to get one or more messages that belong to a specific chat. + """Get one or more messages that belong to a specific chat. You can retrieve up to 200 messages at once. Parameters: diff --git a/pyrogram/client/methods/messages/iter_history.py b/pyrogram/client/methods/messages/iter_history.py index b1546318..218dd7f5 100644 --- a/pyrogram/client/methods/messages/iter_history.py +++ b/pyrogram/client/methods/messages/iter_history.py @@ -32,7 +32,7 @@ class IterHistory(BaseClient): offset_date: int = 0, reverse: bool = False ) -> Generator["pyrogram.Message", None, None]: - """Use this method to iterate through a chat history sequentially. + """Iterate through a chat history sequentially. This convenience method does the same as repeatedly calling :meth:`get_history` in a loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting the whole chat history with a single call. diff --git a/pyrogram/client/methods/messages/retract_vote.py b/pyrogram/client/methods/messages/retract_vote.py index 929298df..b52181a6 100644 --- a/pyrogram/client/methods/messages/retract_vote.py +++ b/pyrogram/client/methods/messages/retract_vote.py @@ -29,7 +29,7 @@ class RetractVote(BaseClient): chat_id: Union[int, str], message_id: int ) -> "pyrogram.Poll": - """Use this method to retract your vote in a poll. + """Retract your vote in a poll. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_animation.py b/pyrogram/client/methods/messages/send_animation.py index 4e21e56c..461ef6fc 100644 --- a/pyrogram/client/methods/messages/send_animation.py +++ b/pyrogram/client/methods/messages/send_animation.py @@ -49,7 +49,7 @@ class SendAnimation(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send animation files (animation or H.264/MPEG-4 AVC video without sound). + """Send animation files (animation or H.264/MPEG-4 AVC video without sound). Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_audio.py b/pyrogram/client/methods/messages/send_audio.py index 71458c33..aaa5a529 100644 --- a/pyrogram/client/methods/messages/send_audio.py +++ b/pyrogram/client/methods/messages/send_audio.py @@ -49,7 +49,7 @@ class SendAudio(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send audio files. + """Send audio files. For sending voice messages, use the :obj:`send_voice()` method instead. diff --git a/pyrogram/client/methods/messages/send_cached_media.py b/pyrogram/client/methods/messages/send_cached_media.py index b0b3fc4e..9f66e5fd 100644 --- a/pyrogram/client/methods/messages/send_cached_media.py +++ b/pyrogram/client/methods/messages/send_cached_media.py @@ -42,7 +42,7 @@ class SendCachedMedia(BaseClient): "pyrogram.ForceReply" ] = None ) -> Union["pyrogram.Message", None]: - """Use this method to send any media stored on the Telegram servers using a file_id. + """Send any media stored on the Telegram servers using a file_id. This convenience method works with any valid file_id only. It does the same as calling the relevant method for sending media using a file_id, thus saving you from the diff --git a/pyrogram/client/methods/messages/send_chat_action.py b/pyrogram/client/methods/messages/send_chat_action.py index 1d819747..ac55c633 100644 --- a/pyrogram/client/methods/messages/send_chat_action.py +++ b/pyrogram/client/methods/messages/send_chat_action.py @@ -44,7 +44,7 @@ POSSIBLE_VALUES = list(map(lambda x: x.lower(), filter(lambda x: not x.startswit class SendChatAction(BaseClient): def send_chat_action(self, chat_id: Union[int, str], action: str) -> bool: - """Use this method when you need to tell the other party that something is happening on your side. + """Tell the other party that something is happening on your side. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_contact.py b/pyrogram/client/methods/messages/send_contact.py index 27df6505..d0b6fb58 100644 --- a/pyrogram/client/methods/messages/send_contact.py +++ b/pyrogram/client/methods/messages/send_contact.py @@ -40,7 +40,7 @@ class SendContact(BaseClient): "pyrogram.ForceReply" ] = None ) -> "pyrogram.Message": - """Use this method to send phone contacts. + """Send phone contacts. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index e2ac0d23..e966a11a 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -46,7 +46,7 @@ class SendDocument(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send general files. + """Send general files. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_location.py b/pyrogram/client/methods/messages/send_location.py index dce6671b..2e3681e6 100644 --- a/pyrogram/client/methods/messages/send_location.py +++ b/pyrogram/client/methods/messages/send_location.py @@ -38,7 +38,7 @@ class SendLocation(BaseClient): "pyrogram.ForceReply" ] = None ) -> "pyrogram.Message": - """Use this method to send points on the map. + """Send points on the map. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_media_group.py b/pyrogram/client/methods/messages/send_media_group.py index fe6725f0..0af94cf9 100644 --- a/pyrogram/client/methods/messages/send_media_group.py +++ b/pyrogram/client/methods/messages/send_media_group.py @@ -41,7 +41,7 @@ class SendMediaGroup(BaseClient): disable_notification: bool = None, reply_to_message_id: int = None ): - """Use this method to send a group of photos or videos as an album. + """Send a group of photos or videos as an album. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_message.py b/pyrogram/client/methods/messages/send_message.py index 15c1487a..f8caa081 100644 --- a/pyrogram/client/methods/messages/send_message.py +++ b/pyrogram/client/methods/messages/send_message.py @@ -39,7 +39,7 @@ class SendMessage(BaseClient): "pyrogram.ForceReply" ] = None ) -> "pyrogram.Message": - """Use this method to send text messages. + """Send text messages. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_photo.py b/pyrogram/client/methods/messages/send_photo.py index 5487761e..7c4f688f 100644 --- a/pyrogram/client/methods/messages/send_photo.py +++ b/pyrogram/client/methods/messages/send_photo.py @@ -46,7 +46,7 @@ class SendPhoto(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send photos. + """Send photos. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_poll.py b/pyrogram/client/methods/messages/send_poll.py index ff5c8533..4dae53b2 100644 --- a/pyrogram/client/methods/messages/send_poll.py +++ b/pyrogram/client/methods/messages/send_poll.py @@ -38,7 +38,7 @@ class SendPoll(BaseClient): "pyrogram.ForceReply" ] = None ) -> "pyrogram.Message": - """Use this method to send a new poll. + """Send a new poll. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_sticker.py b/pyrogram/client/methods/messages/send_sticker.py index 0e314641..cabe3487 100644 --- a/pyrogram/client/methods/messages/send_sticker.py +++ b/pyrogram/client/methods/messages/send_sticker.py @@ -43,7 +43,7 @@ class SendSticker(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send .webp stickers. + """Send .webp stickers. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_venue.py b/pyrogram/client/methods/messages/send_venue.py index 1045bdbd..35545c9b 100644 --- a/pyrogram/client/methods/messages/send_venue.py +++ b/pyrogram/client/methods/messages/send_venue.py @@ -42,7 +42,7 @@ class SendVenue(BaseClient): "pyrogram.ForceReply" ] = None ) -> "pyrogram.Message": - """Use this method to send information about a venue. + """Send information about a venue. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_video.py b/pyrogram/client/methods/messages/send_video.py index baa91d29..92066e19 100644 --- a/pyrogram/client/methods/messages/send_video.py +++ b/pyrogram/client/methods/messages/send_video.py @@ -50,7 +50,7 @@ class SendVideo(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send video files. + """Send video files. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_video_note.py b/pyrogram/client/methods/messages/send_video_note.py index 9f934efe..8886c588 100644 --- a/pyrogram/client/methods/messages/send_video_note.py +++ b/pyrogram/client/methods/messages/send_video_note.py @@ -46,7 +46,7 @@ class SendVideoNote(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send video messages. + """Send video messages. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_voice.py b/pyrogram/client/methods/messages/send_voice.py index e7ec2b11..3631d828 100644 --- a/pyrogram/client/methods/messages/send_voice.py +++ b/pyrogram/client/methods/messages/send_voice.py @@ -46,7 +46,7 @@ class SendVoice(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Use this method to send audio files. + """Send audio files. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/stop_poll.py b/pyrogram/client/methods/messages/stop_poll.py index 4179cce4..6abe6791 100644 --- a/pyrogram/client/methods/messages/stop_poll.py +++ b/pyrogram/client/methods/messages/stop_poll.py @@ -30,7 +30,7 @@ class StopPoll(BaseClient): message_id: int, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Poll": - """Use this method to stop a poll which was sent by you. + """Stop a poll which was sent by you. Stopped polls can't be reopened and nobody will be able to vote in it anymore. diff --git a/pyrogram/client/methods/messages/vote_poll.py b/pyrogram/client/methods/messages/vote_poll.py index 5e7b8ce8..a5d77d86 100644 --- a/pyrogram/client/methods/messages/vote_poll.py +++ b/pyrogram/client/methods/messages/vote_poll.py @@ -30,7 +30,7 @@ class VotePoll(BaseClient): message_id: id, option: int ) -> "pyrogram.Poll": - """Use this method to vote a poll. + """Vote a poll. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/password/change_cloud_password.py b/pyrogram/client/methods/password/change_cloud_password.py index b9ee37d5..a33b83c7 100644 --- a/pyrogram/client/methods/password/change_cloud_password.py +++ b/pyrogram/client/methods/password/change_cloud_password.py @@ -30,7 +30,7 @@ class ChangeCloudPassword(BaseClient): new_password: str, new_hint: str = "" ) -> bool: - """Use this method to change your Two-Step Verification password (Cloud Password) with a new one. + """Change your Two-Step Verification password (Cloud Password) with a new one. Parameters: current_password (``str``): diff --git a/pyrogram/client/methods/password/enable_cloud_password.py b/pyrogram/client/methods/password/enable_cloud_password.py index e2e05633..23ee1608 100644 --- a/pyrogram/client/methods/password/enable_cloud_password.py +++ b/pyrogram/client/methods/password/enable_cloud_password.py @@ -30,7 +30,7 @@ class EnableCloudPassword(BaseClient): hint: str = "", email: str = None ) -> bool: - """Use this method to enable the Two-Step Verification security feature (Cloud Password) on your account. + """Enable the Two-Step Verification security feature (Cloud Password) on your account. This password will be asked when you log-in on a new device in addition to the SMS code. diff --git a/pyrogram/client/methods/password/remove_cloud_password.py b/pyrogram/client/methods/password/remove_cloud_password.py index 37160530..9dcbb005 100644 --- a/pyrogram/client/methods/password/remove_cloud_password.py +++ b/pyrogram/client/methods/password/remove_cloud_password.py @@ -26,7 +26,7 @@ class RemoveCloudPassword(BaseClient): self, password: str ) -> bool: - """Use this method to turn off the Two-Step Verification security feature (Cloud Password) on your account. + """Turn off the Two-Step Verification security feature (Cloud Password) on your account. Parameters: password (``str``): diff --git a/pyrogram/client/methods/users/delete_user_profile_photos.py b/pyrogram/client/methods/users/delete_user_profile_photos.py index 4e962245..305fd554 100644 --- a/pyrogram/client/methods/users/delete_user_profile_photos.py +++ b/pyrogram/client/methods/users/delete_user_profile_photos.py @@ -29,7 +29,7 @@ class DeleteUserProfilePhotos(BaseClient): self, id: Union[str, List[str]] ) -> bool: - """Use this method to delete your own profile photos. + """Delete your own profile photos. Parameters: id (``str`` | ``list``): diff --git a/pyrogram/client/methods/users/get_me.py b/pyrogram/client/methods/users/get_me.py index 03d3cdf1..44f16af3 100644 --- a/pyrogram/client/methods/users/get_me.py +++ b/pyrogram/client/methods/users/get_me.py @@ -23,7 +23,7 @@ from ...ext import BaseClient class GetMe(BaseClient): def get_me(self) -> "pyrogram.User": - """A simple method for testing your authorization. Requires no parameters. + """Get your own user identity. Returns: :obj:`User`: Basic information about the user or bot. diff --git a/pyrogram/client/methods/users/get_user_profile_photos.py b/pyrogram/client/methods/users/get_user_profile_photos.py index 41dd2593..ab58dbec 100644 --- a/pyrogram/client/methods/users/get_user_profile_photos.py +++ b/pyrogram/client/methods/users/get_user_profile_photos.py @@ -30,7 +30,7 @@ class GetUserProfilePhotos(BaseClient): offset: int = 0, limit: int = 100 ) -> "pyrogram.UserProfilePhotos": - """Use this method to get a list of profile pictures for a user. + """Get a list of profile pictures for a user. Parameters: user_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/users/get_user_profile_photos_count.py b/pyrogram/client/methods/users/get_user_profile_photos_count.py index 595352c3..f5526584 100644 --- a/pyrogram/client/methods/users/get_user_profile_photos_count.py +++ b/pyrogram/client/methods/users/get_user_profile_photos_count.py @@ -24,7 +24,7 @@ from ...ext import BaseClient class GetUserProfilePhotosCount(BaseClient): def get_user_profile_photos_count(self, user_id: Union[int, str]) -> int: - """Use this method to get the total count of profile pictures for a user. + """Get the total count of profile pictures for a user. Parameters: user_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/users/get_users.py b/pyrogram/client/methods/users/get_users.py index bbcdebae..e95fedc7 100644 --- a/pyrogram/client/methods/users/get_users.py +++ b/pyrogram/client/methods/users/get_users.py @@ -28,7 +28,7 @@ class GetUsers(BaseClient): self, user_ids: Union[Iterable[Union[int, str]], int, str] ) -> Union["pyrogram.User", List["pyrogram.User"]]: - """Use this method to get information about a user. + """Get information about a user. You can retrieve up to 200 users at once. Parameters: diff --git a/pyrogram/client/methods/users/set_user_profile_photo.py b/pyrogram/client/methods/users/set_user_profile_photo.py index e873cf40..bc056466 100644 --- a/pyrogram/client/methods/users/set_user_profile_photo.py +++ b/pyrogram/client/methods/users/set_user_profile_photo.py @@ -25,7 +25,7 @@ class SetUserProfilePhoto(BaseClient): self, photo: str ) -> bool: - """Use this method to set a new profile photo. + """Set a new profile photo. This method only works for Users. Bots profile photos must be set using BotFather. diff --git a/pyrogram/client/methods/users/update_username.py b/pyrogram/client/methods/users/update_username.py index 8b5b37ae..65b86174 100644 --- a/pyrogram/client/methods/users/update_username.py +++ b/pyrogram/client/methods/users/update_username.py @@ -27,7 +27,7 @@ class UpdateUsername(BaseClient): self, username: Union[str, None] ) -> bool: - """Use this method to update your own username. + """Update your own username. This method only works for users, not bots. Bot usernames must be changed via Bot Support or by recreating them from scratch using BotFather. To update a channel or supergroup username you can use diff --git a/pyrogram/client/types/inline_mode/inline_query.py b/pyrogram/client/types/inline_mode/inline_query.py index a5190452..ab546b5e 100644 --- a/pyrogram/client/types/inline_mode/inline_query.py +++ b/pyrogram/client/types/inline_mode/inline_query.py @@ -28,7 +28,8 @@ from ..user_and_chats import User class InlineQuery(PyrogramType, Update): - """This object represents an incoming inline query. + """An incoming inline query. + When the user sends an empty query, your bot could return some default or trending results. Parameters: diff --git a/pyrogram/client/types/inline_mode/inline_query_result.py b/pyrogram/client/types/inline_mode/inline_query_result.py index 3e7fcb02..c9a46ff2 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result.py +++ b/pyrogram/client/types/inline_mode/inline_query_result.py @@ -40,7 +40,7 @@ from ..pyrogram_type import PyrogramType class InlineQueryResult(PyrogramType): - """This object represents one result of an inline query. + """One result of an inline query. Pyrogram currently supports results of the following 20 types: 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 bc0b4e20..8543eb4c 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result_article.py +++ b/pyrogram/client/types/inline_mode/inline_query_result_article.py @@ -23,7 +23,7 @@ from .inline_query_result import InlineQueryResult class InlineQueryResultArticle(InlineQueryResult): - """Represents a link to an article or web page. + """Link to an article or web page. TODO: Hide url? diff --git a/pyrogram/client/types/input_media/input_media.py b/pyrogram/client/types/input_media/input_media.py index 1e0fbc01..551ca639 100644 --- a/pyrogram/client/types/input_media/input_media.py +++ b/pyrogram/client/types/input_media/input_media.py @@ -20,7 +20,9 @@ from ..pyrogram_type import PyrogramType class InputMedia(PyrogramType): - """This object represents the content of a media message to be sent. It should be one of: + """Content of a media message to be sent. + + It should be one of: - :obj:`InputMediaAnimation` - :obj:`InputMediaDocument` diff --git a/pyrogram/client/types/input_media/input_media_animation.py b/pyrogram/client/types/input_media/input_media_animation.py index 177bd9ad..23fcb967 100644 --- a/pyrogram/client/types/input_media/input_media_animation.py +++ b/pyrogram/client/types/input_media/input_media_animation.py @@ -20,7 +20,7 @@ from . import InputMedia class InputMediaAnimation(InputMedia): - """This object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent. + """An animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent inside an album. Parameters: 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 152532fa..3fb45d8f 100644 --- a/pyrogram/client/types/input_media/input_media_audio.py +++ b/pyrogram/client/types/input_media/input_media_audio.py @@ -20,7 +20,8 @@ from . import InputMedia class InputMediaAudio(InputMedia): - """This object represents an audio to be sent inside an album. + """An audio to be sent inside an album. + It is intended to be used with :obj:`send_media_group() `. Parameters: diff --git a/pyrogram/client/types/input_media/input_media_document.py b/pyrogram/client/types/input_media/input_media_document.py index 046b731c..0de8dedf 100644 --- a/pyrogram/client/types/input_media/input_media_document.py +++ b/pyrogram/client/types/input_media/input_media_document.py @@ -20,7 +20,7 @@ from . import InputMedia class InputMediaDocument(InputMedia): - """This object represents a general file to be sent. + """A generic file to be sent inside an album. Parameters: 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 2797bd5f..ce134af2 100644 --- a/pyrogram/client/types/input_media/input_media_photo.py +++ b/pyrogram/client/types/input_media/input_media_photo.py @@ -20,7 +20,7 @@ from . import InputMedia class InputMediaPhoto(InputMedia): - """This object represents a photo to be sent inside an album. + """A photo to be sent inside an album. It is intended to be used with :obj:`send_media_group() `. Parameters: diff --git a/pyrogram/client/types/input_media/input_media_video.py b/pyrogram/client/types/input_media/input_media_video.py index 319973de..9764dd1a 100644 --- a/pyrogram/client/types/input_media/input_media_video.py +++ b/pyrogram/client/types/input_media/input_media_video.py @@ -20,7 +20,7 @@ from . import InputMedia class InputMediaVideo(InputMedia): - """This object represents a video to be sent inside an album. + """A video to be sent inside an album. It is intended to be used with :obj:`send_media_group() `. Parameters: diff --git a/pyrogram/client/types/input_media/input_phone_contact.py b/pyrogram/client/types/input_media/input_phone_contact.py index 02189011..0b6353b7 100644 --- a/pyrogram/client/types/input_media/input_phone_contact.py +++ b/pyrogram/client/types/input_media/input_phone_contact.py @@ -22,7 +22,7 @@ from ..pyrogram_type import PyrogramType class InputPhoneContact(PyrogramType): - """This object represents a Phone Contact to be added in your Telegram address book. + """A Phone Contact to be added in your Telegram address book. It is intended to be used with :meth:`add_contacts() ` Parameters: 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 f3e238b8..0cd264b7 100644 --- a/pyrogram/client/types/input_message_content/input_message_content.py +++ b/pyrogram/client/types/input_message_content/input_message_content.py @@ -24,7 +24,7 @@ from ..pyrogram_type import PyrogramType class InputMessageContent(PyrogramType): - """This object represents the content of a message to be sent as a result of an inline query. + """Content of a message to be sent as a result of an inline query. Pyrogram currently supports the following 4 types: 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 feedd298..4b294aab 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 @@ -22,7 +22,7 @@ from ...style import HTML, Markdown class InputTextMessageContent(InputMessageContent): - """This object represents the content of a text message to be sent as the result of an inline query. + """Content of a text message to be sent as the result of an inline query. Parameters: message_text (``str``): diff --git a/pyrogram/client/types/keyboards/callback_game.py b/pyrogram/client/types/keyboards/callback_game.py index fc2d9884..b7397075 100644 --- a/pyrogram/client/types/keyboards/callback_game.py +++ b/pyrogram/client/types/keyboards/callback_game.py @@ -20,7 +20,7 @@ from ..pyrogram_type import PyrogramType class CallbackGame(PyrogramType): - """A placeholder, currently holds no information. + """Placeholder, currently holds no information. Use BotFather to set up your game. """ diff --git a/pyrogram/client/types/keyboards/callback_query.py b/pyrogram/client/types/keyboards/callback_query.py index 61bbfe40..e58f77c2 100644 --- a/pyrogram/client/types/keyboards/callback_query.py +++ b/pyrogram/client/types/keyboards/callback_query.py @@ -27,7 +27,8 @@ from ..user_and_chats import User class CallbackQuery(PyrogramType, Update): - """This object represents an incoming callback query from a callback button in an inline keyboard. + """An incoming callback query from a callback button in an inline keyboard. + If the button that originated the query was attached to a message sent by the bot, the field message will be present. If the button was attached to a message sent via the bot (in inline mode), the field inline_message_id will be present. Exactly one of the fields data or game_short_name will be present. diff --git a/pyrogram/client/types/keyboards/force_reply.py b/pyrogram/client/types/keyboards/force_reply.py index f48dab14..f2d337b6 100644 --- a/pyrogram/client/types/keyboards/force_reply.py +++ b/pyrogram/client/types/keyboards/force_reply.py @@ -21,7 +21,9 @@ from ..pyrogram_type import PyrogramType class ForceReply(PyrogramType): - """Upon receiving a message with this object, Telegram clients will display a reply interface to the user. + """Object used to force clients to show a reply interface. + + Upon receiving a message with this object, Telegram clients will display a reply interface to the user. This acts as if the user has selected the bot's message and tapped "Reply". This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to diff --git a/pyrogram/client/types/keyboards/game_high_score.py b/pyrogram/client/types/keyboards/game_high_score.py index 07db8e73..302decec 100644 --- a/pyrogram/client/types/keyboards/game_high_score.py +++ b/pyrogram/client/types/keyboards/game_high_score.py @@ -24,7 +24,7 @@ from pyrogram.client.types.user_and_chats import User class GameHighScore(PyrogramType): - """This object represents one row of the high scores table for a game. + """One row of the high scores table for a game. Parameters: user (:obj:`User`): diff --git a/pyrogram/client/types/keyboards/game_high_scores.py b/pyrogram/client/types/keyboards/game_high_scores.py index 36b14c0f..1c2cf105 100644 --- a/pyrogram/client/types/keyboards/game_high_scores.py +++ b/pyrogram/client/types/keyboards/game_high_scores.py @@ -25,7 +25,7 @@ from .game_high_score import GameHighScore class GameHighScores(PyrogramType): - """This object represents the high scores table for a game. + """The high scores table for a game. Parameters: total_count (``int``): diff --git a/pyrogram/client/types/keyboards/inline_keyboard_button.py b/pyrogram/client/types/keyboards/inline_keyboard_button.py index ea110f7f..358eae21 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_button.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_button.py @@ -27,7 +27,9 @@ from ..pyrogram_type import PyrogramType class InlineKeyboardButton(PyrogramType): - """This object represents one button of an inline keyboard. You must use exactly one of the optional fields. + """One button of an inline keyboard. + + You must use exactly one of the optional fields. Parameters: text (``str``): diff --git a/pyrogram/client/types/keyboards/inline_keyboard_markup.py b/pyrogram/client/types/keyboards/inline_keyboard_markup.py index f48f4b8c..c940fa1a 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_markup.py @@ -24,7 +24,7 @@ from ..pyrogram_type import PyrogramType class InlineKeyboardMarkup(PyrogramType): - """This object represents an inline keyboard that appears right next to the message it belongs to. + """An inline keyboard that appears right next to the message it belongs to. Parameters: inline_keyboard (List of List of :obj:`InlineKeyboardButton`): diff --git a/pyrogram/client/types/keyboards/keyboard_button.py b/pyrogram/client/types/keyboards/keyboard_button.py index e0393e3d..405e37b5 100644 --- a/pyrogram/client/types/keyboards/keyboard_button.py +++ b/pyrogram/client/types/keyboards/keyboard_button.py @@ -22,7 +22,7 @@ from ..pyrogram_type import PyrogramType class KeyboardButton(PyrogramType): - """This object represents one button of the reply keyboard. + """One button of the reply keyboard. For simple text buttons String can be used instead of this object to specify text of the button. Optional fields are mutually exclusive. diff --git a/pyrogram/client/types/keyboards/reply_keyboard_markup.py b/pyrogram/client/types/keyboards/reply_keyboard_markup.py index 32c73c6b..85ab16f4 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_markup.py @@ -25,7 +25,7 @@ from ..pyrogram_type import PyrogramType class ReplyKeyboardMarkup(PyrogramType): - """This object represents a custom keyboard with reply options. + """A custom keyboard with reply options. Parameters: keyboard (List of List of :obj:`KeyboardButton`): diff --git a/pyrogram/client/types/keyboards/reply_keyboard_remove.py b/pyrogram/client/types/keyboards/reply_keyboard_remove.py index 560c89ee..bb448447 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_remove.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_remove.py @@ -21,9 +21,12 @@ from ..pyrogram_type import PyrogramType class ReplyKeyboardRemove(PyrogramType): - """Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and display the default letter-keyboard. - By default, custom keyboards are displayed until a new keyboard is sent by a bot. An exception is made for one-time - keyboards that are hidden immediately after the user presses a button (see ReplyKeyboardMarkup). + """Object used to tell clients to remove a bot keyboard. + + Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and display + the default letter-keyboard. By default, custom keyboards are displayed until a new keyboard is sent by a bot. + An exception is made for one-time keyboards that are hidden immediately after the user presses a button + (see ReplyKeyboardMarkup). Parameters: selective (``bool``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index 25dda78e..8d889cc2 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -26,7 +26,7 @@ from ...ext.utils import encode class Animation(PyrogramType): - """This object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound). + """An animation file (GIF or H.264/MPEG-4 AVC video without sound). Parameters: file_id (``str``): diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index 9f024ee1..704f4f75 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -26,7 +26,7 @@ from ...ext.utils import encode class Audio(PyrogramType): - """This object represents an audio file to be treated as music by the Telegram clients. + """An audio file to be treated as music by the Telegram clients. Parameters: file_id (``str``): diff --git a/pyrogram/client/types/messages_and_media/contact.py b/pyrogram/client/types/messages_and_media/contact.py index e2fba707..fb4eb3a6 100644 --- a/pyrogram/client/types/messages_and_media/contact.py +++ b/pyrogram/client/types/messages_and_media/contact.py @@ -23,7 +23,7 @@ from ..pyrogram_type import PyrogramType class Contact(PyrogramType): - """This object represents a phone contact. + """A phone contact. Parameters: phone_number (``str``): diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index c4c8ab16..754fc5af 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -26,7 +26,7 @@ from ...ext.utils import encode class Document(PyrogramType): - """This object represents a general file (as opposed to photos, voice messages, audio files, ...). + """A generic file (as opposed to photos, voice messages, audio files, ...). Parameters: file_id (``str``): diff --git a/pyrogram/client/types/messages_and_media/game.py b/pyrogram/client/types/messages_and_media/game.py index 50268153..b4c96a11 100644 --- a/pyrogram/client/types/messages_and_media/game.py +++ b/pyrogram/client/types/messages_and_media/game.py @@ -24,7 +24,7 @@ from ..pyrogram_type import PyrogramType class Game(PyrogramType): - """This object represents a game. + """A game. Use BotFather to create and edit games, their short names will act as unique identifiers. Parameters: diff --git a/pyrogram/client/types/messages_and_media/location.py b/pyrogram/client/types/messages_and_media/location.py index 6af918f7..c3d8f974 100644 --- a/pyrogram/client/types/messages_and_media/location.py +++ b/pyrogram/client/types/messages_and_media/location.py @@ -23,7 +23,7 @@ from ..pyrogram_type import PyrogramType class Location(PyrogramType): - """This object represents a point on the map. + """A point on the map. Parameters: longitude (``float``): diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index a4d759c8..28a5d0ea 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -60,7 +60,7 @@ class Str(str): class Message(PyrogramType, Update): - """This object represents a message. + """A message. Parameters: message_id (``int``): diff --git a/pyrogram/client/types/messages_and_media/message_entity.py b/pyrogram/client/types/messages_and_media/message_entity.py index 6fe4ef91..768dee1e 100644 --- a/pyrogram/client/types/messages_and_media/message_entity.py +++ b/pyrogram/client/types/messages_and_media/message_entity.py @@ -24,7 +24,7 @@ from ..user_and_chats.user import User class MessageEntity(PyrogramType): - """This object represents one special entity in a text message. + """One special entity in a text message. For example, hashtags, usernames, URLs, etc. Parameters: diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py index 4ce41aec..4f930a22 100644 --- a/pyrogram/client/types/messages_and_media/messages.py +++ b/pyrogram/client/types/messages_and_media/messages.py @@ -27,7 +27,7 @@ from ..user_and_chats import Chat class Messages(PyrogramType, Update): - """This object represents a chat's messages. + """Contains a chat's messages. Parameters: total_count (``int``): diff --git a/pyrogram/client/types/messages_and_media/photo.py b/pyrogram/client/types/messages_and_media/photo.py index f7f9f4ec..c2d0eb1f 100644 --- a/pyrogram/client/types/messages_and_media/photo.py +++ b/pyrogram/client/types/messages_and_media/photo.py @@ -28,7 +28,7 @@ from ...ext.utils import encode class Photo(PyrogramType): - """This object represents a Photo. + """A Photo. Parameters: id (``str``): diff --git a/pyrogram/client/types/messages_and_media/photo_size.py b/pyrogram/client/types/messages_and_media/photo_size.py index a154c077..c76ef914 100644 --- a/pyrogram/client/types/messages_and_media/photo_size.py +++ b/pyrogram/client/types/messages_and_media/photo_size.py @@ -26,7 +26,7 @@ from ..pyrogram_type import PyrogramType class PhotoSize(PyrogramType): - """This object represents one size of a photo or a file/sticker thumbnail. + """One size of a photo or a file/sticker thumbnail. Parameters: file_id (``str``): diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index 602da364..8aa32137 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -26,7 +26,7 @@ from ..update import Update class Poll(PyrogramType, Update): - """This object represents a Poll. + """A Poll. Parameters: id (``str``): diff --git a/pyrogram/client/types/messages_and_media/poll_option.py b/pyrogram/client/types/messages_and_media/poll_option.py index 31eed702..e594e3ca 100644 --- a/pyrogram/client/types/messages_and_media/poll_option.py +++ b/pyrogram/client/types/messages_and_media/poll_option.py @@ -21,7 +21,7 @@ from ..pyrogram_type import PyrogramType class PollOption(PyrogramType): - """This object contains information about one answer option in a poll. + """Contains information about one answer option in a poll. Parameters: text (``str``): diff --git a/pyrogram/client/types/messages_and_media/sticker.py b/pyrogram/client/types/messages_and_media/sticker.py index e6b8de35..0a3a42d1 100644 --- a/pyrogram/client/types/messages_and_media/sticker.py +++ b/pyrogram/client/types/messages_and_media/sticker.py @@ -28,7 +28,7 @@ from ...ext.utils import encode class Sticker(PyrogramType): - """This object represents a sticker. + """A sticker. Parameters: file_id (``str``): diff --git a/pyrogram/client/types/messages_and_media/user_profile_photos.py b/pyrogram/client/types/messages_and_media/user_profile_photos.py index 66bcb51a..c74a371b 100644 --- a/pyrogram/client/types/messages_and_media/user_profile_photos.py +++ b/pyrogram/client/types/messages_and_media/user_profile_photos.py @@ -24,7 +24,7 @@ from ..pyrogram_type import PyrogramType class UserProfilePhotos(PyrogramType): - """This object represents a user's profile pictures. + """Contains a user's profile pictures. Parameters: total_count (``int``): diff --git a/pyrogram/client/types/messages_and_media/venue.py b/pyrogram/client/types/messages_and_media/venue.py index 61e3d912..cac84e57 100644 --- a/pyrogram/client/types/messages_and_media/venue.py +++ b/pyrogram/client/types/messages_and_media/venue.py @@ -23,7 +23,7 @@ from ..pyrogram_type import PyrogramType class Venue(PyrogramType): - """This object represents a venue. + """A venue. Parameters: location (:obj:`Location`): diff --git a/pyrogram/client/types/messages_and_media/video.py b/pyrogram/client/types/messages_and_media/video.py index 8c3e9c00..13980270 100644 --- a/pyrogram/client/types/messages_and_media/video.py +++ b/pyrogram/client/types/messages_and_media/video.py @@ -26,7 +26,7 @@ from ...ext.utils import encode class Video(PyrogramType): - """This object represents a video file. + """A video file. Parameters: file_id (``str``): diff --git a/pyrogram/client/types/messages_and_media/video_note.py b/pyrogram/client/types/messages_and_media/video_note.py index 59c60c6e..5ebc8774 100644 --- a/pyrogram/client/types/messages_and_media/video_note.py +++ b/pyrogram/client/types/messages_and_media/video_note.py @@ -26,7 +26,7 @@ from ...ext.utils import encode class VideoNote(PyrogramType): - """This object represents a video note. + """A video note. Parameters: file_id (``str``): diff --git a/pyrogram/client/types/messages_and_media/voice.py b/pyrogram/client/types/messages_and_media/voice.py index 87804826..88154e2f 100644 --- a/pyrogram/client/types/messages_and_media/voice.py +++ b/pyrogram/client/types/messages_and_media/voice.py @@ -25,7 +25,7 @@ from ...ext.utils import encode class Voice(PyrogramType): - """This object represents a voice note. + """A voice note. Parameters: file_id (``str``): diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 0c6210eb..3b5f242b 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -26,7 +26,7 @@ from ..pyrogram_type import PyrogramType class Chat(PyrogramType): - """This object represents a chat. + """A chat. Parameters: id (``int``): diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 9841af83..9de9986a 100644 --- a/pyrogram/client/types/user_and_chats/chat_member.py +++ b/pyrogram/client/types/user_and_chats/chat_member.py @@ -23,7 +23,7 @@ from ..pyrogram_type import PyrogramType class ChatMember(PyrogramType): - """This object contains information about one member of a chat. + """Contains information about one member of a chat. Parameters: user (:obj:`User`): diff --git a/pyrogram/client/types/user_and_chats/chat_members.py b/pyrogram/client/types/user_and_chats/chat_members.py index d7cf3b9a..8f98277c 100644 --- a/pyrogram/client/types/user_and_chats/chat_members.py +++ b/pyrogram/client/types/user_and_chats/chat_members.py @@ -25,7 +25,7 @@ from ..pyrogram_type import PyrogramType class ChatMembers(PyrogramType): - """This object contains information about the members list of a chat. + """Contains information about the members list of a chat. Parameters: total_count (``int``): diff --git a/pyrogram/client/types/user_and_chats/chat_permissions.py b/pyrogram/client/types/user_and_chats/chat_permissions.py index ec00272e..6fa1a2a8 100644 --- a/pyrogram/client/types/user_and_chats/chat_permissions.py +++ b/pyrogram/client/types/user_and_chats/chat_permissions.py @@ -23,7 +23,7 @@ from ..pyrogram_type import PyrogramType class ChatPermissions(PyrogramType): - """This object represents both a chat default permissions and a single member permissions within a chat. + """A chat default permissions and a single member permissions within a chat. Some permissions make sense depending on the context: default chat permissions, restricted/kicked member or administrators in groups or channels. diff --git a/pyrogram/client/types/user_and_chats/chat_photo.py b/pyrogram/client/types/user_and_chats/chat_photo.py index af4f2df4..3f1f7cc6 100644 --- a/pyrogram/client/types/user_and_chats/chat_photo.py +++ b/pyrogram/client/types/user_and_chats/chat_photo.py @@ -25,7 +25,7 @@ from ...ext.utils import encode class ChatPhoto(PyrogramType): - """This object represents a chat photo. + """a chat photo. Parameters: small_file_id (``str``): diff --git a/pyrogram/client/types/user_and_chats/chat_preview.py b/pyrogram/client/types/user_and_chats/chat_preview.py index b6b136a1..880dcc8e 100644 --- a/pyrogram/client/types/user_and_chats/chat_preview.py +++ b/pyrogram/client/types/user_and_chats/chat_preview.py @@ -26,7 +26,7 @@ from ..user_and_chats.user import User class ChatPreview(PyrogramType): - """This object represents a chat preview. + """A chat preview. Parameters: title (``str``): diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index ec011d81..3dc09dbc 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -24,7 +24,7 @@ from ..user_and_chats import Chat class Dialog(PyrogramType): - """This object represents a dialog. + """A user's dialog. Parameters: chat (:obj:`Chat `): diff --git a/pyrogram/client/types/user_and_chats/dialogs.py b/pyrogram/client/types/user_and_chats/dialogs.py index 97ca462b..43b9f667 100644 --- a/pyrogram/client/types/user_and_chats/dialogs.py +++ b/pyrogram/client/types/user_and_chats/dialogs.py @@ -26,7 +26,7 @@ from ..pyrogram_type import PyrogramType class Dialogs(PyrogramType): - """This object represents a user's dialogs chunk. + """Contains a user's dialogs chunk. Parameters: total_count (``int``): diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 976ce5a0..c5a0976c 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -24,7 +24,7 @@ from ..pyrogram_type import PyrogramType class User(PyrogramType): - """This object represents a Telegram user or bot. + """A Telegram user or bot. Parameters: id (``int``): diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index 0f9c003e..f91c2924 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -24,7 +24,7 @@ from ..update import Update class UserStatus(PyrogramType, Update): - """This object represents a User status (Last Seen privacy). + """A User status (Last Seen privacy). .. note:: From 0e80b39c2c373de676cc00704da9d0486d64c401 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 15:57:49 +0200 Subject: [PATCH 054/202] Build a much cleaner errors reference page --- docs/source/api/errors.rst | 75 ++++++++++++++++---- docs/source/errors/bad-request.rst | 7 -- docs/source/errors/flood.rst | 7 -- docs/source/errors/forbidden.rst | 7 -- docs/source/errors/internal-server-error.rst | 7 -- docs/source/errors/not-acceptable.rst | 7 -- docs/source/errors/see-other.rst | 7 -- docs/source/errors/unauthorized.rst | 7 -- docs/source/errors/unknown-error.rst | 7 -- docs/source/index.rst | 2 +- docs/source/topics/faq.rst | 2 +- 11 files changed, 62 insertions(+), 73 deletions(-) delete mode 100644 docs/source/errors/bad-request.rst delete mode 100644 docs/source/errors/flood.rst delete mode 100644 docs/source/errors/forbidden.rst delete mode 100644 docs/source/errors/internal-server-error.rst delete mode 100644 docs/source/errors/not-acceptable.rst delete mode 100644 docs/source/errors/see-other.rst delete mode 100644 docs/source/errors/unauthorized.rst delete mode 100644 docs/source/errors/unknown-error.rst diff --git a/docs/source/api/errors.rst b/docs/source/api/errors.rst index 51d1fcd3..29dcafac 100644 --- a/docs/source/api/errors.rst +++ b/docs/source/api/errors.rst @@ -1,28 +1,73 @@ RPC Errors ========== -All the Pyrogram errors listed here live inside the ``errors`` sub-package. +All Pyrogram API errors live inside the ``errors`` sub-package: ``pyrogram.errors``. +The errors ids listed here are shown as *UPPER_SNAKE_CASE*, but the actual exception names to import from Pyrogram +follow the usual *PascalCase* convention. -**Example:** +**Example**: .. code-block:: python - from pyrogram.errors import RPCError + from pyrogram.errors import InternalServerError try: ... - except RPCError: + except FloodWait: ... -.. autoexception:: pyrogram.RPCError() - :members: +303 - See Other +--------------- -.. toctree:: - ../errors/see-other - ../errors/bad-request - ../errors/unauthorized - ../errors/forbidden - ../errors/not-acceptable - ../errors/flood - ../errors/internal-server-error - ../errors/unknown-error +.. csv-table:: + :file: ../../../compiler/error/source/303_SEE_OTHER.tsv + :delim: tab + :header-rows: 1 + +400 - Bad Request +----------------- + +.. csv-table:: + :file: ../../../compiler/error/source/400_BAD_REQUEST.tsv + :delim: tab + :header-rows: 1 + +401 - Unauthorized +------------------ + +.. csv-table:: + :file: ../../../compiler/error/source/401_UNAUTHORIZED.tsv + :delim: tab + :header-rows: 1 + +403 - Forbidden +--------------- + +.. csv-table:: + :file: ../../../compiler/error/source/403_FORBIDDEN.tsv + :delim: tab + :header-rows: 1 + +406 - Not Acceptable +-------------------- + +.. csv-table:: + :file: ../../../compiler/error/source/406_NOT_ACCEPTABLE.tsv + :delim: tab + :header-rows: 1 + +420 - Flood +----------- + +.. csv-table:: + :file: ../../../compiler/error/source/420_FLOOD.tsv + :delim: tab + :header-rows: 1 + +500 - Internal Server Error +--------------------------- + +.. csv-table:: + :file: ../../../compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv + :delim: tab + :header-rows: 1 diff --git a/docs/source/errors/bad-request.rst b/docs/source/errors/bad-request.rst deleted file mode 100644 index 2d56434c..00000000 --- a/docs/source/errors/bad-request.rst +++ /dev/null @@ -1,7 +0,0 @@ -400 - Bad Request -================= - -.. module:: pyrogram.errors.BadRequest - -.. automodule:: pyrogram.errors.exceptions.bad_request_400 - :members: diff --git a/docs/source/errors/flood.rst b/docs/source/errors/flood.rst deleted file mode 100644 index 55098cbb..00000000 --- a/docs/source/errors/flood.rst +++ /dev/null @@ -1,7 +0,0 @@ -420 - Flood -=========== - -.. module:: pyrogram.errors.Flood - -.. automodule:: pyrogram.errors.exceptions.flood_420 - :members: diff --git a/docs/source/errors/forbidden.rst b/docs/source/errors/forbidden.rst deleted file mode 100644 index cd794979..00000000 --- a/docs/source/errors/forbidden.rst +++ /dev/null @@ -1,7 +0,0 @@ -403 - Forbidden -=============== - -.. module:: pyrogram.errors.Forbidden - -.. automodule:: pyrogram.errors.exceptions.forbidden_403 - :members: diff --git a/docs/source/errors/internal-server-error.rst b/docs/source/errors/internal-server-error.rst deleted file mode 100644 index 7f78d519..00000000 --- a/docs/source/errors/internal-server-error.rst +++ /dev/null @@ -1,7 +0,0 @@ -500 - Internal Server Error -=========================== - -.. module:: pyrogram.errors.InternalServerError - -.. automodule:: pyrogram.errors.exceptions.internal_server_error_500 - :members: diff --git a/docs/source/errors/not-acceptable.rst b/docs/source/errors/not-acceptable.rst deleted file mode 100644 index 5a8365fc..00000000 --- a/docs/source/errors/not-acceptable.rst +++ /dev/null @@ -1,7 +0,0 @@ -406 - Not Acceptable -==================== - -.. module:: pyrogram.errors.NotAcceptable - -.. automodule:: pyrogram.errors.exceptions.not_acceptable_406 - :members: diff --git a/docs/source/errors/see-other.rst b/docs/source/errors/see-other.rst deleted file mode 100644 index f90902d0..00000000 --- a/docs/source/errors/see-other.rst +++ /dev/null @@ -1,7 +0,0 @@ -303 - See Other -=============== - -.. module:: pyrogram.errors.SeeOther - -.. automodule:: pyrogram.errors.exceptions.see_other_303 - :members: diff --git a/docs/source/errors/unauthorized.rst b/docs/source/errors/unauthorized.rst deleted file mode 100644 index d47ed3fb..00000000 --- a/docs/source/errors/unauthorized.rst +++ /dev/null @@ -1,7 +0,0 @@ -401 - Unauthorized -================== - -.. module:: pyrogram.errors.Unauthorized - -.. automodule:: pyrogram.errors.exceptions.unauthorized_401 - :members: diff --git a/docs/source/errors/unknown-error.rst b/docs/source/errors/unknown-error.rst deleted file mode 100644 index 21495957..00000000 --- a/docs/source/errors/unknown-error.rst +++ /dev/null @@ -1,7 +0,0 @@ -520 - Unknown Error -=================== - -.. module:: pyrogram.errors.UnknownError - -.. autoexception:: pyrogram.errors.rpc_error.UnknownError - :members: diff --git a/docs/source/index.rst b/docs/source/index.rst index ae6a2fda..81b4213c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -157,4 +157,4 @@ Topics :caption: Telegram API telegram/functions/index - telegram/types/index + telegram/types/index \ No newline at end of file diff --git a/docs/source/topics/faq.rst b/docs/source/topics/faq.rst index f647e261..5a8a3929 100644 --- a/docs/source/topics/faq.rst +++ b/docs/source/topics/faq.rst @@ -68,7 +68,7 @@ in a bunch of seconds: I keep getting [400 PEER_ID_INVALID] error! ------------------------------------------- -The error in question is ``[400 PEER_ID_INVALID]: The id/access_hash combination is invalid``, and could mean several +The error in question is **[400 PEER_ID_INVALID]: The id/access_hash combination is invalid**, and could mean several things: - The chat id you tried to use is simply wrong, double check it. From 65c07b7d3417189ab750842b6138357772fdd870 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 16:06:34 +0200 Subject: [PATCH 055/202] Use a better repr for all types now eval(repr(obj) == obj --- pyrogram/api/core/object.py | 62 +++++++++++-------- .../client/types/inline_mode/inline_query.py | 3 +- .../types/inline_mode/inline_query_result.py | 2 +- .../client/types/input_media/input_media.py | 2 +- .../input_message_content.py | 2 +- .../client/types/keyboards/callback_game.py | 2 +- .../client/types/keyboards/callback_query.py | 2 +- .../client/types/keyboards/force_reply.py | 2 +- .../client/types/keyboards/game_high_score.py | 2 +- .../types/keyboards/game_high_scores.py | 2 +- .../types/keyboards/inline_keyboard_button.py | 2 +- .../types/keyboards/inline_keyboard_markup.py | 2 +- .../client/types/keyboards/keyboard_button.py | 2 +- .../types/keyboards/reply_keyboard_markup.py | 2 +- .../types/keyboards/reply_keyboard_remove.py | 2 +- .../types/messages_and_media/animation.py | 2 +- .../client/types/messages_and_media/audio.py | 2 +- .../types/messages_and_media/contact.py | 2 +- .../types/messages_and_media/document.py | 2 +- .../client/types/messages_and_media/game.py | 2 +- .../types/messages_and_media/location.py | 2 +- .../types/messages_and_media/message.py | 4 +- .../messages_and_media/message_entity.py | 2 +- .../types/messages_and_media/messages.py | 2 +- .../client/types/messages_and_media/photo.py | 2 +- .../types/messages_and_media/photo_size.py | 2 +- .../client/types/messages_and_media/poll.py | 2 +- .../types/messages_and_media/poll_option.py | 9 ++- .../types/messages_and_media/sticker.py | 2 +- .../messages_and_media/user_profile_photos.py | 2 +- .../client/types/messages_and_media/venue.py | 2 +- .../client/types/messages_and_media/video.py | 2 +- .../types/messages_and_media/video_note.py | 2 +- .../client/types/messages_and_media/voice.py | 2 +- pyrogram/client/types/pyrogram_type.py | 61 ++++++++++-------- pyrogram/client/types/user_and_chats/chat.py | 2 +- .../types/user_and_chats/chat_member.py | 2 +- .../types/user_and_chats/chat_members.py | 2 +- .../client/types/user_and_chats/chat_photo.py | 2 +- .../types/user_and_chats/chat_preview.py | 2 +- .../client/types/user_and_chats/dialog.py | 2 +- .../client/types/user_and_chats/dialogs.py | 2 +- pyrogram/client/types/user_and_chats/user.py | 2 +- .../types/user_and_chats/user_status.py | 2 +- 44 files changed, 119 insertions(+), 98 deletions(-) diff --git a/pyrogram/api/core/object.py b/pyrogram/api/core/object.py index a479fb6e..ace7a59a 100644 --- a/pyrogram/api/core/object.py +++ b/pyrogram/api/core/object.py @@ -30,43 +30,51 @@ class Object: QUALNAME = "Base" @staticmethod - def read(b: BytesIO, *args): + def read(b: BytesIO, *args): # TODO: Rename b -> data return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args) def write(self, *args) -> bytes: pass + def __eq__(self, other: "Object") -> bool: + for attr in self.__slots__: + try: + if getattr(self, attr) != getattr(other, attr): + return False + except AttributeError: + return False + + return True + def __str__(self) -> str: + def default(obj: Object): + try: + return OrderedDict( + [("_", obj.QUALNAME)] + + [(attr, getattr(obj, attr)) + for attr in obj.__slots__ + if getattr(obj, attr) is not None] + ) + except AttributeError: + if isinstance(obj, datetime): + return obj.strftime("%d-%b-%Y %H:%M:%S") + else: + return repr(obj) + return dumps(self, indent=4, default=default, ensure_ascii=False) + def __repr__(self) -> str: + return "pyrogram.api.{}({})".format( + self.QUALNAME, + ", ".join( + "{}={}".format(attr, repr(getattr(self, attr))) + for attr in self.__slots__ + if getattr(self, attr) is not None + ) + ) + def __len__(self) -> int: return len(self.write()) def __getitem__(self, item): return getattr(self, item) - - -def remove_none(obj): - if isinstance(obj, (list, tuple, set)): - return type(obj)(remove_none(x) for x in obj if x is not None) - elif isinstance(obj, dict): - return type(obj)((remove_none(k), remove_none(v)) for k, v in obj.items() if k is not None and v is not None) - else: - return obj - - -def default(o: "Object"): - try: - content = {i: getattr(o, i) for i in o.__slots__} - - return remove_none( - OrderedDict( - [("_", o.QUALNAME)] - + [i for i in content.items()] - ) - ) - except AttributeError: - if isinstance(o, datetime): - return o.strftime("%d-%b-%Y %H:%M:%S") - else: - return repr(o) diff --git a/pyrogram/client/types/inline_mode/inline_query.py b/pyrogram/client/types/inline_mode/inline_query.py index ab546b5e..4d1c9a16 100644 --- a/pyrogram/client/types/inline_mode/inline_query.py +++ b/pyrogram/client/types/inline_mode/inline_query.py @@ -53,7 +53,7 @@ class InlineQuery(PyrogramType, Update): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, id: str, from_user: User, query: str, @@ -62,7 +62,6 @@ class InlineQuery(PyrogramType, Update): ): super().__init__(client) - self._client = client self.id = id self.from_user = from_user self.query = query diff --git a/pyrogram/client/types/inline_mode/inline_query_result.py b/pyrogram/client/types/inline_mode/inline_query_result.py index c9a46ff2..4b7f7ca3 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result.py +++ b/pyrogram/client/types/inline_mode/inline_query_result.py @@ -50,7 +50,7 @@ class InlineQueryResult(PyrogramType): __slots__ = ["type", "id"] def __init__(self, type: str, id: str): - super().__init__(None) + super().__init__() self.type = type self.id = id diff --git a/pyrogram/client/types/input_media/input_media.py b/pyrogram/client/types/input_media/input_media.py index 551ca639..8360862f 100644 --- a/pyrogram/client/types/input_media/input_media.py +++ b/pyrogram/client/types/input_media/input_media.py @@ -33,7 +33,7 @@ class InputMedia(PyrogramType): __slots__ = ["media", "caption", "parse_mode"] def __init__(self, media: str, caption: str, parse_mode: str): - super().__init__(None) + super().__init__() self.media = media self.caption = caption 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 0cd264b7..50e068b7 100644 --- a/pyrogram/client/types/input_message_content/input_message_content.py +++ b/pyrogram/client/types/input_message_content/input_message_content.py @@ -34,4 +34,4 @@ class InputMessageContent(PyrogramType): __slots__ = [] def __init__(self): - super().__init__(None) + super().__init__() diff --git a/pyrogram/client/types/keyboards/callback_game.py b/pyrogram/client/types/keyboards/callback_game.py index b7397075..4fa43a30 100644 --- a/pyrogram/client/types/keyboards/callback_game.py +++ b/pyrogram/client/types/keyboards/callback_game.py @@ -28,4 +28,4 @@ class CallbackGame(PyrogramType): __slots__ = [] def __init__(self): - super().__init__(None) + super().__init__() diff --git a/pyrogram/client/types/keyboards/callback_query.py b/pyrogram/client/types/keyboards/callback_query.py index e58f77c2..822ea234 100644 --- a/pyrogram/client/types/keyboards/callback_query.py +++ b/pyrogram/client/types/keyboards/callback_query.py @@ -64,7 +64,7 @@ class CallbackQuery(PyrogramType, Update): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, id: str, from_user: User, chat_instance: str, diff --git a/pyrogram/client/types/keyboards/force_reply.py b/pyrogram/client/types/keyboards/force_reply.py index f2d337b6..5b263d03 100644 --- a/pyrogram/client/types/keyboards/force_reply.py +++ b/pyrogram/client/types/keyboards/force_reply.py @@ -42,7 +42,7 @@ class ForceReply(PyrogramType): self, selective: bool = None ): - super().__init__(None) + super().__init__() self.selective = selective diff --git a/pyrogram/client/types/keyboards/game_high_score.py b/pyrogram/client/types/keyboards/game_high_score.py index 302decec..56389b17 100644 --- a/pyrogram/client/types/keyboards/game_high_score.py +++ b/pyrogram/client/types/keyboards/game_high_score.py @@ -42,7 +42,7 @@ class GameHighScore(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, user: User, score: int, position: int = None diff --git a/pyrogram/client/types/keyboards/game_high_scores.py b/pyrogram/client/types/keyboards/game_high_scores.py index 1c2cf105..8183b9b0 100644 --- a/pyrogram/client/types/keyboards/game_high_scores.py +++ b/pyrogram/client/types/keyboards/game_high_scores.py @@ -40,7 +40,7 @@ class GameHighScores(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, total_count: int, game_high_scores: List[GameHighScore] ): diff --git a/pyrogram/client/types/keyboards/inline_keyboard_button.py b/pyrogram/client/types/keyboards/inline_keyboard_button.py index 358eae21..7e9fd458 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_button.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_button.py @@ -71,7 +71,7 @@ class InlineKeyboardButton(PyrogramType): switch_inline_query_current_chat: str = None, callback_game: CallbackGame = None ): - super().__init__(None) + super().__init__() self.text = str(text) self.url = url diff --git a/pyrogram/client/types/keyboards/inline_keyboard_markup.py b/pyrogram/client/types/keyboards/inline_keyboard_markup.py index c940fa1a..c7230eaf 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_markup.py @@ -37,7 +37,7 @@ class InlineKeyboardMarkup(PyrogramType): self, inline_keyboard: List[List[InlineKeyboardButton]] ): - super().__init__(None) + super().__init__() self.inline_keyboard = inline_keyboard diff --git a/pyrogram/client/types/keyboards/keyboard_button.py b/pyrogram/client/types/keyboards/keyboard_button.py index 405e37b5..93d2e5ef 100644 --- a/pyrogram/client/types/keyboards/keyboard_button.py +++ b/pyrogram/client/types/keyboards/keyboard_button.py @@ -48,7 +48,7 @@ class KeyboardButton(PyrogramType): request_contact: bool = None, request_location: bool = None ): - super().__init__(None) + super().__init__() self.text = str(text) self.request_contact = request_contact diff --git a/pyrogram/client/types/keyboards/reply_keyboard_markup.py b/pyrogram/client/types/keyboards/reply_keyboard_markup.py index 85ab16f4..c4b37b7c 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_markup.py @@ -58,7 +58,7 @@ class ReplyKeyboardMarkup(PyrogramType): one_time_keyboard: bool = None, selective: bool = None ): - super().__init__(None) + super().__init__() self.keyboard = keyboard self.resize_keyboard = resize_keyboard diff --git a/pyrogram/client/types/keyboards/reply_keyboard_remove.py b/pyrogram/client/types/keyboards/reply_keyboard_remove.py index bb448447..9d6eb7d5 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_remove.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_remove.py @@ -43,7 +43,7 @@ class ReplyKeyboardRemove(PyrogramType): self, selective: bool = None ): - super().__init__(None) + super().__init__() self.selective = selective diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index 8d889cc2..cd6e03ab 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -62,7 +62,7 @@ class Animation(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, width: int, height: int, diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index 704f4f75..76181a22 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -62,7 +62,7 @@ class Audio(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, duration: int, thumb: PhotoSize = None, diff --git a/pyrogram/client/types/messages_and_media/contact.py b/pyrogram/client/types/messages_and_media/contact.py index fb4eb3a6..9205304e 100644 --- a/pyrogram/client/types/messages_and_media/contact.py +++ b/pyrogram/client/types/messages_and_media/contact.py @@ -47,7 +47,7 @@ class Contact(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, phone_number: str, first_name: str, last_name: str = None, diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index 754fc5af..394d5e14 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -53,7 +53,7 @@ class Document(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, thumb: PhotoSize = None, file_name: str = None, diff --git a/pyrogram/client/types/messages_and_media/game.py b/pyrogram/client/types/messages_and_media/game.py index b4c96a11..1377173a 100644 --- a/pyrogram/client/types/messages_and_media/game.py +++ b/pyrogram/client/types/messages_and_media/game.py @@ -53,7 +53,7 @@ class Game(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, id: int, title: str, short_name: str, diff --git a/pyrogram/client/types/messages_and_media/location.py b/pyrogram/client/types/messages_and_media/location.py index c3d8f974..55def7a0 100644 --- a/pyrogram/client/types/messages_and_media/location.py +++ b/pyrogram/client/types/messages_and_media/location.py @@ -38,7 +38,7 @@ class Location(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, longitude: float, latitude: float ): diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 28a5d0ea..d37028b5 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -282,7 +282,7 @@ class Message(PyrogramType, Update): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, message_id: int, date: int = None, chat: Chat = None, @@ -2852,7 +2852,7 @@ class Message(PyrogramType, Update): block: bool = True, progress: callable = None, progress_args: tuple = () - ) -> "Message": + ) -> str: """Bound method *download* of :obj:`Message`. Use as a shortcut for: diff --git a/pyrogram/client/types/messages_and_media/message_entity.py b/pyrogram/client/types/messages_and_media/message_entity.py index 768dee1e..e369e74e 100644 --- a/pyrogram/client/types/messages_and_media/message_entity.py +++ b/pyrogram/client/types/messages_and_media/message_entity.py @@ -68,7 +68,7 @@ class MessageEntity(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, type: str, offset: int, length: int, diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py index 4f930a22..379830be 100644 --- a/pyrogram/client/types/messages_and_media/messages.py +++ b/pyrogram/client/types/messages_and_media/messages.py @@ -42,7 +42,7 @@ class Messages(PyrogramType, Update): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, total_count: int, messages: List[Message] ): diff --git a/pyrogram/client/types/messages_and_media/photo.py b/pyrogram/client/types/messages_and_media/photo.py index c2d0eb1f..8d60d59a 100644 --- a/pyrogram/client/types/messages_and_media/photo.py +++ b/pyrogram/client/types/messages_and_media/photo.py @@ -46,7 +46,7 @@ class Photo(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, id: str, date: int, sizes: List[PhotoSize] diff --git a/pyrogram/client/types/messages_and_media/photo_size.py b/pyrogram/client/types/messages_and_media/photo_size.py index c76ef914..9f64ae6a 100644 --- a/pyrogram/client/types/messages_and_media/photo_size.py +++ b/pyrogram/client/types/messages_and_media/photo_size.py @@ -47,7 +47,7 @@ class PhotoSize(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, width: int, height: int, diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index 8aa32137..e6c97bfb 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -53,7 +53,7 @@ class Poll(PyrogramType, Update): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, id: str, question: str, options: List[PollOption], diff --git a/pyrogram/client/types/messages_and_media/poll_option.py b/pyrogram/client/types/messages_and_media/poll_option.py index e594e3ca..e7eb1f5f 100644 --- a/pyrogram/client/types/messages_and_media/poll_option.py +++ b/pyrogram/client/types/messages_and_media/poll_option.py @@ -30,14 +30,17 @@ class PollOption(PyrogramType): voter_count (``int``): Number of users that voted for this option. Equals to 0 until you vote. + + data (``bytes``): + The data this poll option is holding. """ - __slots__ = ["text", "voter_count", "_data"] + __slots__ = ["text", "voter_count", "data"] def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, text: str, voter_count: int, data: bytes @@ -46,4 +49,4 @@ class PollOption(PyrogramType): self.text = text self.voter_count = voter_count - self._data = data # Hidden + self.data = data diff --git a/pyrogram/client/types/messages_and_media/sticker.py b/pyrogram/client/types/messages_and_media/sticker.py index 0a3a42d1..edeee37e 100644 --- a/pyrogram/client/types/messages_and_media/sticker.py +++ b/pyrogram/client/types/messages_and_media/sticker.py @@ -71,7 +71,7 @@ class Sticker(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, width: int, height: int, diff --git a/pyrogram/client/types/messages_and_media/user_profile_photos.py b/pyrogram/client/types/messages_and_media/user_profile_photos.py index c74a371b..628831d5 100644 --- a/pyrogram/client/types/messages_and_media/user_profile_photos.py +++ b/pyrogram/client/types/messages_and_media/user_profile_photos.py @@ -39,7 +39,7 @@ class UserProfilePhotos(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, total_count: int, photos: List[Photo] ): diff --git a/pyrogram/client/types/messages_and_media/venue.py b/pyrogram/client/types/messages_and_media/venue.py index cac84e57..e54a812e 100644 --- a/pyrogram/client/types/messages_and_media/venue.py +++ b/pyrogram/client/types/messages_and_media/venue.py @@ -49,7 +49,7 @@ class Venue(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, location: Location, title: str, address: str, diff --git a/pyrogram/client/types/messages_and_media/video.py b/pyrogram/client/types/messages_and_media/video.py index 13980270..529fc5ef 100644 --- a/pyrogram/client/types/messages_and_media/video.py +++ b/pyrogram/client/types/messages_and_media/video.py @@ -68,7 +68,7 @@ class Video(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, width: int, height: int, diff --git a/pyrogram/client/types/messages_and_media/video_note.py b/pyrogram/client/types/messages_and_media/video_note.py index 5ebc8774..133ccae0 100644 --- a/pyrogram/client/types/messages_and_media/video_note.py +++ b/pyrogram/client/types/messages_and_media/video_note.py @@ -56,7 +56,7 @@ class VideoNote(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, length: int, duration: int, diff --git a/pyrogram/client/types/messages_and_media/voice.py b/pyrogram/client/types/messages_and_media/voice.py index 88154e2f..3e08d57a 100644 --- a/pyrogram/client/types/messages_and_media/voice.py +++ b/pyrogram/client/types/messages_and_media/voice.py @@ -52,7 +52,7 @@ class Voice(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, file_id: str, duration: int, waveform: bytes = None, diff --git a/pyrogram/client/types/pyrogram_type.py b/pyrogram/client/types/pyrogram_type.py index 5f757d43..ed50efbc 100644 --- a/pyrogram/client/types/pyrogram_type.py +++ b/pyrogram/client/types/pyrogram_type.py @@ -25,34 +25,45 @@ import pyrogram class PyrogramType: __slots__ = ["_client"] - def __init__(self, client: "pyrogram.client.ext.BaseClient"): + def __init__(self, client: "pyrogram.BaseClient" = None): self._client = client - def __str__(self): + if self._client is None: + del self._client + + def __eq__(self, other: "PyrogramType") -> bool: + for attr in self.__slots__: + try: + if getattr(self, attr) != getattr(other, attr): + return False + except AttributeError: + return False + + return True + + def __str__(self) -> str: + def default(obj: PyrogramType): + try: + return OrderedDict( + [("_", "pyrogram." + obj.__class__.__name__)] + + [(attr, getattr(obj, attr)) + for attr in obj.__slots__ + if getattr(obj, attr) is not None] + ) + except AttributeError: + return repr(obj) + return dumps(self, indent=4, default=default, ensure_ascii=False) + def __repr__(self) -> str: + return "pyrogram.{}({})".format( + self.__class__.__name__, + ", ".join( + "{}={}".format(attr, repr(getattr(self, attr))) + for attr in self.__slots__ + if getattr(self, attr) is not None + ) + ) + def __getitem__(self, item): return getattr(self, item) - - -def remove_none(obj): - if isinstance(obj, (list, tuple, set)): - return type(obj)(remove_none(x) for x in obj if x is not None) - elif isinstance(obj, dict): - return type(obj)((remove_none(k), remove_none(v)) for k, v in obj.items() if k is not None and v is not None) - else: - return obj - - -def default(o: PyrogramType): - try: - content = {i: getattr(o, i) for i in o.__slots__} - - return remove_none( - OrderedDict( - [("_", "pyrogram." + o.__class__.__name__)] - + [i for i in content.items() if not i[0].startswith("_")] - ) - ) - except AttributeError: - return repr(o) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 3b5f242b..8793942c 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -89,7 +89,7 @@ class Chat(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, id: int, type: str, title: str = None, diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 9de9986a..536f9526 100644 --- a/pyrogram/client/types/user_and_chats/chat_member.py +++ b/pyrogram/client/types/user_and_chats/chat_member.py @@ -59,7 +59,7 @@ class ChatMember(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, user: "pyrogram.User", status: str, date: int = None, diff --git a/pyrogram/client/types/user_and_chats/chat_members.py b/pyrogram/client/types/user_and_chats/chat_members.py index 8f98277c..f57b8b46 100644 --- a/pyrogram/client/types/user_and_chats/chat_members.py +++ b/pyrogram/client/types/user_and_chats/chat_members.py @@ -40,7 +40,7 @@ class ChatMembers(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, total_count: int, chat_members: List[ChatMember] ): diff --git a/pyrogram/client/types/user_and_chats/chat_photo.py b/pyrogram/client/types/user_and_chats/chat_photo.py index 3f1f7cc6..37fde9fd 100644 --- a/pyrogram/client/types/user_and_chats/chat_photo.py +++ b/pyrogram/client/types/user_and_chats/chat_photo.py @@ -40,7 +40,7 @@ class ChatPhoto(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, small_file_id: str, big_file_id: str ): diff --git a/pyrogram/client/types/user_and_chats/chat_preview.py b/pyrogram/client/types/user_and_chats/chat_preview.py index 880dcc8e..0366d04f 100644 --- a/pyrogram/client/types/user_and_chats/chat_preview.py +++ b/pyrogram/client/types/user_and_chats/chat_preview.py @@ -50,7 +50,7 @@ class ChatPreview(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, title: str, photo: ChatPhoto, type: str, diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index 3dc09dbc..fc691ab6 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -51,7 +51,7 @@ class Dialog(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, chat: Chat, top_message: "pyrogram.Message", unread_messages_count: int, diff --git a/pyrogram/client/types/user_and_chats/dialogs.py b/pyrogram/client/types/user_and_chats/dialogs.py index 43b9f667..0d6a0935 100644 --- a/pyrogram/client/types/user_and_chats/dialogs.py +++ b/pyrogram/client/types/user_and_chats/dialogs.py @@ -41,7 +41,7 @@ class Dialogs(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, total_count: int, dialogs: List[Dialog] ): diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index c5a0976c..455b4a4d 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -78,7 +78,7 @@ class User(PyrogramType): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, id: int, is_self: bool, is_contact: bool, diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index f91c2924..e6f5b134 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -70,7 +70,7 @@ class UserStatus(PyrogramType, Update): def __init__( self, *, - client: "pyrogram.client.ext.BaseClient", + client: "pyrogram.BaseClient" = None, user_id: int, online: bool = None, offline: bool = None, From 90115448ac39794b22c250b49873f6c7c15d35f0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 16:37:26 +0200 Subject: [PATCH 056/202] Update link hint for No API Key found errors --- pyrogram/client/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index f65ef231..31a7c14c 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -1093,7 +1093,7 @@ class Client(Methods, BaseClient): else: raise AttributeError( "No API Key found. " - "More info: https://docs.pyrogram.ml/start/ProjectSetup#configuration" + "More info: https://docs.pyrogram.ml/intro/setup#configuration" ) for option in ["app_version", "device_model", "system_version", "lang_code"]: From fb014f315ce82210807153e670461ae99c55554e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 17:15:00 +0200 Subject: [PATCH 057/202] Update and rename README.rst to README.md --- README.md | 94 ++++++++++++++++++++++++++++++++++++++ README.rst | 131 ----------------------------------------------------- 2 files changed, 94 insertions(+), 131 deletions(-) create mode 100644 README.md delete mode 100644 README.rst diff --git a/README.md b/README.md new file mode 100644 index 00000000..35c80f37 --- /dev/null +++ b/README.md @@ -0,0 +1,94 @@ +

+ + Pyrogram + +
+ Telegram MTProto API Framework for Python +
+ + Documentation + + • + + Releases + + • + + Community + +
+ + Schema Layer + + + TgCrypto Version + +

+ +## Pyrogram + +``` python +from pyrogram import Client, Filters + +app = Client("my_account") + + +@app.on_message(Filters.private) +def hello(client, message): + message.reply("Hello {}".format(message.from_user.first_name)) + + +app.run() +``` + +**Pyrogram** is an elegant, easy-to-use [Telegram](https://telegram.org/) client library and framework written from the +ground up in Python and C. It enables you to easily create custom apps for both user and bot identities (bot API alternative) via the [MTProto API](https://core.telegram.org/api#telegram-api). + +> [Pyrogram in fully-asynchronous mode is also available »](https://github.com/pyrogram/pyrogram/issues/181) +> +> [Working PoC of Telegram voice calls using Pyrogram »](https://github.com/bakatrouble/pytgvoip) + +### Features + +- **Easy**: You can install Pyrogram with pip and start building your applications right away. +- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way. +- **Fast**: Crypto parts are boosted up by [TgCrypto](https://github.com/pyrogram/tgcrypto), a high-performance library + written in pure C. +- **Documented**: Pyrogram API methods, types and public interfaces are well documented. +- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. +- **Updated**, to the latest Telegram API version, currently Layer 97 on top of + [MTProto 2.0](https://core.telegram.org/mtproto). +- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code. +- **Comprehensive**: Execute any advanced action an official client is able to do, and even more. + +### Requirements + +- Python 3.4 or higher. +- A [Telegram API key](https://docs.pyrogram.ml/intro/setup#api-keys). + +### Installing + +``` bash +pip3 install pyrogram +``` + +### Resources + +- The Docs contain lots of resources to help you getting started with Pyrogram: https://docs.pyrogram.ml. +- Reading [Examples in this repository](https://github.com/pyrogram/pyrogram/tree/master/examples) is also a good way + for learning how Pyrogram works. +- Seeking extra help? Don't be shy, come join and ask our [Community](https://t.me/PyrogramChat)! +- For other requests you can send an [Email](mailto:admin@pyrogram.ml) or a [Message](https://t.me/haskell). + +### Contributing + +Pyrogram is brand new, and **you are welcome to try it and help make it even better** by either submitting pull +requests or reporting issues/bugs as well as suggesting best practices, ideas, enhancements on both code +and documentation. Any help is appreciated! + +### Copyright & License + +- Copyright (C) 2017-2019 Dan Tès <> +- Licensed under the terms of the [GNU Lesser General Public License v3 or later (LGPLv3+)](COPYING.lesser) diff --git a/README.rst b/README.rst deleted file mode 100644 index dfb03abc..00000000 --- a/README.rst +++ /dev/null @@ -1,131 +0,0 @@ -|header| - -Pyrogram -======== - -.. code-block:: python - - from pyrogram import Client, Filters - - app = Client("my_account") - - - @app.on_message(Filters.private) - def hello(client, message): - message.reply("Hello {}".format(message.from_user.first_name)) - - - app.run() - -**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and C. -It enables you to easily create custom apps using both user and bot identities (bot API alternative) via the `MTProto API`_. - - `Pyrogram in fully-asynchronous mode is also available » `_ - - `Working PoC of Telegram voice calls using Pyrogram » `_ - -Features --------- - -- **Easy**: You can install Pyrogram with pip and start building your applications right away. -- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way. -- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C. -- **Documented**: Pyrogram API methods, types and public interfaces are well documented. -- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. -- **Updated**, to the latest Telegram API version, currently Layer 97 on top of `MTProto 2.0`_. -- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code. -- **Comprehensive**: Execute any advanced action an official client is able to do, and even more. - -Requirements ------------- - -- Python 3.4 or higher. -- A `Telegram API key`_. - -Installing ----------- - -.. code:: shell - - pip3 install pyrogram - -Resources ---------- - -- The Docs contain lots of resources to help you getting started with Pyrogram: https://docs.pyrogram.ml. -- Reading `Examples in this repository`_ is also a good way for learning how Pyrogram works. -- Seeking extra help? Don't be shy, come join and ask our Community_! -- For other requests you can send an Email_ or a Message_. - -Contributing ------------- - -Pyrogram is brand new, and **you are welcome to try it and help make it even better** by either submitting pull -requests or reporting issues/bugs as well as suggesting best practices, ideas, enhancements on both code -and documentation. Any help is appreciated! - -Copyright & License -------------------- - -- Copyright (C) 2017-2019 Dan Tès -- Licensed under the terms of the `GNU Lesser General Public License v3 or later (LGPLv3+)`_ - -.. _`Telegram`: https://telegram.org/ -.. _`MTProto API`: https://core.telegram.org/api#telegram-api -.. _`Telegram API key`: https://docs.pyrogram.ml/start/ProjectSetup#api-keys -.. _`Community`: https://t.me/PyrogramChat -.. _`Examples in this repository`: https://github.com/pyrogram/pyrogram/tree/master/examples -.. _`GitHub`: https://github.com/pyrogram/pyrogram/issues -.. _`Email`: admin@pyrogram.ml -.. _`Message`: https://t.me/haskell -.. _TgCrypto: https://github.com/pyrogram/tgcrypto -.. _`MTProto 2.0`: https://core.telegram.org/mtproto -.. _`GNU Lesser General Public License v3 or later (LGPLv3+)`: COPYING.lesser - -.. |header| raw:: html - -

- -
Pyrogram Logo
-
-

- -

- Telegram MTProto API Framework for Python - -
- - Documentation - - • - - Changelog - - • - - Community - -
- - Schema Layer - - - TgCrypto Version - -

- -.. |logo| image:: https://raw.githubusercontent.com/pyrogram/logos/master/logos/pyrogram_logo2.png - :target: https://pyrogram.ml - :alt: Pyrogram - -.. |description| replace:: **Telegram MTProto API Framework for Python** - -.. |schema| image:: https://img.shields.io/badge/schema-layer%2097-eda738.svg?longCache=true&colorA=262b30 - :target: compiler/api/source/main_api.tl - :alt: Schema Layer - -.. |tgcrypto| image:: https://img.shields.io/badge/tgcrypto-v1.1.1-eda738.svg?longCache=true&colorA=262b30 - :target: https://github.com/pyrogram/tgcrypto - :alt: TgCrypto Version From 9a2602ff2a5704efdaeaa85b5f672f1964b845d7 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 17:17:20 +0200 Subject: [PATCH 058/202] Update setup.py --- setup.py | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/setup.py b/setup.py index 437ba39a..245655e6 100644 --- a/setup.py +++ b/setup.py @@ -27,22 +27,14 @@ from compiler.api import compiler as api_compiler from compiler.docs import compiler as docs_compiler from compiler.error import compiler as error_compiler +with open("requirements.txt", encoding="utf-8") as r: + requires = [i.strip() for i in r] -def read(file: str) -> list: - with open(file, encoding="utf-8") as r: - return [i.strip() for i in r] +with open("pyrogram/__init__.py", encoding="utf-8") as f: + version = re.findall(r"__version__ = \"(.+)\"", f.read())[0] - -def get_version(): - with open("pyrogram/__init__.py", encoding="utf-8") as f: - return re.findall(r"__version__ = \"(.+)\"", f.read())[0] - - -def get_readme(): - # PyPI doesn't like raw html - with open("README.rst", encoding="utf-8") as f: - readme = re.sub(r"\.\. \|.+\| raw:: html(?:\s{4}.+)+\n\n", "", f.read()) - return re.sub(r"\|header\|", "|logo|\n\n|description|\n\n|schema| |tgcrypto|", readme) +with open("README.md", encoding="utf-8") as f: + readme = f.read() class Clean(Command): @@ -128,23 +120,24 @@ class Generate(Command): if len(argv) > 1 and argv[1] in ["bdist_wheel", "install", "develop"]: - error_compiler.start() api_compiler.start() - docs_compiler.start() + error_compiler.start() setup( name="Pyrogram", - version=get_version(), + version=version, description="Telegram MTProto API Client Library for Python", - long_description=get_readme(), + long_description=readme, + long_description_content_type="text/markdown", url="https://github.com/pyrogram", download_url="https://github.com/pyrogram/pyrogram/releases/latest", author="Dan Tès", author_email="admin@pyrogram.ml", license="LGPLv3+", classifiers=[ - "Development Status :: 3 - Alpha", + "Development Status :: 4 - Beta", "Intended Audience :: Developers", + "Natural Language :: English", "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)", "Operating System :: OS Independent", "Programming Language :: Python", @@ -152,6 +145,8 @@ setup( "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", @@ -175,10 +170,9 @@ setup( "pyrogram.client.ext": ["mime.types"] }, zip_safe=False, - install_requires=read("requirements.txt"), + install_requires=requires, extras_require={ - "tgcrypto": ["tgcrypto==1.1.1"], # TODO: Remove soon - "fast": ["tgcrypto==1.1.1"], + "fast": ["tgcrypto==1.1.1"] }, cmdclass={ "clean": Clean, From 29ac51f256286c610954d7b955c0c08bcfbe59b6 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 17:21:15 +0200 Subject: [PATCH 059/202] Include README.md into MANIFEST.in --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 80c061ff..97d04588 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ ## Include -include COPYING COPYING.lesser NOTICE requirements.txt +include README.md COPYING COPYING.lesser NOTICE requirements.txt recursive-include compiler *.py *.tl *.tsv *.txt recursive-include pyrogram mime.types From 0914654ba69b9cf013f286e95315b69c57060b8c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 18:04:44 +0200 Subject: [PATCH 060/202] Fix cross-reference links --- docs/source/index.rst | 13 +++++++------ docs/source/intro/install.rst | 2 +- docs/source/start/errors.rst | 20 ++++++++++---------- docs/source/start/updates.rst | 5 ++++- docs/source/topics/advanced-usage.rst | 13 +++++-------- docs/source/topics/config-file.rst | 6 +++--- docs/source/topics/faq.rst | 4 ++-- docs/source/topics/more-on-updates.rst | 4 ++-- docs/source/topics/session-settings.rst | 4 ++-- docs/source/topics/smart-plugins.rst | 4 ++-- 10 files changed, 38 insertions(+), 37 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 81b4213c..9ff0f720 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -23,7 +23,7 @@ Welcome to Pyrogram • - Changelog + Releases @@ -55,7 +55,7 @@ Welcome to Pyrogram app.run() **Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and -C. It enables you to easily create custom apps using both user and bot identities (bot API alternative) via the +C. It enables you to easily create custom apps for both user and bot identities (bot API alternative) via the `MTProto API`_. .. _Telegram: https://telegram.org @@ -65,7 +65,8 @@ How the Documentation is Organized ---------------------------------- Contents are organized into self-contained topics and can be all accessed from the sidebar, or by following them in -order using the Next button at the end of each page. Here below you can find a list of the most relevant pages. +order using the Next button at the end of each page. Here below you can, instead, find a list of the most relevant +pages. Getting Started ^^^^^^^^^^^^^^^ @@ -86,9 +87,9 @@ API Reference - `Available Methods`_ - A list of available high-level methods. - `Available Types`_ - A list of available high-level types. -.. _Client Class: core/client -.. _Available Methods: core/methods -.. _Available Types: core/types +.. _Client Class: api/client +.. _Available Methods: api/methods +.. _Available Types: api/types Topics ^^^^^^ diff --git a/docs/source/intro/install.rst b/docs/source/intro/install.rst index 161c7d61..e2e4365a 100644 --- a/docs/source/intro/install.rst +++ b/docs/source/intro/install.rst @@ -88,5 +88,5 @@ If no error shows up you are good to go. >>> pyrogram.__version__ '0.12.0' -.. _TgCrypto: ../resources/tgcrypto.html +.. _TgCrypto: ../topics/tgcrypto .. _`Github repo`: http://github.com/pyrogram/pyrogram diff --git a/docs/source/start/errors.rst b/docs/source/start/errors.rst index d05206c9..1260672e 100644 --- a/docs/source/start/errors.rst +++ b/docs/source/start/errors.rst @@ -4,18 +4,18 @@ Error Handling Errors are inevitable when working with the API, and they must be correctly handled with ``try..except`` blocks. There are many errors that Telegram could return, but they all fall in one of these categories -(which are in turn children of the :obj:`RPCError ` superclass): +(which are in turn children of the ``RPCError`` superclass): -- :obj:`303 - See Other ` -- :obj:`400 - Bad Request ` -- :obj:`401 - Unauthorized ` -- :obj:`403 - Forbidden ` -- :obj:`406 - Not Acceptable ` -- :obj:`420 - Flood ` -- :obj:`500 - Internal Server Error ` +- `303 - See Other <../api/errors#see-other>`_ +- `400 - Bad Request <../api/errors#bad-request>`_ +- `401 - Unauthorized <../api/errors#unauthorized>`_ +- `403 - Forbidden <../api/errors#forbidden>`_ +- `406 - Not Acceptable <../api/errors#not-acceptable>`_ +- `420 - Flood <../api/errors#flood>`_ +- `500 - Internal Server Error <../api/errors#internal-server-error>`_ As stated above, there are really many (too many) errors, and in case Pyrogram does not know anything yet about a -specific one, it raises a special :obj:`520 Unknown Error ` exception and logs it +specific one, it raises a special ``520 Unknown Error`` exception and logs it in the ``unknown_errors.txt`` file. Users are invited to report these unknown errors. Examples @@ -44,7 +44,7 @@ Examples pass Exception objects may also contain some informative values. -E.g.: :obj:`FloodWait ` holds the amount of seconds you have to wait +E.g.: ``FloodWait`` holds the amount of seconds you have to wait before you can try again. The value is always stored in the ``x`` field of the returned exception object: .. code-block:: python diff --git a/docs/source/start/updates.rst b/docs/source/start/updates.rst index 0dcb08ad..85005b9c 100644 --- a/docs/source/start/updates.rst +++ b/docs/source/start/updates.rst @@ -4,10 +4,13 @@ Handling Updates Calling `API methods`_ sequentially is cool, but how to react when, for example, a new message arrives? This page deals with updates and how to handle such events in Pyrogram. Let's have a look at how they work. +Defining Updates +---------------- + First, let's define what are these updates. As hinted already, updates are simply events that happen in your Telegram account (incoming messages, new members join, button presses, etc...), which are meant to notify you about a new specific state that changed. These updates are handled by registering one or more callback functions in your app using -`Handlers <../pyrogram/Handlers.html>`_. +`Handlers <../api/handlers>`_. Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback function will be called and its body executed. diff --git a/docs/source/topics/advanced-usage.rst b/docs/source/topics/advanced-usage.rst index 8b722b2a..970e07e0 100644 --- a/docs/source/topics/advanced-usage.rst +++ b/docs/source/topics/advanced-usage.rst @@ -125,12 +125,9 @@ For example, given the ID *123456789*, here's how Pyrogram can tell entities apa So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an high-level method. - - - -.. _methods: ../pyrogram/Client.html#messages -.. _types: ../pyrogram/Types.html -.. _plenty of them: ../pyrogram/Client.html#messages -.. _raw functions: ../pyrogram/functions -.. _raw types: ../pyrogram/types +.. _methods: ../api/methods +.. _types: ../api/types +.. _plenty of them: ../api/methods +.. _raw functions: ../telegram/functions +.. _raw types: ../telegram/types .. _Community: https://t.me/PyrogramChat \ No newline at end of file diff --git a/docs/source/topics/config-file.rst b/docs/source/topics/config-file.rst index 2a50277f..14ae9fb6 100644 --- a/docs/source/topics/config-file.rst +++ b/docs/source/topics/config-file.rst @@ -54,7 +54,7 @@ The ``[pyrogram]`` section contains your Telegram API credentials: *api_id* and api_id = 12345 api_hash = 0123456789abcdef0123456789abcdef -`More info about API Key. <../start/Setup.html#configuration>`_ +`More info about API Key. <../intro/setup#api-keys>`_ Proxy ^^^^^ @@ -70,7 +70,7 @@ The ``[proxy]`` section contains settings about your SOCKS5 proxy. username = password = -`More info about SOCKS5 Proxy. `_ +`More info about SOCKS5 Proxy. `_ Plugins ^^^^^^^ @@ -87,4 +87,4 @@ The ``[plugins]`` section contains settings about Smart Plugins. exclude = module fn2 -`More info about Smart Plugins. `_ +`More info about Smart Plugins. `_ diff --git a/docs/source/topics/faq.rst b/docs/source/topics/faq.rst index 5a8a3929..0834389e 100644 --- a/docs/source/topics/faq.rst +++ b/docs/source/topics/faq.rst @@ -11,7 +11,7 @@ What is Pyrogram? ----------------- **Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and -C. It enables you to easily create custom applications using both user and bot identities (bot API alternative) via the +C. It enables you to easily create custom applications for both user and bot identities (bot API alternative) via the `MTProto API`_ with the Python programming language. .. _Telegram: https://telegram.org @@ -30,7 +30,7 @@ How old is Pyrogram? Pyrogram was first released on December 12, 2017. The actual work on the framework began roughly three months prior the initial public release on `GitHub`_. -.. _GitHub: +.. _GitHub: https://github.com/pyrogram/pyrogram Why do I need an API key for bots? ---------------------------------- diff --git a/docs/source/topics/more-on-updates.rst b/docs/source/topics/more-on-updates.rst index 84086622..cb319ee1 100644 --- a/docs/source/topics/more-on-updates.rst +++ b/docs/source/topics/more-on-updates.rst @@ -218,5 +218,5 @@ The output of both (equivalent) examples will be: 1 2 -.. _`update handlers`: UpdateHandling.html -.. _`filters`: UsingFilters.html \ No newline at end of file +.. _`update handlers`: ../start/updates +.. _`filters`: filters \ No newline at end of file diff --git a/docs/source/topics/session-settings.rst b/docs/source/topics/session-settings.rst index 47c6872e..89b7e62c 100644 --- a/docs/source/topics/session-settings.rst +++ b/docs/source/topics/session-settings.rst @@ -5,8 +5,8 @@ As you may probably know, Telegram allows users (and bots) having more than one in the system at the same time. Briefly explaining, sessions are simply new logins in your account. They can be reviewed in the settings of an official -app (or by invoking `GetAuthorizations <../functions/account/GetAuthorizations.html>`_ with Pyrogram). They store some -useful information such as the client who's using them and from which country and IP address. +app (or by invoking `GetAuthorizations <../telegram/functions/account/GetAuthorizations.html>`_ with Pyrogram). They +store some useful information such as the client who's using them and from which country and IP address. .. figure:: https://i.imgur.com/lzGPCdZ.png :width: 70% diff --git a/docs/source/topics/smart-plugins.rst b/docs/source/topics/smart-plugins.rst index 6f266590..fbe27388 100644 --- a/docs/source/topics/smart-plugins.rst +++ b/docs/source/topics/smart-plugins.rst @@ -65,7 +65,7 @@ after importing your modules, like this: app.run() This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to -manually ``import``, manually :meth:`add_handler ` and manually instantiate each +manually ``import``, manually :meth:`add_handler() ` and manually instantiate each :obj:`MessageHandler ` object because **you can't use those cool decorators** for your functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically. @@ -156,7 +156,7 @@ found inside each module will be, instead, loaded in the order they are defined, .. note:: Remember: there can be at most one handler, within a group, dealing with a specific update. Plugins with overlapping - filters included a second time will not work. Learn more at `More on Updates `_. + filters included a second time will not work. Learn more at `More on Updates `_. This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude`` From 94de75f7144be9f69d5eb58107c84098c3568238 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 21:03:55 +0200 Subject: [PATCH 061/202] Bring back the possibility to use strings as callback query data In case bytes (which is the type used by telegram) can't be successfully decoded into strings, the raw bytes are presented instead of trying to decode by ignoring/replacing errors. --- .../methods/bots/request_callback_answer.py | 10 +++++++--- .../client/types/keyboards/callback_query.py | 16 ++++++++++++---- .../types/keyboards/inline_keyboard_button.py | 17 +++++++++++++---- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/pyrogram/client/methods/bots/request_callback_answer.py b/pyrogram/client/methods/bots/request_callback_answer.py index 443cb825..97d8d42b 100644 --- a/pyrogram/client/methods/bots/request_callback_answer.py +++ b/pyrogram/client/methods/bots/request_callback_answer.py @@ -27,7 +27,7 @@ class RequestCallbackAnswer(BaseClient): self, chat_id: Union[int, str], message_id: int, - callback_data: bytes, + callback_data: Union[str, bytes], timeout: int = 10 ): """Request a callback answer from bots. @@ -42,7 +42,7 @@ class RequestCallbackAnswer(BaseClient): message_id (``int``): The message id the inline keyboard is attached on. - callback_data (``bytes``): + callback_data (``str`` | ``bytes``): Callback data associated with the inline button you want to get the answer from. timeout (``int``, *optional*): @@ -56,11 +56,15 @@ class RequestCallbackAnswer(BaseClient): RPCError: In case of a Telegram RPC error. TimeoutError: In case the bot fails to answer within 10 seconds. """ + + # Telegram only wants bytes, but we are allowed to pass strings too. + data = bytes(callback_data, "utf-8") if isinstance(callback_data, str) else callback_data + return self.send( functions.messages.GetBotCallbackAnswer( peer=self.resolve_peer(chat_id), msg_id=message_id, - data=callback_data + data=data ), retries=0, timeout=timeout diff --git a/pyrogram/client/types/keyboards/callback_query.py b/pyrogram/client/types/keyboards/callback_query.py index 822ea234..4d657767 100644 --- a/pyrogram/client/types/keyboards/callback_query.py +++ b/pyrogram/client/types/keyboards/callback_query.py @@ -18,6 +18,7 @@ from base64 import b64encode from struct import pack +from typing import Union import pyrogram from pyrogram.api import types @@ -51,7 +52,7 @@ class CallbackQuery(PyrogramType, Update): inline_message_id (``str``): Identifier of the message sent via the bot in inline mode, that originated the query. - data (``bytes``, *optional*): + data (``str`` | ``bytes``, *optional*): Data associated with the callback button. Be aware that a bad client can send arbitrary data in this field. game_short_name (``str``, *optional*): @@ -70,7 +71,7 @@ class CallbackQuery(PyrogramType, Update): chat_instance: str, message: "pyrogram.Message" = None, inline_message_id: str = None, - data: bytes = None, + data: Union[str, bytes] = None, game_short_name: str = None ): super().__init__(client) @@ -80,7 +81,7 @@ class CallbackQuery(PyrogramType, Update): self.chat_instance = chat_instance self.message = message self.inline_message_id = inline_message_id - self.data = str(data, "utf-8") + self.data = data self.game_short_name = game_short_name @staticmethod @@ -110,13 +111,20 @@ class CallbackQuery(PyrogramType, Update): b"-_" ).decode().rstrip("=") + # Try to decode callback query data into string. If that fails, fallback to bytes instead of decoding by + # ignoring/replacing errors, this way, button clicks will still work. + try: + data = callback_query.data.decode() + except UnicodeDecodeError: + data = callback_query.data + return CallbackQuery( id=str(callback_query.query_id), from_user=User._parse(client, users[callback_query.user_id]), message=message, inline_message_id=inline_message_id, chat_instance=str(callback_query.chat_instance), - data=callback_query.data, + data=data, game_short_name=callback_query.game_short_name, client=client ) diff --git a/pyrogram/client/types/keyboards/inline_keyboard_button.py b/pyrogram/client/types/keyboards/inline_keyboard_button.py index 7e9fd458..08ad0f35 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_button.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_button.py @@ -35,7 +35,7 @@ class InlineKeyboardButton(PyrogramType): text (``str``): Label text on the button. - callback_data (``bytes``, *optional*): + callback_data (``str`` | ``bytes``, *optional*): Data to be sent in a callback query to the bot when button is pressed, 1-64 bytes. url (``str``, *optional*): @@ -75,7 +75,7 @@ class InlineKeyboardButton(PyrogramType): self.text = str(text) self.url = url - self.callback_data = bytes(callback_data, "utf-8") if isinstance(callback_data, str) else callback_data + self.callback_data = callback_data self.switch_inline_query = switch_inline_query self.switch_inline_query_current_chat = switch_inline_query_current_chat self.callback_game = callback_game @@ -90,9 +90,16 @@ class InlineKeyboardButton(PyrogramType): ) if isinstance(o, KeyboardButtonCallback): + # Try decode data to keep it as string, but if fails, fallback to bytes so we don't lose any information, + # instead of decoding by ignoring/replacing errors. + try: + data = o.data.decode() + except UnicodeDecodeError: + data = o.data + return InlineKeyboardButton( text=o.text, - callback_data=o.data + callback_data=data ) if isinstance(o, KeyboardButtonSwitchInline): @@ -115,7 +122,9 @@ class InlineKeyboardButton(PyrogramType): def write(self): if self.callback_data is not None: - return KeyboardButtonCallback(text=self.text, data=self.callback_data) + # Telegram only wants bytes, but we are allowed to pass strings too, for convenience. + data = bytes(self.callback_data, "utf-8") if isinstance(self.callback_data, str) else self.callback_data + return KeyboardButtonCallback(text=self.text, data=data) if self.url is not None: return KeyboardButtonUrl(text=self.text, url=self.url) From a5e42572f62986093fc8f64aed316a248234dc35 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 13 May 2019 21:05:47 +0200 Subject: [PATCH 062/202] Allow Message.click() without arguments. Default to 0 (first button) --- pyrogram/client/types/messages_and_media/message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index d37028b5..a8f6d31b 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -2725,7 +2725,7 @@ class Message(PyrogramType, Update): revoke=revoke ) - def click(self, x: int or str, y: int = None, quote: bool = None, timeout: int = 10): + def click(self, x: int or str, y: int = 0, quote: bool = None, timeout: int = 10): """Bound method *click* of :obj:`Message`. Use as a shortcut for clicking a button attached to the message instead of: From 944b672fe5b044446970887b868e9785addb6525 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 16 May 2019 21:28:34 +0200 Subject: [PATCH 063/202] Docs revamp. Part 4 --- compiler/docs/template/page.txt | 2 +- docs/source/api/bound-methods.rst | 102 ++++++++++++++++++ docs/source/api/client.rst | 13 ++- docs/source/api/decorators.rst | 7 +- docs/source/api/errors.rst | 23 ++-- docs/source/api/handlers.rst | 9 +- docs/source/api/methods.rst | 5 +- docs/source/api/types.rst | 98 +---------------- docs/source/index.rst | 12 ++- docs/source/intro/auth.rst | 1 + docs/source/intro/install.rst | 13 +-- docs/source/intro/start.rst | 7 +- docs/source/start/errors.rst | 88 ++++++++------- docs/source/start/invoking.rst | 9 +- docs/source/start/updates.rst | 4 +- docs/source/topics/advanced-usage.rst | 6 +- docs/source/topics/faq.rst | 58 ++++++++-- docs/source/topics/filters.rst | 3 + docs/source/topics/glossary.rst | 53 +++++++++ docs/source/topics/smart-plugins.rst | 26 ++--- pyrogram/client/client.py | 18 ++-- pyrogram/client/filters/filters.py | 34 ++---- .../methods/decorators/on_callback_query.py | 3 +- .../methods/decorators/on_deleted_messages.py | 3 +- .../methods/decorators/on_disconnect.py | 3 +- .../methods/decorators/on_inline_query.py | 3 +- .../client/methods/decorators/on_message.py | 3 +- pyrogram/client/methods/decorators/on_poll.py | 3 +- .../methods/decorators/on_raw_update.py | 3 +- .../methods/decorators/on_user_status.py | 2 +- .../methods/messages/forward_messages.py | 2 +- .../client/methods/messages/send_document.py | 2 +- .../client/types/keyboards/callback_query.py | 6 +- .../types/messages_and_media/message.py | 55 +++++----- .../client/types/user_and_chats/chat_photo.py | 2 +- 35 files changed, 402 insertions(+), 279 deletions(-) create mode 100644 docs/source/api/bound-methods.rst create mode 100644 docs/source/topics/glossary.rst diff --git a/compiler/docs/template/page.txt b/compiler/docs/template/page.txt index 25a396fa..638a10cf 100644 --- a/compiler/docs/template/page.txt +++ b/compiler/docs/template/page.txt @@ -1,5 +1,5 @@ {title} {title_markup} -.. autoclass:: {full_class_path} +.. autoclass:: {full_class_path}() :members: diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst new file mode 100644 index 00000000..d93497fe --- /dev/null +++ b/docs/source/api/bound-methods.rst @@ -0,0 +1,102 @@ +Bound Methods +============= + +Some Pyrogram types define what are called bound methods. Bound methods are functions attached to a class which are +accessed via an instance of that class. They make it even easier to call specific methods by automatically inferring +some of the required arguments. + +.. code-block:: python + :emphasize-lines: 8 + + from pyrogram import Client + + app = Client("my_account") + + + @app.on_message() + def hello(client, message) + message.reply("hi") + + + app.run() + +.. currentmodule:: pyrogram + +- Message_ +- CallbackQuery_ +- InlineQuery_ + +.. _Message: + +Message +------- + +- :meth:`Message.click()` +- :meth:`Message.delete()` +- :meth:`Message.download()` +- :meth:`Message.edit()` +- :meth:`Message.edit_caption()` +- :meth:`Message.edit_media()` +- :meth:`Message.edit_reply_markup()` +- :meth:`Message.forward()` +- :meth:`Message.pin()` +- :meth:`Message.reply()` +- :meth:`Message.reply_animation()` +- :meth:`Message.reply_audio()` +- :meth:`Message.reply_cached_media()` +- :meth:`Message.reply_chat_action()` +- :meth:`Message.reply_contact()` +- :meth:`Message.reply_document()` +- :meth:`Message.reply_game()` +- :meth:`Message.reply_inline_bot_result()` +- :meth:`Message.reply_location()` +- :meth:`Message.reply_media_group()` +- :meth:`Message.reply_photo()` +- :meth:`Message.reply_poll()` +- :meth:`Message.reply_sticker()` +- :meth:`Message.reply_venue()` +- :meth:`Message.reply_video()` +- :meth:`Message.reply_video_note()` +- :meth:`Message.reply_voice()` + +.. automethod:: Message.click() +.. automethod:: Message.delete() +.. automethod:: Message.download() +.. automethod:: Message.edit() +.. automethod:: Message.edit_caption() +.. automethod:: Message.edit_media() +.. automethod:: Message.edit_reply_markup() +.. automethod:: Message.forward() +.. automethod:: Message.pin() +.. automethod:: Message.reply() +.. automethod:: Message.reply_animation() +.. automethod:: Message.reply_audio() +.. automethod:: Message.reply_cached_media() +.. automethod:: Message.reply_chat_action() +.. automethod:: Message.reply_contact() +.. automethod:: Message.reply_document() +.. automethod:: Message.reply_game() +.. automethod:: Message.reply_inline_bot_result() +.. automethod:: Message.reply_location() +.. automethod:: Message.reply_media_group() +.. automethod:: Message.reply_photo() +.. automethod:: Message.reply_poll() +.. automethod:: Message.reply_sticker() +.. automethod:: Message.reply_venue() +.. automethod:: Message.reply_video() +.. automethod:: Message.reply_video_note() +.. automethod:: Message.reply_voice() + +.. _CallbackQuery: + +CallbackQuery +------------- + +.. automethod:: CallbackQuery.answer() + +.. _InlineQuery: + +InlineQuery +----------- + +.. automethod:: InlineQuery.answer() \ No newline at end of file diff --git a/docs/source/api/client.rst b/docs/source/api/client.rst index 05c5cd0c..01e3f5f8 100644 --- a/docs/source/api/client.rst +++ b/docs/source/api/client.rst @@ -1,7 +1,16 @@ Pyrogram Client =============== -The :class:`Client ` is the main class. It exposes easy-to-use methods that are named -after the well established Telegram Bot API methods, thus offering a familiar look to Bot developers. +This class exposes high-level methods for an easy access to the API. + +.. code-block:: python + :emphasize-lines: 1-3 + + from pyrogram import Client + + app = Client("my_account") + + with app: + app.send_message("me", "Hi!") .. autoclass:: pyrogram.Client() diff --git a/docs/source/api/decorators.rst b/docs/source/api/decorators.rst index a9cd70c7..26bd64e1 100644 --- a/docs/source/api/decorators.rst +++ b/docs/source/api/decorators.rst @@ -1,7 +1,7 @@ Decorators ========== -While still being methods bound to the :obj:`Client` class, decorators are of a special kind and thus deserve a +While still being methods bound to the :obj:`Client ` class, decorators are of a special kind and thus deserve a dedicated page. Decorators are able to register callback functions for handling updates in a much easier and cleaner way compared to @@ -9,13 +9,12 @@ Decorators are able to register callback functions for handling updates in a muc :meth:`add_handler() `, automatically. All you need to do is adding the decorators on top of your functions. -**Example:** - .. code-block:: python + :emphasize-lines: 6 from pyrogram import Client - app = Client(...) + app = Client("my_account") @app.on_message() diff --git a/docs/source/api/errors.rst b/docs/source/api/errors.rst index 29dcafac..fad571e3 100644 --- a/docs/source/api/errors.rst +++ b/docs/source/api/errors.rst @@ -5,27 +5,26 @@ All Pyrogram API errors live inside the ``errors`` sub-package: ``pyrogram.error The errors ids listed here are shown as *UPPER_SNAKE_CASE*, but the actual exception names to import from Pyrogram follow the usual *PascalCase* convention. -**Example**: - .. code-block:: python + :emphasize-lines: 1, 5 - from pyrogram.errors import InternalServerError + from pyrogram.errors import FloodWait try: ... - except FloodWait: + except FloodWait as e: ... -303 - See Other ---------------- +303 - SeeOther +-------------- .. csv-table:: :file: ../../../compiler/error/source/303_SEE_OTHER.tsv :delim: tab :header-rows: 1 -400 - Bad Request ------------------ +400 - BadRequest +---------------- .. csv-table:: :file: ../../../compiler/error/source/400_BAD_REQUEST.tsv @@ -48,8 +47,8 @@ follow the usual *PascalCase* convention. :delim: tab :header-rows: 1 -406 - Not Acceptable --------------------- +406 - NotAcceptable +------------------- .. csv-table:: :file: ../../../compiler/error/source/406_NOT_ACCEPTABLE.tsv @@ -64,8 +63,8 @@ follow the usual *PascalCase* convention. :delim: tab :header-rows: 1 -500 - Internal Server Error ---------------------------- +500 - InternalServerError +------------------------- .. csv-table:: :file: ../../../compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv diff --git a/docs/source/api/handlers.rst b/docs/source/api/handlers.rst index 08d40039..023f6e28 100644 --- a/docs/source/api/handlers.rst +++ b/docs/source/api/handlers.rst @@ -7,13 +7,12 @@ For a much more convenient way of registering callback functions have a look at In case you decided to manually create an handler, use :meth:`add_handler() ` to register it. -**Example:** - .. code-block:: python + :emphasize-lines: 1, 10 from pyrogram import Client, MessageHandler - app = Client(...) + app = Client("my_account") def dump(client, message): @@ -34,6 +33,7 @@ it. CallbackQueryHandler InlineQueryHandler UserStatusHandler + PollHandler DisconnectHandler RawUpdateHandler @@ -52,6 +52,9 @@ it. .. autoclass:: UserStatusHandler() :members: +.. autoclass:: PollHandler() + :members: + .. autoclass:: DisconnectHandler() :members: diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index 609a38a8..ded4d017 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -3,13 +3,12 @@ Available Methods All Pyrogram methods listed here are bound to a :obj:`Client ` instance. -**Example:** - .. code-block:: python + :emphasize-lines: 6 from pyrogram import Client - app = Client(...) + app = Client("my_account") with app: app.send_message("haskell", "hi") diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 710a772d..506fe003 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -3,9 +3,8 @@ Available Types All Pyrogram types listed here are accessible through the main package directly. -**Example:** - .. code-block:: python + :emphasize-lines: 1 from pyrogram import User, Message, ... @@ -112,167 +111,72 @@ InputMessageContent ------------ .. autoclass:: User() - :members: - .. autoclass:: UserStatus() - :members: - .. autoclass:: Chat() - :members: - .. autoclass:: ChatPreview() - :members: - .. autoclass:: ChatPhoto() - :members: - .. autoclass:: ChatMember() - :members: - .. autoclass:: ChatMembers() - :members: - .. autoclass:: ChatPermissions() - :members: - .. autoclass:: Dialog() - :members: - .. autoclass:: Dialogs() - :members: .. Messages & Media ---------------- .. autoclass:: Message() - :members: - .. autoclass:: Messages() - :members: - .. autoclass:: MessageEntity() - :members: - .. autoclass:: Photo() - :members: - .. autoclass:: PhotoSize() - :members: - .. autoclass:: UserProfilePhotos() - :members: - .. autoclass:: Audio() - :members: - .. autoclass:: Document() - :members: - .. autoclass:: Animation() - :members: - .. autoclass:: Video() - :members: - .. autoclass:: Voice() - :members: - .. autoclass:: VideoNote() - :members: - .. autoclass:: Contact() - :members: - .. autoclass:: Location() - :members: - .. autoclass:: Venue() - :members: - .. autoclass:: Sticker() - :members: - .. autoclass:: Game() - :members: - .. autoclass:: Poll() - :members: - .. autoclass:: PollOption() - :members: .. Keyboards --------- .. autoclass:: ReplyKeyboardMarkup() - :members: - .. autoclass:: KeyboardButton() - :members: - .. autoclass:: ReplyKeyboardRemove() - :members: - .. autoclass:: InlineKeyboardMarkup() - :members: - .. autoclass:: InlineKeyboardButton() - :members: - .. autoclass:: ForceReply() - :members: - .. autoclass:: CallbackQuery() - :members: - .. autoclass:: GameHighScore() - :members: - .. autoclass:: CallbackGame() - :members: .. Input Media ----------- .. autoclass:: InputMedia() - :members: - .. autoclass:: InputMediaPhoto() - :members: - .. autoclass:: InputMediaVideo() - :members: - .. autoclass:: InputMediaAudio() - :members: - .. autoclass:: InputMediaAnimation() - :members: - .. autoclass:: InputMediaDocument() - :members: - .. autoclass:: InputPhoneContact() - :members: - .. Inline Mode ----------- .. autoclass:: InlineQuery() - :members: - .. autoclass:: InlineQueryResult() - :members: - .. autoclass:: InlineQueryResultArticle() - :members: .. InputMessageContent ------------------- .. autoclass:: InputMessageContent() - :members: - .. autoclass:: InputTextMessageContent() - :members: diff --git a/docs/source/index.rst b/docs/source/index.rst index 9ff0f720..9b878baf 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -66,7 +66,7 @@ How the Documentation is Organized Contents are organized into self-contained topics and can be all accessed from the sidebar, or by following them in order using the Next button at the end of each page. Here below you can, instead, find a list of the most relevant -pages. +pages for a quick access. Getting Started ^^^^^^^^^^^^^^^ @@ -86,23 +86,27 @@ API Reference - `Client Class`_ - Details about the Client class. - `Available Methods`_ - A list of available high-level methods. - `Available Types`_ - A list of available high-level types. +- `Bound Methods`_ - A list of convenient bound methods. .. _Client Class: api/client .. _Available Methods: api/methods .. _Available Types: api/types +.. _Bound Methods: api/bound-methods -Topics -^^^^^^ +Relevant Topics +^^^^^^^^^^^^^^^ - `Smart Plugins`_ - How to modularize your application. - `Advanced Usage`_ - How to use Telegram's raw API. - `Release Notes`_ - Release notes for Pyrogram releases. - `Pyrogram FAQ`_ - Answers to common Pyrogram questions. +- `Pyrogram Glossary`_ - A list of words with brief explanations. .. _Smart Plugins: topics/smart-plugins .. _Advanced Usage: topics/advanced-usage .. _Release Notes: topics/releases .. _Pyrogram FAQ: topics/faq +.. _Pyrogram Glossary: topics/glossary .. toctree:: :hidden: @@ -128,6 +132,7 @@ Topics api/client api/methods api/types + api/bound-methods api/handlers api/decorators api/filters @@ -152,6 +157,7 @@ Topics topics/voice-calls topics/releases topics/faq + topics/glossary .. toctree:: :hidden: diff --git a/docs/source/intro/auth.rst b/docs/source/intro/auth.rst index 86217137..846a19a1 100644 --- a/docs/source/intro/auth.rst +++ b/docs/source/intro/auth.rst @@ -61,6 +61,7 @@ after the session name, which will be ``pyrogrambot.session`` for the example be "my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" ) + app.run() .. _project is set up: setup.html diff --git a/docs/source/intro/install.rst b/docs/source/intro/install.rst index e2e4365a..c4df60d4 100644 --- a/docs/source/intro/install.rst +++ b/docs/source/intro/install.rst @@ -29,12 +29,12 @@ Install Pyrogram Bleeding Edge ------------- -Things are constantly evolving in Pyrogram, although new releases are published only when enough changes are added, -but this doesn't mean you can't try new features right now! +Pyrogram is always evolving, although new releases on PyPI are published only when enough changes are added, but this +doesn't mean you can't try new features right now! -In case you would like to try out the latest Pyrogram features and additions, the `GitHub repo`_ is always kept updated -with new changes; you can install the development version straight from the ``develop`` branch using this command -(note "develop.zip" in the link): +In case you'd like to try out the latest Pyrogram features, the `GitHub repo`_ is always kept updated with new changes; +you can install the development version straight from the ``develop`` branch using this command (note "develop.zip" in +the link): .. code-block:: text @@ -44,7 +44,8 @@ Asynchronous ------------ Pyrogram heavily depends on IO-bound network code (it's a cloud-based messaging framework after all), and here's -where asyncio shines the most by providing extra performance while running on a single OS-level thread only. +where asyncio shines the most by providing extra performance and efficiency while running on a single OS-level thread +only. **A fully asynchronous variant of Pyrogram is therefore available** (Python 3.5.3+ required). Use this command to install (note "asyncio.zip" in the link): diff --git a/docs/source/intro/start.rst b/docs/source/intro/start.rst index 7d6f0150..2fcd4633 100644 --- a/docs/source/intro/start.rst +++ b/docs/source/intro/start.rst @@ -10,7 +10,7 @@ Get Pyrogram Real Fast 2. Get your own Telegram API key from https://my.telegram.org/apps. -3. Open your best text editor and paste the following: +3. Open your best text editor and paste the following: .. code-block:: python @@ -40,10 +40,9 @@ Enjoy the API ------------- That was just a quick overview that barely scratched the surface! -In the next few pages of the introduction, we'll take a much more in-depth look of what we have just done. +In the next few pages of the introduction, we'll take a much more in-depth look of what we have just done above. -Feeling eager? You can take a shortcut to `Calling Methods`_ and come back later to learn some more -details. +Feeling eager to continue? You can take a shortcut to `Calling Methods`_ and come back later to learn some more details. .. _community: //t.me/pyrogramchat .. _Calling Methods: ../start/invoking \ No newline at end of file diff --git a/docs/source/start/errors.rst b/docs/source/start/errors.rst index 1260672e..1f4f5a2e 100644 --- a/docs/source/start/errors.rst +++ b/docs/source/start/errors.rst @@ -1,51 +1,57 @@ Error Handling ============== -Errors are inevitable when working with the API, and they must be correctly handled with ``try..except`` blocks. - -There are many errors that Telegram could return, but they all fall in one of these categories -(which are in turn children of the ``RPCError`` superclass): - -- `303 - See Other <../api/errors#see-other>`_ -- `400 - Bad Request <../api/errors#bad-request>`_ -- `401 - Unauthorized <../api/errors#unauthorized>`_ -- `403 - Forbidden <../api/errors#forbidden>`_ -- `406 - Not Acceptable <../api/errors#not-acceptable>`_ -- `420 - Flood <../api/errors#flood>`_ -- `500 - Internal Server Error <../api/errors#internal-server-error>`_ - -As stated above, there are really many (too many) errors, and in case Pyrogram does not know anything yet about a -specific one, it raises a special ``520 Unknown Error`` exception and logs it -in the ``unknown_errors.txt`` file. Users are invited to report these unknown errors. - -Examples --------- +Errors are inevitable when working with the API, and they must be correctly handled with ``try..except`` blocks in order +to control the behaviour of your application. Pyrogram errors all live inside the ``errors`` package: .. code-block:: python - from pyrogram.errors import ( - BadRequest, Flood, InternalServerError, - SeeOther, Unauthorized, UnknownError - ) + from pyrogram import errors - try: - ... - except BadRequest: - pass - except Flood: - pass - except InternalServerError: - pass - except SeeOther: - pass - except Unauthorized: - pass - except UnknownError: - pass +RPCError +-------- -Exception objects may also contain some informative values. -E.g.: ``FloodWait`` holds the amount of seconds you have to wait -before you can try again. The value is always stored in the ``x`` field of the returned exception object: +The father of all errors is named ``RPCError``. This error exists in form of a Python exception and is able to catch all +Telegram API related errors. + +.. code-block:: python + + from pyrogram.errors import RPCError + +.. warning:: + + It must be noted that catching this error is bad practice, especially when no feedback is given (i.e. by + logging/printing the full error traceback), because it makes it impossible to understand what went wrong. + +Error Categories +---------------- + +The ``RPCError`` packs together all the possible errors Telegram could raise, but to make things tidier, Pyrogram +provides categories of errors, which are named after the common HTTP errors: + +.. code-block:: python + + from pyrogram.errors import BadRequest, Forbidden, ... + +- `303 - SeeOther <../api/errors#seeother>`_ +- `400 - BadRequest <../api/errors#badrequest>`_ +- `401 - Unauthorized <../api/errors#unauthorized>`_ +- `403 - Forbidden <../api/errors#forbidden>`_ +- `406 - NotAcceptable <../api/errors#notacceptable>`_ +- `420 - Flood <../api/errors#flood>`_ +- `500 - InternalServerError <../api/errors#internalservererror>`_ + +Unknown Errors +-------------- + +In case Pyrogram does not know anything yet about a specific error, it raises a special ``520 - UnknownError`` exception +and logs it in the ``unknown_errors.txt`` file. Users are invited to report these unknown errors. + +Errors with Values +------------------ + +Exception objects may also contain some informative values. For example, ``FloodWait`` holds the amount of seconds you +have to wait before you can try again. The value is always stored in the ``x`` field of the returned exception object: .. code-block:: python @@ -55,4 +61,4 @@ before you can try again. The value is always stored in the ``x`` field of the r try: ... except FloodWait as e: - time.sleep(e.x) + time.sleep(e.x) # Wait before trying again diff --git a/docs/source/start/invoking.rst b/docs/source/start/invoking.rst index c27e86c3..fae19523 100644 --- a/docs/source/start/invoking.rst +++ b/docs/source/start/invoking.rst @@ -1,9 +1,12 @@ Calling Methods =============== -At this point, we have successfully `installed Pyrogram`_ and authorized_ our account; we are now pointing towards the +At this point, we have successfully `installed Pyrogram`_ and authorized_ our account; we are now aiming towards the core of the library. It's time to start playing with the API! +Basic Usage +----------- + Making API method calls with Pyrogram is very simple. Here's an example we are going to examine: .. code-block:: python @@ -60,8 +63,8 @@ Context Manager --------------- You can also use Pyrogram's Client in a context manager with the ``with`` statement. The client will automatically -:meth:`start ` and :meth:`stop ` gracefully, even in case of unhandled -exceptions in your code. The example above can be therefore rewritten in a much nicer way, this way: +:meth:`start() ` and :meth:`stop() ` gracefully, even in case of unhandled +exceptions in your code. The example above can be therefore rewritten in a much nicer way: .. code-block:: python diff --git a/docs/source/start/updates.rst b/docs/source/start/updates.rst index 85005b9c..930096a3 100644 --- a/docs/source/start/updates.rst +++ b/docs/source/start/updates.rst @@ -8,7 +8,7 @@ Defining Updates ---------------- First, let's define what are these updates. As hinted already, updates are simply events that happen in your Telegram -account (incoming messages, new members join, button presses, etc...), which are meant to notify you about a new +account (incoming messages, new members join, bot button presses, etc...), which are meant to notify you about a new specific state that changed. These updates are handled by registering one or more callback functions in your app using `Handlers <../api/handlers>`_. @@ -70,7 +70,7 @@ begins. app.add_handler(my_handler) -Last one, the :meth:`run() ` method. What this does is simply calling +Last one, the :meth:`run() ` method. What this does is simply call :meth:`start() ` and a special method :meth:`idle() ` that keeps your main scripts alive until you press ``CTRL+C``; the client will be automatically stopped after that. diff --git a/docs/source/topics/advanced-usage.rst b/docs/source/topics/advanced-usage.rst index 970e07e0..02a3e3b6 100644 --- a/docs/source/topics/advanced-usage.rst +++ b/docs/source/topics/advanced-usage.rst @@ -101,9 +101,9 @@ sending messages with IDs only thanks to cached access hashes. There are three different InputPeer types, one for each kind of Telegram entity. Whenever an InputPeer is needed you must pass one of these: - - `InputPeerUser `_ - Users - - `InputPeerChat `_ - Basic Chats - - `InputPeerChannel `_ - Either Channels or Supergroups + - :obj:`InputPeerUser <../telegram/types/InputPeerUser>` - Users + - :obj:`InputPeerChat <../telegram/types/InputPeerChat>` - Basic Chats + - :obj:`InputPeerChannel <../telegram/types/InputPeerChannel>` - Either Channels or Supergroups But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides :meth:`resolve_peer() ` as a convenience utility method that returns the correct InputPeer diff --git a/docs/source/topics/faq.rst b/docs/source/topics/faq.rst index 0834389e..7f2086a1 100644 --- a/docs/source/topics/faq.rst +++ b/docs/source/topics/faq.rst @@ -17,21 +17,51 @@ C. It enables you to easily create custom applications for both user and bot ide .. _Telegram: https://telegram.org .. _MTProto API: https://core.telegram.org/api#telegram-api -What does "Pyrogram" mean? --------------------------- +What does the name mean? +------------------------ The word "Pyrogram" is composed by **pyro**, which comes from the Greek word *πῦρ (pyr)*, meaning fire, and **gram**, from *Telegram*. The word *pyro* itself is built from *Python*, **py** for short, and the suffix **ro** to come up with the word *fire*, which also inspired the project logo. -How old is Pyrogram? --------------------- +How old is the project? +----------------------- Pyrogram was first released on December 12, 2017. The actual work on the framework began roughly three months prior the initial public release on `GitHub`_. .. _GitHub: https://github.com/pyrogram/pyrogram +Why Pyrogram? +------------- + +- **Easy**: You can install Pyrogram with pip and start building your applications right away. +- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way. +- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C. +- **Documented**: Pyrogram API methods, types and public interfaces are well documented. +- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. +- **Updated**, to make use of the latest Telegram API version and features. +- **Pluggable**: The `Smart Plugin`_ system allows to write components with minimal boilerplate code. +- **Comprehensive**: Execute any `advanced action`_ an official client is able to do, and even more. + +.. _TgCrypto: https://github.com/pyrogram/tgcrypto +.. _Smart Plugin: smart-plugins +.. _advanced action: advanced-usage + +What can MTProto do more than the Bot API? +------------------------------------------ + +- Authorize both user and bot identities. +- Upload & download any file, up to 1500 MB each. +- Has less overhead due to direct connections to the actual Telegram servers. +- Run multiple sessions at once, up to 10 per account (either bot or user). +- Get information about any public chat by usernames, even if not a member. +- Obtain information about any message existing in a chat using message ids. +- retrieve the whole chat members list of either public or private chats. +- Receive extra updates, such as the one about a user name change. +- More meaningful errors in case something went wrong. +- Get API version updates, and thus new features, sooner. + Why do I need an API key for bots? ---------------------------------- @@ -46,6 +76,8 @@ Using MTProto is the only way to communicate with the actual Telegram servers, a identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone number only. +Why is the main API (MTProto) superiod + I started a client but nothing happens! --------------------------------------- @@ -65,7 +97,7 @@ in a bunch of seconds: .. _you need a proxy: proxy -I keep getting [400 PEER_ID_INVALID] error! +I keep getting PEER_ID_INVALID error! ------------------------------------------- The error in question is **[400 PEER_ID_INVALID]: The id/access_hash combination is invalid**, and could mean several @@ -104,4 +136,18 @@ mistakes by either the automatic systems or a moderator. In such cases you can k recover@telegram.org, contact `@smstelegram`_ on Twitter or use `this form`_. .. _@smstelegram: https://twitter.com/smstelegram -.. _this form: https://telegram.org/support \ No newline at end of file +.. _this form: https://telegram.org/support + +About the License +----------------- + +.. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png + :align: left + +Pyrogram is free software and is currently licensed under the terms of the GNU Lesser General Public License v3 or later +(LGPLv3+). In short: you may use, redistribute and/or modify it provided that modifications are described and licensed +for free under LGPLv3+. + +In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or a +different licence or even proprietary --- without being required to release the source code of your own applications. +However, any modifications to the library itself are required to be published for free under the same LGPLv3+ license. \ No newline at end of file diff --git a/docs/source/topics/filters.rst b/docs/source/topics/filters.rst index ec3e2e10..cb2e2a4c 100644 --- a/docs/source/topics/filters.rst +++ b/docs/source/topics/filters.rst @@ -7,6 +7,9 @@ but there's much more than that to come. Here we'll discuss about :class:`Filters `. Filters enable a fine-grain control over what kind of updates are allowed or not to be passed in your callback functions, based on their inner details. +Single Filters +-------------- + Let's start right away with a simple example: - This example will show you how to **only** handle messages containing an :obj:`Audio ` object and diff --git a/docs/source/topics/glossary.rst b/docs/source/topics/glossary.rst new file mode 100644 index 00000000..5721306c --- /dev/null +++ b/docs/source/topics/glossary.rst @@ -0,0 +1,53 @@ +Pyrogram Glossary +----------------- + +This page contains a list of common words with brief explanations related to Pyrogram and, to some extent, Telegram in +general. + +.. glossary:: + + API + Application Programming Interface: a set of methods, protocols and tools that make it easier to develop programs + by providing useful building blocks to the developer. + + API key + A secret code used to authenticate and/or authorize a specific application to Telegram in order for it to + control how the API is being used, for example, to prevent abuses of the API. + + MTProto + The name of the custom-made, open encryption protocol by Telegram, implemented in Pyrogram. + + MTProto API + The Telegram main API Pyrogram makes use of, which is able to connect both users and normal bots to Telegram + using MTProto as application layer protocol and execute any method Telegram provides from its public schema. + + Bot API + The `Telegram Bot API`_ that is able to only connect normal bots to Telegram using HTTP as application layer + protocol and allows to execute a subset of the main Telegram API. + + Pyrogrammer + A developer that uses Pyrogram to build Telegram applications. + + Userbot + Also known as *user bot* or *ubot* for short, is a user logged in by third-party Telegram libraries --- such as + Pyrogram --- to automate some behaviours, like sending messages or reacting to text commands or any other event. + + Session + Also known as *login session*, is a strictly personal piece of information created and held by both parties + (client and server) which is used to grant permission into a single account without having to start a new + authorization process from scratch. + + Callback + Also known as *callback function*, is a user-defined generic function that *can be* registered to and then + called-back by the framework when specific events occurs. + + Handler + An object that wraps around a callback function that is *actually meant* to be registered into the framework, + which will then be able to handle a specific kind of events, such as a new incoming message, for example. + + Decorator + Also known as *function decorator*, in Python, is a callable object that is used to modify another function. + Decorators in Pyrogram are used to automatically register callback functions for `handling updates`_. + +.. _Telegram Bot API: https://core.telegram.org/bots/api +.. _handling updates: ../start/updates \ No newline at end of file diff --git a/docs/source/topics/smart-plugins.rst b/docs/source/topics/smart-plugins.rst index fbe27388..9f1592d1 100644 --- a/docs/source/topics/smart-plugins.rst +++ b/docs/source/topics/smart-plugins.rst @@ -30,7 +30,7 @@ after importing your modules, like this: handlers.py main.py -- ``handlers.py`` +- ``handlers.py`` .. code-block:: python @@ -41,7 +41,7 @@ after importing your modules, like this: def echo_reversed(client, message): message.reply(message.text[::-1]) -- ``main.py`` +- ``main.py`` .. code-block:: python @@ -91,7 +91,7 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight config.ini main.py -- ``plugins/handlers.py`` +- ``plugins/handlers.py`` .. code-block:: python :emphasize-lines: 4, 9 @@ -108,14 +108,14 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight def echo_reversed(client, message): message.reply(message.text[::-1]) -- ``config.ini`` +- ``config.ini`` .. code-block:: ini [plugins] root = plugins -- ``main.py`` +- ``main.py`` .. code-block:: python @@ -199,8 +199,8 @@ also organized in subfolders: ... ... -- Load every handler from every module, namely *plugins0.py*, *plugins1.py* and *plugins2.py* in alphabetical order - (files) and definition order (handlers inside files): +- Load every handler from every module, namely *plugins0.py*, *plugins1.py* and *plugins2.py* in alphabetical order + (files) and definition order (handlers inside files): Using *config.ini* file: @@ -217,7 +217,7 @@ also organized in subfolders: Client("my_account", plugins=plugins).run() -- Load only handlers defined inside *plugins2.py* and *plugins0.py*, in this order: +- Load only handlers defined inside *plugins2.py* and *plugins0.py*, in this order: Using *config.ini* file: @@ -243,7 +243,7 @@ also organized in subfolders: Client("my_account", plugins=plugins).run() -- Load everything except the handlers inside *plugins2.py*: +- Load everything except the handlers inside *plugins2.py*: Using *config.ini* file: @@ -264,7 +264,7 @@ also organized in subfolders: Client("my_account", plugins=plugins).run() -- Load only *fn3*, *fn1* and *fn2* (in this order) from *plugins1.py*: +- Load only *fn3*, *fn1* and *fn2* (in this order) from *plugins1.py*: Using *config.ini* file: @@ -297,7 +297,7 @@ Each function decorated with the usual ``on_message`` decorator (or any other de *(handler: Handler, group: int)*. The actual callback function is therefore stored inside the handler's *callback* attribute. Here's an example: -- ``plugins/handlers.py`` +- ``plugins/handlers.py`` .. code-block:: python :emphasize-lines: 5, 6 @@ -321,7 +321,7 @@ In order to unload a plugin, or any other handler, all you need to do is obtain relevant module and call :meth:`remove_handler() ` Client's method with your function name preceded by the star ``*`` operator as argument. Example: -- ``main.py`` +- ``main.py`` .. code-block:: python @@ -345,7 +345,7 @@ Loading Similarly to the unloading process, in order to load again a previously unloaded plugin you do the same, but this time using :meth:`add_handler() ` instead. Example: -- ``main.py`` +- ``main.py`` .. code-block:: python diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 31a7c14c..d382b2fb 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -60,9 +60,7 @@ log = logging.getLogger(__name__) class Client(Methods, BaseClient): - """This class represents a Client, the main means for interacting with Telegram. - It exposes bot-like methods for an easy access to the API as well as a simple way to - invoke every single Telegram API method available. + """Pyrogram Client, the main means for interacting with Telegram. Parameters: session_name (``str``): @@ -80,7 +78,7 @@ class Client(Methods, BaseClient): This is an alternative way to pass it if you don't want to use the *config.ini* file. app_version (``str``, *optional*): - Application version. Defaults to "Pyrogram \U0001f525 vX.Y.Z" + Application version. Defaults to "Pyrogram :fire: vX.Y.Z" This is an alternative way to set it if you don't want to use the *config.ini* file. device_model (``str``, *optional*): @@ -110,6 +108,10 @@ class Client(Methods, BaseClient): Only applicable for new sessions and will be ignored in case previously created sessions are loaded. + bot_token (``str``, *optional*): + Pass your Bot API token to create a bot session, e.g.: "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" + Only applicable for new sessions. + phone_number (``str`` | ``callable``, *optional*): Pass your phone number as string (with your Country Code prefix included) to avoid entering it manually. Or pass a callback function which accepts no arguments and must return the correct phone number as string @@ -143,10 +145,6 @@ class Client(Methods, BaseClient): a new Telegram account in case the phone number you passed is not registered yet. Only applicable for new sessions. - bot_token (``str``, *optional*): - Pass your Bot API token to create a bot session, e.g.: "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" - Only applicable for new sessions. - last_name (``str``, *optional*): Same purpose as *first_name*; pass a Last Name to avoid entering it manually. It can be an empty string: "". Only applicable for new sessions. @@ -193,12 +191,12 @@ class Client(Methods, BaseClient): ipv6: bool = False, proxy: dict = None, test_mode: bool = False, + bot_token: str = None, phone_number: str = None, phone_code: Union[str, callable] = None, password: str = None, recovery_code: callable = None, force_sms: bool = False, - bot_token: str = None, first_name: str = None, last_name: str = None, workers: int = BaseClient.WORKERS, @@ -221,12 +219,12 @@ class Client(Methods, BaseClient): # TODO: Make code consistent, use underscore for private/protected fields self._proxy = proxy self.test_mode = test_mode + self.bot_token = bot_token self.phone_number = phone_number self.phone_code = phone_code self.password = password self.recovery_code = recovery_code self.force_sms = force_sms - self.bot_token = bot_token self.first_name = first_name self.last_name = last_name self.workers = workers diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 2117ec6e..169193a0 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -191,35 +191,19 @@ class Filters: """Filter messages sent via inline bots""" service = create("Service", lambda _, m: bool(m.service)) - """Filter service messages. A service message contains any of the following fields set + """Filter service messages. - - 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_score""" + A service message contains any of the following fields set: *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_score*. + """ media = create("Media", lambda _, m: bool(m.media)) - """Filter media messages. A media message contains any of the following fields set + """Filter media messages. - - audio - - document - - photo - - sticker - - video - - animation - - voice - - video_note - - contact - - location - - venue - - poll""" + A media message contains any of the following fields set: *audio*, *document*, *photo*, *sticker*, *video*, + *animation*, *voice*, *video_note*, *contact*, *location*, *venue*, *poll*. + """ @staticmethod def command( diff --git a/pyrogram/client/methods/decorators/on_callback_query.py b/pyrogram/client/methods/decorators/on_callback_query.py index 9ead25b4..b76655fb 100644 --- a/pyrogram/client/methods/decorators/on_callback_query.py +++ b/pyrogram/client/methods/decorators/on_callback_query.py @@ -30,7 +30,8 @@ class OnCallbackQuery(BaseClient): filters=None, group: int = 0 ) -> callable: - """Use this decorator to automatically register a function for handling callback queries. + """Decorator for handling callback queries. + This does the same thing as :meth:`add_handler` using the :class:`CallbackQueryHandler`. Parameters: diff --git a/pyrogram/client/methods/decorators/on_deleted_messages.py b/pyrogram/client/methods/decorators/on_deleted_messages.py index eb9dfcd0..7637e6eb 100644 --- a/pyrogram/client/methods/decorators/on_deleted_messages.py +++ b/pyrogram/client/methods/decorators/on_deleted_messages.py @@ -30,7 +30,8 @@ class OnDeletedMessages(BaseClient): filters=None, group: int = 0 ) -> callable: - """Use this decorator to automatically register a function for handling deleted messages. + """Decorator for handling deleted messages. + This does the same thing as :meth:`add_handler` using the :class:`DeletedMessagesHandler`. Parameters: diff --git a/pyrogram/client/methods/decorators/on_disconnect.py b/pyrogram/client/methods/decorators/on_disconnect.py index 515a28c1..9305808e 100644 --- a/pyrogram/client/methods/decorators/on_disconnect.py +++ b/pyrogram/client/methods/decorators/on_disconnect.py @@ -23,7 +23,8 @@ from ...ext import BaseClient class OnDisconnect(BaseClient): def on_disconnect(self=None) -> callable: - """Use this decorator to automatically register a function for handling disconnections. + """Decorator for handling disconnections. + This does the same thing as :meth:`add_handler` using the :class:`DisconnectHandler`. """ diff --git a/pyrogram/client/methods/decorators/on_inline_query.py b/pyrogram/client/methods/decorators/on_inline_query.py index e9758c64..58837398 100644 --- a/pyrogram/client/methods/decorators/on_inline_query.py +++ b/pyrogram/client/methods/decorators/on_inline_query.py @@ -30,7 +30,8 @@ class OnInlineQuery(BaseClient): filters=None, group: int = 0 ) -> callable: - """Use this decorator to automatically register a function for handling inline queries. + """Decorator for handling inline queries. + This does the same thing as :meth:`add_handler` using the :class:`InlineQueryHandler`. Parameters: diff --git a/pyrogram/client/methods/decorators/on_message.py b/pyrogram/client/methods/decorators/on_message.py index ad95cd45..f590fd12 100644 --- a/pyrogram/client/methods/decorators/on_message.py +++ b/pyrogram/client/methods/decorators/on_message.py @@ -30,7 +30,8 @@ class OnMessage(BaseClient): filters=None, group: int = 0 ) -> callable: - """Use this decorator to automatically register a function for handling messages. + """Decorator for handling messages. + This does the same thing as :meth:`add_handler` using the :class:`MessageHandler`. Parameters: diff --git a/pyrogram/client/methods/decorators/on_poll.py b/pyrogram/client/methods/decorators/on_poll.py index 68f3d78e..de1c1d3d 100644 --- a/pyrogram/client/methods/decorators/on_poll.py +++ b/pyrogram/client/methods/decorators/on_poll.py @@ -30,7 +30,8 @@ class OnPoll(BaseClient): filters=None, group: int = 0 ) -> callable: - """Use this decorator to automatically register a function for handling poll updates. + """Decorator for handling poll updates. + This does the same thing as :meth:`add_handler` using the :class:`PollHandler`. Parameters: diff --git a/pyrogram/client/methods/decorators/on_raw_update.py b/pyrogram/client/methods/decorators/on_raw_update.py index 2ab1f61b..53a0f4cf 100644 --- a/pyrogram/client/methods/decorators/on_raw_update.py +++ b/pyrogram/client/methods/decorators/on_raw_update.py @@ -28,7 +28,8 @@ class OnRawUpdate(BaseClient): self=None, group: int = 0 ) -> callable: - """Use this decorator to automatically register a function for handling raw updates. + """Decorator for handling raw updates. + This does the same thing as :meth:`add_handler` using the :class:`RawUpdateHandler`. Parameters: diff --git a/pyrogram/client/methods/decorators/on_user_status.py b/pyrogram/client/methods/decorators/on_user_status.py index 5b49bb3c..e7db7b74 100644 --- a/pyrogram/client/methods/decorators/on_user_status.py +++ b/pyrogram/client/methods/decorators/on_user_status.py @@ -30,7 +30,7 @@ class OnUserStatus(BaseClient): filters=None, group: int = 0 ) -> callable: - """Use this decorator to automatically register a function for handling user status updates. + """Decorator for handling user status updates. This does the same thing as :meth:`add_handler` using the :class:`UserStatusHandler`. Parameters: diff --git a/pyrogram/client/methods/messages/forward_messages.py b/pyrogram/client/methods/messages/forward_messages.py index a3e161fb..82c35f92 100644 --- a/pyrogram/client/methods/messages/forward_messages.py +++ b/pyrogram/client/methods/messages/forward_messages.py @@ -28,7 +28,7 @@ class ForwardMessages(BaseClient): self, chat_id: Union[int, str], from_chat_id: Union[int, str], - message_ids: Iterable[int], + message_ids: Union[int, Iterable[int]], disable_notification: bool = None, as_copy: bool = False, remove_caption: bool = False diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index e966a11a..66b3f1c9 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -46,7 +46,7 @@ class SendDocument(BaseClient): progress: callable = None, progress_args: tuple = () ) -> Union["pyrogram.Message", None]: - """Send general files. + """Send generic files. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/types/keyboards/callback_query.py b/pyrogram/client/types/keyboards/callback_query.py index 4d657767..fe6a2175 100644 --- a/pyrogram/client/types/keyboards/callback_query.py +++ b/pyrogram/client/types/keyboards/callback_query.py @@ -30,9 +30,9 @@ from ..user_and_chats import User class CallbackQuery(PyrogramType, Update): """An incoming callback query from a callback button in an inline keyboard. - If the button that originated the query was attached to a message sent by the bot, the field message - will be present. If the button was attached to a message sent via the bot (in inline mode), - the field inline_message_id will be present. Exactly one of the fields data or game_short_name will be present. + If the button that originated the query was attached to a message sent by the bot, the field *message* + will be present. If the button was attached to a message sent via the bot (in inline mode), the field + *inline_message_id* will be present. Exactly one of the fields *data* or *game_short_name* will be present. Parameters: id (``str``): diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index a8f6d31b..e51f3425 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -661,7 +661,7 @@ class Message(PyrogramType, Update): reply_to_message_id: int = None, reply_markup=None ) -> "Message": - """Bound method *reply* of :obj:`Message`. + """Bound method *reply* :obj:`Message `. Use as a shortcut for: @@ -748,7 +748,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_animation* of :obj:`Message`. + """Bound method *reply_animation* :obj:`Message `. Use as a shortcut for: @@ -882,7 +882,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_audio* of :obj:`Message`. + """Bound method *reply_audio* :obj:`Message `. Use as a shortcut for: @@ -1010,7 +1010,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_cached_media* of :obj:`Message`. + """Bound method *reply_cached_media* :obj:`Message `. Use as a shortcut for: @@ -1077,7 +1077,7 @@ class Message(PyrogramType, Update): ) def reply_chat_action(self, action: str) -> bool: - """Bound method *reply_chat_action* of :obj:`Message`. + """Bound method *reply_chat_action* :obj:`Message `. Use as a shortcut for: @@ -1130,7 +1130,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_contact* of :obj:`Message`. + """Bound method *reply_contact* :obj:`Message `. Use as a shortcut for: @@ -1217,7 +1217,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_document* of :obj:`Message`. + """Bound method *reply_document* :obj:`Message `. Use as a shortcut for: @@ -1331,7 +1331,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_game* of :obj:`Message`. + """Bound method *reply_game* :obj:`Message `. Use as a shortcut for: @@ -1396,7 +1396,7 @@ class Message(PyrogramType, Update): reply_to_message_id: int = None, hide_via: bool = None ) -> "Message": - """Bound method *reply_inline_bot_result* of :obj:`Message`. + """Bound method *reply_inline_bot_result* :obj:`Message `. Use as a shortcut for: @@ -1470,7 +1470,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_location* of :obj:`Message`. + """Bound method *reply_location* :obj:`Message `. Use as a shortcut for: @@ -1538,7 +1538,7 @@ class Message(PyrogramType, Update): disable_notification: bool = None, reply_to_message_id: int = None ) -> "Message": - """Bound method *reply_media_group* of :obj:`Message`. + """Bound method *reply_media_group* :obj:`Message `. Use as a shortcut for: @@ -1610,7 +1610,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_photo* of :obj:`Message`. + """Bound method *reply_photo* :obj:`Message `. Use as a shortcut for: @@ -1724,7 +1724,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_poll* of :obj:`Message`. + """Bound method *reply_poll* :obj:`Message `. Use as a shortcut for: @@ -1800,7 +1800,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_sticker* of :obj:`Message`. + """Bound method *reply_sticker* :obj:`Message `. Use as a shortcut for: @@ -1903,7 +1903,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_venue* of :obj:`Message`. + """Bound method *reply_venue* :obj:`Message `. Use as a shortcut for: @@ -2005,7 +2005,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video* of :obj:`Message`. + """Bound method *reply_video* :obj:`Message `. Use as a shortcut for: @@ -2140,7 +2140,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video_note* of :obj:`Message`. + """Bound method *reply_video_note* :obj:`Message `. Use as a shortcut for: @@ -2258,7 +2258,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_voice* of :obj:`Message`. + """Bound method *reply_voice* :obj:`Message `. Use as a shortcut for: @@ -2368,7 +2368,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit* of :obj:`Message` + """Bound method *edit* :obj:`Message `. Use as a shortcut for: @@ -2425,7 +2425,7 @@ class Message(PyrogramType, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit_caption* of :obj:`Message` + """Bound method *edit_caption* :obj:`Message `. Use as a shortcut for: @@ -2468,7 +2468,7 @@ class Message(PyrogramType, Update): ) def edit_media(self, media: InputMedia, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_media* of :obj:`Message` + """Bound method *edit_media* :obj:`Message `. Use as a shortcut for: @@ -2506,7 +2506,7 @@ class Message(PyrogramType, Update): ) def edit_reply_markup(self, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_reply_markup* of :obj:`Message` + """Bound method *edit_reply_markup* :obj:`Message `. Use as a shortcut for: @@ -2547,7 +2547,7 @@ class Message(PyrogramType, Update): as_copy: bool = False, remove_caption: bool = False ) -> "Message": - """Bound method *forward* of :obj:`Message`. + """Bound method *forward* :obj:`Message `. Use as a shortcut for: @@ -2690,7 +2690,7 @@ class Message(PyrogramType, Update): ) def delete(self, revoke: bool = True): - """Bound method *delete* of :obj:`Message`. + """Bound method *delete* :obj:`Message `. Use as a shortcut for: @@ -2726,7 +2726,7 @@ class Message(PyrogramType, Update): ) def click(self, x: int or str, y: int = 0, quote: bool = None, timeout: int = 10): - """Bound method *click* of :obj:`Message`. + """Bound method *click* :obj:`Message `. Use as a shortcut for clicking a button attached to the message instead of: @@ -2764,6 +2764,7 @@ class Message(PyrogramType, Update): Parameters: x (``int`` | ``str``): Used as integer index, integer abscissa (in pair with y) or as string label. + Defaults to 0 (first button). y (``int``, *optional*): Used as ordinate only (in pair with x). @@ -2853,7 +2854,7 @@ class Message(PyrogramType, Update): progress: callable = None, progress_args: tuple = () ) -> str: - """Bound method *download* of :obj:`Message`. + """Bound method *download* :obj:`Message `. Use as a shortcut for: @@ -2902,7 +2903,7 @@ class Message(PyrogramType, Update): ) def pin(self, disable_notification: bool = None) -> "Message": - """Bound method *pin* of :obj:`Message`. + """Bound method *pin* :obj:`Message `. Use as a shortcut for: diff --git a/pyrogram/client/types/user_and_chats/chat_photo.py b/pyrogram/client/types/user_and_chats/chat_photo.py index 37fde9fd..08e43138 100644 --- a/pyrogram/client/types/user_and_chats/chat_photo.py +++ b/pyrogram/client/types/user_and_chats/chat_photo.py @@ -25,7 +25,7 @@ from ...ext.utils import encode class ChatPhoto(PyrogramType): - """a chat photo. + """A chat photo. Parameters: small_file_id (``str``): From fd69f45e985e2914fa6a174e471a20beacd331f8 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 16 May 2019 21:29:09 +0200 Subject: [PATCH 064/202] Add CHAT_SEND_MEDIA_FORBIDDEN and INVITE_HASH_EXPIRED error --- compiler/error/source/400_BAD_REQUEST.tsv | 3 ++- compiler/error/source/403_FORBIDDEN.tsv | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index 8325040d..db2f0e58 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -96,4 +96,5 @@ EXTERNAL_URL_INVALID The external media URL is invalid CHAT_NOT_MODIFIED The chat settings were not modified RESULTS_TOO_MUCH The result contains too many items RESULT_ID_DUPLICATE The result contains items with duplicated identifiers -ACCESS_TOKEN_INVALID The bot access token is invalid \ No newline at end of file +ACCESS_TOKEN_INVALID The bot access token is invalid +INVITE_HASH_EXPIRED The chat invite link is no longer valid \ No newline at end of file diff --git a/compiler/error/source/403_FORBIDDEN.tsv b/compiler/error/source/403_FORBIDDEN.tsv index 34433da7..ddd8d26f 100644 --- a/compiler/error/source/403_FORBIDDEN.tsv +++ b/compiler/error/source/403_FORBIDDEN.tsv @@ -2,4 +2,5 @@ id message CHAT_WRITE_FORBIDDEN You don't have rights to send messages in this chat RIGHT_FORBIDDEN One or more admin rights can't be applied to this kind of chat (channel/supergroup) CHAT_ADMIN_INVITE_REQUIRED You don't have rights to invite other users -MESSAGE_DELETE_FORBIDDEN You don't have rights to delete messages in this chat \ No newline at end of file +MESSAGE_DELETE_FORBIDDEN You don't have rights to delete messages in this chat +CHAT_SEND_MEDIA_FORBIDDEN You can't send media messages in this chat \ No newline at end of file From 82c3bb2dba983cf9f7d7c1dedd1616380d63692b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 17 May 2019 13:13:58 +0200 Subject: [PATCH 065/202] Add three more internal server errors --- compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv index d1c666c6..4dfe5994 100644 --- a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv +++ b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv @@ -5,4 +5,7 @@ RPC_MCGET_FAIL Telegram is having internal problems. Please try again later PERSISTENT_TIMESTAMP_OUTDATED Telegram is having internal problems. Please try again later HISTORY_GET_FAILED Telegram is having internal problems. Please try again later REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later -RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later \ No newline at end of file +RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later +WORKER_BUSY_TOO_LONG_RETRY Telegram is having internal problems. Please try again later +INTERDC_X_CALL_ERROR Telegram is having internal problems. Please try again later +INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems. Please try again later \ No newline at end of file From 53d0cc30f644623ceff7977e05613b9d01cc818f Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 17 May 2019 13:18:24 +0200 Subject: [PATCH 066/202] Remove get_chat_preview and have get_chat deal with ChatPreview objects --- pyrogram/client/methods/chats/__init__.py | 2 - pyrogram/client/methods/chats/get_chat.py | 14 ++-- .../client/methods/chats/get_chat_preview.py | 67 ------------------- .../types/user_and_chats/chat_preview.py | 4 +- 4 files changed, 9 insertions(+), 78 deletions(-) delete mode 100644 pyrogram/client/methods/chats/get_chat_preview.py diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index 8db44abe..698255f5 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -22,7 +22,6 @@ from .get_chat import GetChat from .get_chat_member import GetChatMember from .get_chat_members import GetChatMembers from .get_chat_members_count import GetChatMembersCount -from .get_chat_preview import GetChatPreview from .get_dialogs import GetDialogs from .iter_chat_members import IterChatMembers from .iter_dialogs import IterDialogs @@ -61,7 +60,6 @@ class Chats( UnpinChatMessage, GetDialogs, GetChatMembersCount, - GetChatPreview, IterDialogs, IterChatMembers, UpdateChatUsername, diff --git a/pyrogram/client/methods/chats/get_chat.py b/pyrogram/client/methods/chats/get_chat.py index 96bc9eaf..4f71c3b3 100644 --- a/pyrogram/client/methods/chats/get_chat.py +++ b/pyrogram/client/methods/chats/get_chat.py @@ -27,8 +27,9 @@ class GetChat(BaseClient): def get_chat( self, chat_id: Union[int, str] - ) -> "pyrogram.Chat": - """Get up to date information about the chat. + ) -> Union["pyrogram.Chat", "pyrogram.ChatPreview"]: + """Get up to date information about a chat. + Information include current name of the user for one-on-one conversations, current username of a user, group or channel, etc. @@ -39,7 +40,8 @@ class GetChat(BaseClient): of the target channel/supergroup (in the format @username). Returns: - :obj:`Chat`: On success, a chat object is returned. + :obj:`Chat` | :obj:`ChatPreview`: On success, if you've already joined the chat, a chat object is returned, + otherwise, a chat preview object is returned. Raises: RPCError: In case of a Telegram RPC error. @@ -48,16 +50,14 @@ class GetChat(BaseClient): match = self.INVITE_LINK_RE.match(str(chat_id)) if match: - h = match.group(1) - r = self.send( functions.messages.CheckChatInvite( - hash=h + hash=match.group(1) ) ) if isinstance(r, types.ChatInvite): - raise ValueError("You haven't joined \"t.me/joinchat/{}\" yet".format(h)) + return pyrogram.ChatPreview._parse(self, r) self.fetch_peers([r.chat]) diff --git a/pyrogram/client/methods/chats/get_chat_preview.py b/pyrogram/client/methods/chats/get_chat_preview.py deleted file mode 100644 index 8551aaf4..00000000 --- a/pyrogram/client/methods/chats/get_chat_preview.py +++ /dev/null @@ -1,67 +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 . - -import pyrogram -from pyrogram.api import functions, types -from ...ext import BaseClient - - -class GetChatPreview(BaseClient): - def get_chat_preview( - self, - invite_link: str - ): - """Get the preview of a chat using the invite link. - - This method only returns a chat preview, if you want to join a chat use :meth:`join_chat` - - Parameters: - invite_link (``str``): - Unique identifier for the target chat in form of *t.me/joinchat/* links. - - Returns: - :obj:`Chat`: In case you already joined the chat. - - :obj:`ChatPreview` -- In case you haven't joined the chat yet. - - Raises: - RPCError: In case of a Telegram RPC error. - ValueError: In case of an invalid invite link. - """ - match = self.INVITE_LINK_RE.match(invite_link) - - if match: - r = self.send( - functions.messages.CheckChatInvite( - hash=match.group(1) - ) - ) - - if isinstance(r, types.ChatInvite): - return pyrogram.ChatPreview._parse(self, r) - - if isinstance(r, types.ChatInviteAlready): - chat = r.chat - - if isinstance(chat, types.Chat): - return pyrogram.Chat._parse_chat_chat(self, chat) - - if isinstance(chat, types.Channel): - return pyrogram.Chat._parse_channel_chat(self, chat) - else: - raise ValueError("The invite_link is invalid") diff --git a/pyrogram/client/types/user_and_chats/chat_preview.py b/pyrogram/client/types/user_and_chats/chat_preview.py index 0366d04f..38dda6b6 100644 --- a/pyrogram/client/types/user_and_chats/chat_preview.py +++ b/pyrogram/client/types/user_and_chats/chat_preview.py @@ -32,7 +32,7 @@ class ChatPreview(PyrogramType): title (``str``): Title of the chat. - photo (:obj:`ChatPhoto`): + photo (:obj:`ChatPhoto`, *optional*): Chat photo. Suitable for downloads only. type (``str``): @@ -52,7 +52,7 @@ class ChatPreview(PyrogramType): *, client: "pyrogram.BaseClient" = None, title: str, - photo: ChatPhoto, + photo: ChatPhoto = None, type: str, members_count: int, members: List[User] = None From ddef2032e299173c7545ac5c1fc59dc8a9499a51 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 17 May 2019 13:21:51 +0200 Subject: [PATCH 067/202] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 35c80f37..4d202b4f 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Releases • - + Community
@@ -58,8 +58,7 @@ ground up in Python and C. It enables you to easily create custom apps for both written in pure C. - **Documented**: Pyrogram API methods, types and public interfaces are well documented. - **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. -- **Updated**, to the latest Telegram API version, currently Layer 97 on top of - [MTProto 2.0](https://core.telegram.org/mtproto). +- **Updated**, to make use of the latest Telegram API version and features. - **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code. - **Comprehensive**: Execute any advanced action an official client is able to do, and even more. From 23d0ef3cf94b78041141e6efb0129f23082dd4fd Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 17 May 2019 13:23:03 +0200 Subject: [PATCH 068/202] Use "bot" as chat type for bots. We now have "private", "bot", "group", "supergroups" and "channel" chat types. --- pyrogram/client/types/user_and_chats/chat.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 8793942c..e45814ea 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -33,33 +33,33 @@ class Chat(PyrogramType): Unique identifier for this chat. type (``str``): - Type of chat, can be either "private", "group", "supergroup" or "channel". + Type of chat, can be either "private", "bot", "group", "supergroup" or "channel". title (``str``, *optional*): Title, for supergroups, channels and basic group chats. username (``str``, *optional*): - Username, for private chats, supergroups and channels if available. + Username, for private chats, bots, supergroups and channels if available. first_name (``str``, *optional*): - First name of the other party in a private chat. + First name of the other party in a private chat, for private chats and bots. last_name (``str``, *optional*): - Last name of the other party in a private chat. + Last name of the other party in a private chat, for private chats. photo (:obj:`ChatPhoto `, *optional*): Chat photo. Suitable for downloads only. description (``str``, *optional*): - Description, for supergroups and channel chats. + Bio, for private chats and bots or description for groups, supergroups and channels. Returned only in :meth:`get_chat() `. invite_link (``str``, *optional*): - Chat invite link, for supergroups and channel chats. + Chat invite link, for groups, supergroups and channels. Returned only in :meth:`get_chat() `. pinned_message (:obj:`Message`, *optional*): - Pinned message, for supergroups and channel chats. + Pinned message, for groups, supergroups channels and own chat. Returned only in :meth:`get_chat() `. sticker_set_name (``str``, *optional*): @@ -71,13 +71,13 @@ class Chat(PyrogramType): Returned only in :meth:`get_chat() `. members_count (``int``, *optional*): - Chat members count, for groups and channels only. + Chat members count, for groups, supergroups and channels only. restriction_reason (``str``, *optional*): The reason why this chat might be unavailable to some users. permissions (:obj:`ChatPermissions ` *optional*): - Information about the chat default permissions. + Information about the chat default permissions, for groups and supergroups. """ __slots__ = [ @@ -128,7 +128,7 @@ class Chat(PyrogramType): def _parse_user_chat(client, user: types.User) -> "Chat": return Chat( id=user.id, - type="private", + type="bot" if user.bot else "private", username=user.username, first_name=user.first_name, last_name=user.last_name, From b6ea451ee5db710fdf562c18cba11c37f1f67b7a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 17 May 2019 13:44:44 +0200 Subject: [PATCH 069/202] Reword some method return type docstrings --- docs/source/api/handlers.rst | 16 ---------------- docs/source/api/methods.rst | 2 -- docs/source/api/types.rst | 2 ++ docs/source/index.rst | 2 +- docs/source/intro/start.rst | 2 +- docs/source/topics/advanced-usage.rst | 2 +- .../client/methods/bots/answer_inline_query.py | 2 +- .../methods/bots/send_inline_bot_result.py | 2 +- pyrogram/client/methods/bots/set_game_score.py | 6 +++--- .../methods/chats/get_chat_members_count.py | 2 +- .../client/methods/chats/get_dialogs_count.py | 2 +- .../client/methods/chats/kick_chat_member.py | 5 ++--- pyrogram/client/methods/contacts/get_contacts.py | 1 + .../methods/contacts/get_contacts_count.py | 2 +- .../client/methods/messages/download_media.py | 5 ++--- .../messages/edit_message_reply_markup.py | 5 ++--- .../client/methods/messages/forward_messages.py | 8 +++----- .../client/methods/messages/get_history_count.py | 2 +- pyrogram/client/methods/messages/get_messages.py | 8 +++----- .../client/methods/messages/send_animation.py | 5 ++--- pyrogram/client/methods/messages/send_audio.py | 5 ++--- .../client/methods/messages/send_document.py | 5 ++--- pyrogram/client/methods/messages/send_photo.py | 5 ++--- pyrogram/client/methods/messages/send_sticker.py | 6 ++---- pyrogram/client/methods/messages/send_video.py | 5 ++--- .../client/methods/messages/send_video_note.py | 5 ++--- pyrogram/client/methods/messages/send_voice.py | 5 ++--- .../users/get_user_profile_photos_count.py | 2 +- pyrogram/client/methods/users/get_users.py | 7 ++++--- 29 files changed, 48 insertions(+), 78 deletions(-) diff --git a/docs/source/api/handlers.rst b/docs/source/api/handlers.rst index 023f6e28..5f80922d 100644 --- a/docs/source/api/handlers.rst +++ b/docs/source/api/handlers.rst @@ -38,26 +38,10 @@ it. RawUpdateHandler .. autoclass:: MessageHandler() - :members: - .. autoclass:: DeletedMessagesHandler() - :members: - .. autoclass:: CallbackQueryHandler() - :members: - .. autoclass:: InlineQueryHandler() - :members: - .. autoclass:: UserStatusHandler() - :members: - .. autoclass:: PollHandler() - :members: - .. autoclass:: DisconnectHandler() - :members: - .. autoclass:: RawUpdateHandler() - :members: - diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index ded4d017..7c061d3a 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -90,7 +90,6 @@ Chats pin_chat_message unpin_chat_message get_chat - get_chat_preview get_chat_member get_chat_members get_chat_members_count @@ -217,7 +216,6 @@ Bots .. automethod:: pyrogram.Client.pin_chat_message() .. automethod:: pyrogram.Client.unpin_chat_message() .. automethod:: pyrogram.Client.get_chat() -.. automethod:: pyrogram.Client.get_chat_preview() .. automethod:: pyrogram.Client.get_chat_member() .. automethod:: pyrogram.Client.get_chat_members() .. automethod:: pyrogram.Client.get_chat_members_count() diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 506fe003..d911520c 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -72,6 +72,7 @@ Keyboards ForceReply CallbackQuery GameHighScore + GameHighScores CallbackGame Input Media @@ -155,6 +156,7 @@ InputMessageContent .. autoclass:: ForceReply() .. autoclass:: CallbackQuery() .. autoclass:: GameHighScore() +.. autoclass:: GameHighScores() .. autoclass:: CallbackGame() .. Input Media diff --git a/docs/source/index.rst b/docs/source/index.rst index 9b878baf..d061b677 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -17,7 +17,7 @@ Welcome to Pyrogram GitHub • - + Community diff --git a/docs/source/intro/start.rst b/docs/source/intro/start.rst index 2fcd4633..c7bfc74a 100644 --- a/docs/source/intro/start.rst +++ b/docs/source/intro/start.rst @@ -44,5 +44,5 @@ In the next few pages of the introduction, we'll take a much more in-depth look Feeling eager to continue? You can take a shortcut to `Calling Methods`_ and come back later to learn some more details. -.. _community: //t.me/pyrogramchat +.. _community: //t.me/Pyrogram .. _Calling Methods: ../start/invoking \ No newline at end of file diff --git a/docs/source/topics/advanced-usage.rst b/docs/source/topics/advanced-usage.rst index 02a3e3b6..4032783f 100644 --- a/docs/source/topics/advanced-usage.rst +++ b/docs/source/topics/advanced-usage.rst @@ -130,4 +130,4 @@ high-level method. .. _plenty of them: ../api/methods .. _raw functions: ../telegram/functions .. _raw types: ../telegram/types -.. _Community: https://t.me/PyrogramChat \ No newline at end of file +.. _Community: https://t.me/Pyrogram \ No newline at end of file diff --git a/pyrogram/client/methods/bots/answer_inline_query.py b/pyrogram/client/methods/bots/answer_inline_query.py index 62344f20..38ed99c3 100644 --- a/pyrogram/client/methods/bots/answer_inline_query.py +++ b/pyrogram/client/methods/bots/answer_inline_query.py @@ -73,7 +73,7 @@ class AnswerInlineQuery(BaseClient): where they wanted to use the bot's inline capabilities. Returns: - ``bool``: On success, True is returned. + ``bool``: True, on success. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/bots/send_inline_bot_result.py b/pyrogram/client/methods/bots/send_inline_bot_result.py index 031591db..411ab462 100644 --- a/pyrogram/client/methods/bots/send_inline_bot_result.py +++ b/pyrogram/client/methods/bots/send_inline_bot_result.py @@ -58,7 +58,7 @@ class SendInlineBotResult(BaseClient): Sends the message with *via @bot* hidden. Returns: - On success, the sent Message is returned. + :obj:`Message`: On success, the sent inline result message is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/bots/set_game_score.py b/pyrogram/client/methods/bots/set_game_score.py index 3b0e97e2..f9115b74 100644 --- a/pyrogram/client/methods/bots/set_game_score.py +++ b/pyrogram/client/methods/bots/set_game_score.py @@ -32,7 +32,7 @@ class SetGameScore(BaseClient): disable_edit_message: bool = None, chat_id: Union[int, str] = None, message_id: int = None - ): + ) -> Union["pyrogram.Message", bool]: # inline_message_id: str = None): TODO Add inline_message_id """Set the score of the specified user in a game. @@ -63,8 +63,8 @@ class SetGameScore(BaseClient): Required if inline_message_id is not specified. Returns: - On success, if the message was sent by the bot, returns the edited :obj:`Message`, - otherwise returns True. + :obj:`Message` | ``bool``: On success, if the message was sent by the bot, the edited message is returned, + True otherwise. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/chats/get_chat_members_count.py b/pyrogram/client/methods/chats/get_chat_members_count.py index c8bd6deb..4c7ab747 100644 --- a/pyrogram/client/methods/chats/get_chat_members_count.py +++ b/pyrogram/client/methods/chats/get_chat_members_count.py @@ -34,7 +34,7 @@ class GetChatMembersCount(BaseClient): Unique identifier (int) or username (str) of the target chat. Returns: - On success, an integer is returned. + ``int``: On success, the chat members count is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/chats/get_dialogs_count.py b/pyrogram/client/methods/chats/get_dialogs_count.py index 1a307433..b9b0970a 100644 --- a/pyrogram/client/methods/chats/get_dialogs_count.py +++ b/pyrogram/client/methods/chats/get_dialogs_count.py @@ -29,7 +29,7 @@ class GetDialogsCount(BaseClient): Defaults to False. Returns: - ``int``: On success, an integer is returned. + ``int``: On success, the dialogs count is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/chats/kick_chat_member.py b/pyrogram/client/methods/chats/kick_chat_member.py index f5058829..9686e754 100644 --- a/pyrogram/client/methods/chats/kick_chat_member.py +++ b/pyrogram/client/methods/chats/kick_chat_member.py @@ -54,9 +54,8 @@ class KickChatMember(BaseClient): considered to be banned forever. Defaults to 0 (ban forever). Returns: - :obj:`Message`: On success, a service message will be returned (when applicable). - - ``bool`` -- True, in case a message object couldn't be returned. + :obj:`Message` | ``bool``: On success, a service message will be returned (when applicable), otherwise, in + case a message object couldn't be returned, True is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/contacts/get_contacts.py b/pyrogram/client/methods/contacts/get_contacts.py index 1fa5b738..0c231670 100644 --- a/pyrogram/client/methods/contacts/get_contacts.py +++ b/pyrogram/client/methods/contacts/get_contacts.py @@ -30,6 +30,7 @@ log = logging.getLogger(__name__) class GetContacts(BaseClient): def get_contacts(self) -> List["pyrogram.User"]: + # TODO: Create a Users object and return that """Get contacts from your Telegram address book. Returns: diff --git a/pyrogram/client/methods/contacts/get_contacts_count.py b/pyrogram/client/methods/contacts/get_contacts_count.py index 01fb0789..dddfe8c4 100644 --- a/pyrogram/client/methods/contacts/get_contacts_count.py +++ b/pyrogram/client/methods/contacts/get_contacts_count.py @@ -25,7 +25,7 @@ class GetContactsCount(BaseClient): """Get the total count of contacts from your Telegram address book. Returns: - ``int``: On success, an integer is returned. + ``int``: On success, the contacts count is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index 5c440173..c21a95bf 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -73,9 +73,8 @@ class DownloadMedia(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - ``str``: On success, the absolute path of the downloaded file is returned. - - ``None`` -- In case the download is deliberately stopped with :meth:`stop_transmission`. + ``str`` | ``None``: On success, the absolute path of the downloaded file is returned, otherwise, in case + the download failed or was deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/edit_message_reply_markup.py b/pyrogram/client/methods/messages/edit_message_reply_markup.py index 8d2b82af..a058646f 100644 --- a/pyrogram/client/methods/messages/edit_message_reply_markup.py +++ b/pyrogram/client/methods/messages/edit_message_reply_markup.py @@ -45,9 +45,8 @@ class EditMessageReplyMarkup(BaseClient): An InlineKeyboardMarkup object. Returns: - :obj:`Message`: In case the edited message is sent by the bot. - - ``bool`` -- True, in case the edited message is sent by the user. + :obj:`Message` | ``bool``: In case the edited message is sent by the bot, the edited message is returned, + otherwise, True is returned in case the edited message is send by the user. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/forward_messages.py b/pyrogram/client/methods/messages/forward_messages.py index 82c35f92..bc9ad331 100644 --- a/pyrogram/client/methods/messages/forward_messages.py +++ b/pyrogram/client/methods/messages/forward_messages.py @@ -64,11 +64,9 @@ class ForwardMessages(BaseClient): Defaults to False. Returns: - :obj:`Message`: In case *message_ids* was an integer, the single forwarded message is - returned. - - :obj:`Messages` -- In case *message_ids* was an iterable, the returned value will be an - object containing a list of messages, even if such iterable contained just a single element. + :obj:`Message` | :obj:`Messages`: In case *message_ids* was an integer, the single forwarded message is + returned, otherwise, in case *message_ids* was an iterable, the returned value will be an object containing + a list of messages, even if such iterable contained just a single element. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/get_history_count.py b/pyrogram/client/methods/messages/get_history_count.py index ced46799..48614030 100644 --- a/pyrogram/client/methods/messages/get_history_count.py +++ b/pyrogram/client/methods/messages/get_history_count.py @@ -45,7 +45,7 @@ class GetHistoryCount(BaseClient): Unique identifier (int) or username (str) of the target chat. Returns: - ``int``: On success, an integer is returned. + ``int``: On success, the chat history count is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/get_messages.py b/pyrogram/client/methods/messages/get_messages.py index 51f71352..7a60f276 100644 --- a/pyrogram/client/methods/messages/get_messages.py +++ b/pyrogram/client/methods/messages/get_messages.py @@ -60,11 +60,9 @@ class GetMessages(BaseClient): Defaults to 1. Returns: - :obj:`Message`: In case *message_ids* was an integer, the single forwarded message is - returned. - - :obj:`Messages` -- In case *message_ids* was an iterable, the returned value will be an - object containing a list of messages, even if such iterable contained just a single element. + :obj:`Message` | :obj:`Messages`: In case *message_ids* was an integer, the single requested message is + returned, otherwise, in case *message_ids* was an iterable, the returned value will be an object containing + a list of messages, even if such iterable contained just a single element. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_animation.py b/pyrogram/client/methods/messages/send_animation.py index 461ef6fc..edf5ea54 100644 --- a/pyrogram/client/methods/messages/send_animation.py +++ b/pyrogram/client/methods/messages/send_animation.py @@ -120,9 +120,8 @@ class SendAnimation(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent animation message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. + :obj:`Message` | ``None``: On success, the sent animation message is returned, otherwise, in case the upload + is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_audio.py b/pyrogram/client/methods/messages/send_audio.py index aaa5a529..b6d7b777 100644 --- a/pyrogram/client/methods/messages/send_audio.py +++ b/pyrogram/client/methods/messages/send_audio.py @@ -122,9 +122,8 @@ class SendAudio(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent audio message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. + :obj:`Message` | ``None``: On success, the sent audio message is returned, otherwise, in case the upload + is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index 66b3f1c9..df202fd7 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -108,9 +108,8 @@ class SendDocument(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent document message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. + :obj:`Message` | ``None``: On success, the sent document message is returned, otherwise, in case the upload + is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_photo.py b/pyrogram/client/methods/messages/send_photo.py index 7c4f688f..14292da9 100644 --- a/pyrogram/client/methods/messages/send_photo.py +++ b/pyrogram/client/methods/messages/send_photo.py @@ -107,9 +107,8 @@ class SendPhoto(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent photo message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. + :obj:`Message` | ``None``: On success, the sent photo message is returned, otherwise, in case the upload + is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_sticker.py b/pyrogram/client/methods/messages/send_sticker.py index cabe3487..4a03e4c8 100644 --- a/pyrogram/client/methods/messages/send_sticker.py +++ b/pyrogram/client/methods/messages/send_sticker.py @@ -92,10 +92,8 @@ class SendSticker(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent sticker message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. - + :obj:`Message` | ``None``: On success, the sent sticker message is returned, otherwise, in case the upload + is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. """ diff --git a/pyrogram/client/methods/messages/send_video.py b/pyrogram/client/methods/messages/send_video.py index 92066e19..d2d5afc0 100644 --- a/pyrogram/client/methods/messages/send_video.py +++ b/pyrogram/client/methods/messages/send_video.py @@ -124,9 +124,8 @@ class SendVideo(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent video message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. + :obj:`Message` | ``None``: On success, the sent video message is returned, otherwise, in case the upload + is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_video_note.py b/pyrogram/client/methods/messages/send_video_note.py index 8886c588..c17ea92a 100644 --- a/pyrogram/client/methods/messages/send_video_note.py +++ b/pyrogram/client/methods/messages/send_video_note.py @@ -107,9 +107,8 @@ class SendVideoNote(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent video note message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. + :obj:`Message` | ``None``: On success, the sent video note message is returned, otherwise, in case the + pload is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_voice.py b/pyrogram/client/methods/messages/send_voice.py index 3631d828..59031f5f 100644 --- a/pyrogram/client/methods/messages/send_voice.py +++ b/pyrogram/client/methods/messages/send_voice.py @@ -105,9 +105,8 @@ class SendVoice(BaseClient): You can either keep *\*args* or add every single extra argument in your function signature. Returns: - :obj:`Message`: On success, the sent voice message is returned. - - ``None`` -- In case the upload is deliberately stopped with :meth:`stop_transmission`. + :obj:`Message` | ``None``: On success, the sent voice message is returned, otherwise, in case the upload + is deliberately stopped with :meth:`stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/users/get_user_profile_photos_count.py b/pyrogram/client/methods/users/get_user_profile_photos_count.py index f5526584..7870d003 100644 --- a/pyrogram/client/methods/users/get_user_profile_photos_count.py +++ b/pyrogram/client/methods/users/get_user_profile_photos_count.py @@ -33,7 +33,7 @@ class GetUserProfilePhotosCount(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). Returns: - ``int``: On success, an integer is returned. + ``int``: On success, the user profile photos count is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/users/get_users.py b/pyrogram/client/methods/users/get_users.py index e95fedc7..4ec0e893 100644 --- a/pyrogram/client/methods/users/get_users.py +++ b/pyrogram/client/methods/users/get_users.py @@ -24,6 +24,7 @@ from ...ext import BaseClient class GetUsers(BaseClient): + # TODO: Add Users type and use that def get_users( self, user_ids: Union[Iterable[Union[int, str]], int, str] @@ -38,9 +39,9 @@ class GetUsers(BaseClient): Iterators and Generators are also accepted. Returns: - :obj:`User`: In case *user_ids* was an integer or string. - - List of :obj:`User` -- In case *user_ids* was an iterable, even if the iterable contained one item only. + :obj:`User` | List of :obj:`User`: In case *user_ids* was an integer or string the single requested user is + returned, otherwise, in case *user_ids* was an iterable a list of users is returned, even if the iterable + contained one item only. Raises: RPCError: In case of a Telegram RPC error. From 518220431ecf25ee987bee30f5bff78aa7045510 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 18 May 2019 01:45:01 +0200 Subject: [PATCH 070/202] Docs revamp. Part 5 --- README.md | 1 + docs/source/index.rst | 33 ++++------- docs/source/intro/auth.rst | 4 +- docs/source/intro/install.rst | 4 +- docs/source/intro/start.rst | 3 +- docs/source/start/errors.rst | 33 ++++++++++- docs/source/start/invoking.rst | 2 +- docs/source/start/updates.rst | 12 ++-- docs/source/topics/faq.rst | 79 +++++++++++++++++++------ docs/source/topics/glossary.rst | 23 ++++++- docs/source/topics/session-settings.rst | 10 ++-- pyrogram/__init__.py | 4 +- pyrogram/client/client.py | 2 +- pyrogram/client/ext/base_client.py | 2 +- 14 files changed, 144 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 4d202b4f..6e12bce0 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ ground up in Python and C. It enables you to easily create custom apps for both - **Documented**: Pyrogram API methods, types and public interfaces are well documented. - **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. - **Updated**, to make use of the latest Telegram API version and features. +- **Bot API-like**: Similar to the Bot API in its simplicity, but much more powerful and detailed. - **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code. - **Comprehensive**: Execute any advanced action an official client is able to do, and even more. diff --git a/docs/source/index.rst b/docs/source/index.rst index d061b677..a68c81d9 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -14,29 +14,15 @@ Welcome to Pyrogram
- GitHub + Source Code - • - - Community - - • Releases • - - PyPI - -
- - Schema Layer - - - TgCrypto Version + + Community

@@ -59,7 +45,7 @@ C. It enables you to easily create custom apps for both user and bot identities `MTProto API`_. .. _Telegram: https://telegram.org -.. _MTProto API: https://core.telegram.org/api#telegram-api +.. _MTProto API: topics/faq#what-can-mtproto-do-more-than-the-bot-api How the Documentation is Organized ---------------------------------- @@ -68,11 +54,11 @@ Contents are organized into self-contained topics and can be all accessed from t order using the Next button at the end of each page. Here below you can, instead, find a list of the most relevant pages for a quick access. -Getting Started -^^^^^^^^^^^^^^^ +First Steps +^^^^^^^^^^^ -- `Quick Start`_ - Overview to get you started as fast as possible. -- `Calling Methods`_ - How to use Pyrogram's API. +- `Quick Start`_ - Overview to get you started quickly. +- `Calling Methods`_ - How to call Pyrogram's methods. - `Handling Updates`_ - How to handle Telegram updates. - `Error Handling`_ - How to handle API errors correctly. @@ -83,7 +69,8 @@ Getting Started API Reference ^^^^^^^^^^^^^ -- `Client Class`_ - Details about the Client class. + +- `Client Class`_ - Reference details about the Client class. - `Available Methods`_ - A list of available high-level methods. - `Available Types`_ - A list of available high-level types. - `Bound Methods`_ - A list of convenient bound methods. diff --git a/docs/source/intro/auth.rst b/docs/source/intro/auth.rst index 846a19a1..483d1202 100644 --- a/docs/source/intro/auth.rst +++ b/docs/source/intro/auth.rst @@ -2,7 +2,7 @@ Authorization ============= Once a `project is set up`_, you will still have to follow a few steps before you can actually use Pyrogram to make -API calls. This section provides all the information you need in order to authorize yourself as user or a bot. +API calls. This section provides all the information you need in order to authorize yourself as user or bot. User Authorization ------------------ @@ -51,7 +51,7 @@ the `Bot Father`_. Bot tokens replace the users' phone numbers only — you stil The authorization process is automatically managed. All you need to do is choose a ``session_name`` (can be anything, usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named -after the session name, which will be ``pyrogrambot.session`` for the example below. +after the session name, which will be ``my_bot.session`` for the example below. .. code-block:: python diff --git a/docs/source/intro/install.rst b/docs/source/intro/install.rst index c4df60d4..f26fc37f 100644 --- a/docs/source/intro/install.rst +++ b/docs/source/intro/install.rst @@ -55,7 +55,7 @@ Use this command to install (note "asyncio.zip" in the link): $ pip3 install -U https://github.com/pyrogram/pyrogram/archive/asyncio.zip -Pyrogram API remains the same and features are kept up to date from the non-async, default develop branch, but you +Pyrogram's API remains the same and features are kept up to date from the non-async, default develop branch, but you are obviously required Python asyncio knowledge in order to take full advantage of it. @@ -87,7 +87,7 @@ If no error shows up you are good to go. >>> import pyrogram >>> pyrogram.__version__ - '0.12.0' + '0.13.0' .. _TgCrypto: ../topics/tgcrypto .. _`Github repo`: http://github.com/pyrogram/pyrogram diff --git a/docs/source/intro/start.rst b/docs/source/intro/start.rst index c7bfc74a..1aa7989e 100644 --- a/docs/source/intro/start.rst +++ b/docs/source/intro/start.rst @@ -1,7 +1,8 @@ Quick Start =========== -The next few steps serve as a quick start for all new Pyrogrammers that want to get something done as fast as possible! +The next few steps serve as a quick start for all new Pyrogrammers that want to get something done as fast as possible. +Let's go! Get Pyrogram Real Fast ---------------------- diff --git a/docs/source/start/errors.rst b/docs/source/start/errors.rst index 1f4f5a2e..cf329947 100644 --- a/docs/source/start/errors.rst +++ b/docs/source/start/errors.rst @@ -11,8 +11,9 @@ to control the behaviour of your application. Pyrogram errors all live inside th RPCError -------- -The father of all errors is named ``RPCError``. This error exists in form of a Python exception and is able to catch all -Telegram API related errors. +The father of all errors is named ``RPCError``. This error exists in form of a Python exception which is directly +subclass-ed from Python's main ``Exception`` and is able to catch all Telegram API related errors. This error is raised +every time a method call against Telegram's API was unsuccessful. .. code-block:: python @@ -27,7 +28,7 @@ Error Categories ---------------- The ``RPCError`` packs together all the possible errors Telegram could raise, but to make things tidier, Pyrogram -provides categories of errors, which are named after the common HTTP errors: +provides categories of errors, which are named after the common HTTP errors and subclass-ed from the RPCError: .. code-block:: python @@ -41,6 +42,32 @@ provides categories of errors, which are named after the common HTTP errors: - `420 - Flood <../api/errors#flood>`_ - `500 - InternalServerError <../api/errors#internalservererror>`_ +Single Errors +------------- + +For a fine-grained control over every single error, Pyrogram does also expose errors that deal each with a specific +issue. For example: + +.. code-block:: python + + from pyrogram.errors import FloodWait + +These errors subclass directly from the category of errors they belong to, which in turn subclass from the father +RPCError, thus building a class of error hierarchy such as this: + +- RPCError + - BadRequest + - ``MessageEmpty`` + - ``UsernameOccupied`` + - ``...`` + - InternalServerError + - ``RpcCallFail`` + - ``InterDcCallError`` + - ``...`` + - ``...`` + +.. _Errors: api/errors + Unknown Errors -------------- diff --git a/docs/source/start/invoking.rst b/docs/source/start/invoking.rst index fae19523..ef9bc373 100644 --- a/docs/source/start/invoking.rst +++ b/docs/source/start/invoking.rst @@ -36,7 +36,7 @@ Now instantiate a new Client object, "my_account" is a session name of your choi app = Client("my_account") -To actually make use of any method, the client has to be started: +To actually make use of any method, the client has to be started first: .. code-block:: python diff --git a/docs/source/start/updates.rst b/docs/source/start/updates.rst index 930096a3..644cf31c 100644 --- a/docs/source/start/updates.rst +++ b/docs/source/start/updates.rst @@ -9,11 +9,11 @@ Defining Updates First, let's define what are these updates. As hinted already, updates are simply events that happen in your Telegram account (incoming messages, new members join, bot button presses, etc...), which are meant to notify you about a new -specific state that changed. These updates are handled by registering one or more callback functions in your app using -`Handlers <../api/handlers>`_. +specific state that has changed. These updates are handled by registering one or more callback functions in your app +using `Handlers <../api/handlers>`_. Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback -function will be called and its body executed. +function will be called back by the framework and its body executed. Registering an Handler ---------------------- @@ -63,8 +63,8 @@ above must only handle updates that are in form of a :obj:`Message `. This method is used to actually register the -handler and let Pyrogram know it needs to be taken into consideration when new updates arrive and the dispatching phase -begins. +handler and let Pyrogram know it needs to be taken into consideration when new updates arrive and the internal +dispatching phase begins. .. code-block:: python @@ -109,4 +109,4 @@ to do so is by decorating your callback function with the :meth:`on_message() @@ -45,7 +45,7 @@ C. It enables you to easily create custom apps for both user and bot identities `MTProto API`_. .. _Telegram: https://telegram.org -.. _MTProto API: topics/faq#what-can-mtproto-do-more-than-the-bot-api +.. _MTProto API: topics/mtproto-vs-botapi#what-is-the-mtproto-api How the Documentation is Organized ---------------------------------- @@ -62,7 +62,7 @@ First Steps - `Handling Updates`_ - How to handle Telegram updates. - `Error Handling`_ - How to handle API errors correctly. -.. _Quick Start: intro/start +.. _Quick Start: intro/quickstart .. _Calling Methods: start/invoking .. _Handling Updates: start/updates .. _Error Handling: start/errors @@ -80,26 +80,26 @@ API Reference .. _Available Types: api/types .. _Bound Methods: api/bound-methods -Relevant Topics -^^^^^^^^^^^^^^^ +Meta +^^^^ -- `Smart Plugins`_ - How to modularize your application. -- `Advanced Usage`_ - How to use Telegram's raw API. -- `Release Notes`_ - Release notes for Pyrogram releases. - `Pyrogram FAQ`_ - Answers to common Pyrogram questions. - `Pyrogram Glossary`_ - A list of words with brief explanations. +- `Release Notes`_ - Release notes for Pyrogram releases. +- `Powered by Pyrogram`_ - A collection of Pyrogram Projects. +- `Support Pyrogram Development`_ - Ways to show your appreciation. -.. _Smart Plugins: topics/smart-plugins -.. _Advanced Usage: topics/advanced-usage -.. _Release Notes: topics/releases -.. _Pyrogram FAQ: topics/faq -.. _Pyrogram Glossary: topics/glossary +.. _Pyrogram FAQ: meta/faq +.. _Pyrogram Glossary: meta/glossary +.. _Release Notes: meta/releases +.. _Powered by Pyrogram: meta/powered-by +.. _Support Pyrogram Development: meta/support-pyrogram .. toctree:: :hidden: :caption: Introduction - intro/start + intro/quickstart intro/install intro/setup @@ -107,7 +107,7 @@ Relevant Topics :hidden: :caption: Getting Started - intro/auth + start/auth start/invoking start/updates start/errors @@ -139,12 +139,20 @@ Relevant Topics topics/text-formatting topics/proxy topics/bots-interaction + topics/mtproto-vs-botapi topics/test-servers topics/advanced-usage topics/voice-calls - topics/releases - topics/faq - topics/glossary + +.. toctree:: + :hidden: + :caption: Meta + + meta/faq + meta/glossary + meta/releases + meta/powered-by + meta/support-pyrogram .. toctree:: :hidden: diff --git a/docs/source/sitemap.py b/docs/source/sitemap.py index 539bac0d..b4d24c6a 100644 --- a/docs/source/sitemap.py +++ b/docs/source/sitemap.py @@ -20,7 +20,7 @@ import datetime import os import re -canonical = "https://docs.pyrogram.ml" +canonical = "https://docs.pyrogram.org/" dirs = { "start": ("weekly", 0.9), diff --git a/docs/source/topics/text-formatting.rst b/docs/source/topics/text-formatting.rst index 535fec31..8f2292d0 100644 --- a/docs/source/topics/text-formatting.rst +++ b/docs/source/topics/text-formatting.rst @@ -20,7 +20,7 @@ To use this mode, pass "markdown" in the *parse_mode* field when using __italic text__ - [inline URL](https://docs.pyrogram.ml/) + [inline URL](https://docs.pyrogram.org/) [inline mention of a user](tg://user?id=23122162) @@ -43,7 +43,7 @@ The following tags are currently supported: italic, italic - inline URL + inline URL inline mention of a user @@ -66,7 +66,7 @@ Examples "**bold**, " "__italic__, " "[mention](tg://user?id=23122162), " - "[URL](https://docs.pyrogram.ml), " + "[URL](https://docs.pyrogram.org), " "`code`, " "```" "for i in range(10):\n" @@ -84,7 +84,7 @@ Examples "bold, " "italic, " "mention, " - "URL, " + "URL, " "code, " "
"
                 "for i in range(10):\n"
diff --git a/examples/bot_keyboards.py b/examples/bot_keyboards.py
index 4cbe8eaa..e1ff1e7e 100644
--- a/examples/bot_keyboards.py
+++ b/examples/bot_keyboards.py
@@ -39,7 +39,7 @@ with app:
                     ),
                     InlineKeyboardButton(  # Opens a web URL
                         "URL",
-                        url="https://docs.pyrogram.ml"
+                        url="https://docs.pyrogram.org"
                     ),
                 ],
                 [  # Second row
diff --git a/examples/inline_queries.py b/examples/inline_queries.py
index c1727fe6..d86d90d5 100644
--- a/examples/inline_queries.py
+++ b/examples/inline_queries.py
@@ -22,12 +22,12 @@ def answer(client, inline_query):
                 input_message_content=InputTextMessageContent(
                     "Here's how to install **Pyrogram**"
                 ),
-                url="https://docs.pyrogram.ml/start/Installation",
+                url="https://docs.pyrogram.org/intro/install",
                 description="How to install Pyrogram",
                 thumb_url="https://i.imgur.com/JyxrStE.png",
                 reply_markup=InlineKeyboardMarkup(
                     [
-                        [InlineKeyboardButton("Open website", url="https://docs.pyrogram.ml/start/Installation")]
+                        [InlineKeyboardButton("Open website", url="https://docs.pyrogram.org/intro/install")]
                     ]
                 )
             ),
@@ -37,12 +37,12 @@ def answer(client, inline_query):
                 input_message_content=InputTextMessageContent(
                     "Here's how to use **Pyrogram**"
                 ),
-                url="https://docs.pyrogram.ml/start/Usage",
+                url="https://docs.pyrogram.org/start/invoking",
                 description="How to use Pyrogram",
                 thumb_url="https://i.imgur.com/JyxrStE.png",
                 reply_markup=InlineKeyboardMarkup(
                     [
-                        [InlineKeyboardButton("Open website", url="https://docs.pyrogram.ml/start/Usage")]
+                        [InlineKeyboardButton("Open website", url="https://docs.pyrogram.org/start/invoking")]
                     ]
                 )
             )
diff --git a/examples/welcomebot.py b/examples/welcomebot.py
index ab252672..35f72aff 100644
--- a/examples/welcomebot.py
+++ b/examples/welcomebot.py
@@ -8,7 +8,7 @@ from pyrogram import Client, Emoji, Filters
 
 TARGET = "PyrogramChat"  # Target chat. Can also be a list of multiple chat ids/usernames
 MENTION = "[{}](tg://user?id={})"  # User mention markup
-MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.ml/)'s group chat {}!"  # Welcome message
+MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.org/)'s group chat {}!"  # Welcome message
 
 app = Client("my_account")
 
diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py
index 247a29cb..1cfa7c79 100644
--- a/pyrogram/client/client.py
+++ b/pyrogram/client/client.py
@@ -275,7 +275,7 @@ class Client(Methods, BaseClient):
             log.warning('\nWARNING: You are using a bot token as session name!\n'
                         'This usage will be deprecated soon. Please use a session file name to load '
                         'an existing session and the bot_token argument to create new sessions.\n'
-                        'More info: https://docs.pyrogram.ml/start/Setup#bot-authorization\n')
+                        'More info: https://docs.pyrogram.org/intro/auth#bot-authorization\n')
 
         self.load_config()
         self.load_session()
@@ -1091,7 +1091,7 @@ class Client(Methods, BaseClient):
             else:
                 raise AttributeError(
                     "No API Key found. "
-                    "More info: https://docs.pyrogram.ml/intro/setup#configuration"
+                    "More info: https://docs.pyrogram.org/intro/setup#configuration"
                 )
 
         for option in ["app_version", "device_model", "system_version", "lang_code"]:
diff --git a/pyrogram/crypto/aes.py b/pyrogram/crypto/aes.py
index de275bd0..d603caa0 100644
--- a/pyrogram/crypto/aes.py
+++ b/pyrogram/crypto/aes.py
@@ -56,7 +56,7 @@ except ImportError:
     log.warning(
         "TgCrypto is missing! "
         "Pyrogram will work the same, but at a much slower speed. "
-        "More info: https://docs.pyrogram.ml/resources/TgCrypto"
+        "More info: https://docs.pyrogram.org/topics/tgcrypto"
     )
 
 
diff --git a/setup.py b/setup.py
index 245655e6..f0d6d030 100644
--- a/setup.py
+++ b/setup.py
@@ -126,13 +126,13 @@ if len(argv) > 1 and argv[1] in ["bdist_wheel", "install", "develop"]:
 setup(
     name="Pyrogram",
     version=version,
-    description="Telegram MTProto API Client Library for Python",
+    description="Telegram MTProto API Client Library and Framework for Python",
     long_description=readme,
     long_description_content_type="text/markdown",
     url="https://github.com/pyrogram",
     download_url="https://github.com/pyrogram/pyrogram/releases/latest",
     author="Dan Tès",
-    author_email="admin@pyrogram.ml",
+    author_email="dan@pyrogram.org",
     license="LGPLv3+",
     classifiers=[
         "Development Status :: 4 - Beta",
@@ -162,7 +162,7 @@ setup(
         "Tracker": "https://github.com/pyrogram/pyrogram/issues",
         "Community": "https://t.me/PyrogramChat",
         "Source": "https://github.com/pyrogram/pyrogram",
-        "Documentation": "https://docs.pyrogram.ml",
+        "Documentation": "https://docs.pyrogram.org",
     },
     python_requires="~=3.4",
     packages=find_packages(exclude=["compiler*"]),

From a6b4a3fe4b0d68251f0bcd7dfaa0fbf824d2fbde Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Mon, 20 May 2019 17:59:04 +0200
Subject: [PATCH 074/202] Update email address

---
 .github/CODE_OF_CONDUCT.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
index 27bb02a3..c3b69284 100644
--- a/.github/CODE_OF_CONDUCT.md
+++ b/.github/CODE_OF_CONDUCT.md
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
 ## Enforcement
 
 Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at admin@pyrogram.ml. All
+reported by contacting the project team at dan@pyrogram.org. All
 complaints will be reviewed and investigated and will result in a response that
 is deemed necessary and appropriate to the circumstances. The project team is
 obligated to maintain confidentiality with regard to the reporter of an incident.

From 5975a410902ee440edb770ebbfd87005f5ecdd41 Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Mon, 20 May 2019 17:59:29 +0200
Subject: [PATCH 075/202] Bump pysocks version to 1.7.0

---
 requirements.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/requirements.txt b/requirements.txt
index 227aacf6..45525022 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,3 @@
 pyaes==1.6.1
-pysocks==1.6.8
+pysocks==1.7.0
 typing==3.6.6; python_version<"3.5"
\ No newline at end of file

From 8866a749e0fa764969a088260f7c0e906ddf7e84 Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Mon, 20 May 2019 19:19:26 +0200
Subject: [PATCH 076/202] Fix spelling: an handler -> a handler Thanks
 @rastamanjohn for the hint

---
 docs/source/api/handlers.rst  | 2 +-
 docs/source/start/updates.rst | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/source/api/handlers.rst b/docs/source/api/handlers.rst
index 5f80922d..90c8e614 100644
--- a/docs/source/api/handlers.rst
+++ b/docs/source/api/handlers.rst
@@ -4,7 +4,7 @@ Update Handlers
 Handlers are used to instruct Pyrogram about which kind of updates you'd like to handle with your callback functions.
 
 For a much more convenient way of registering callback functions have a look at `Decorators `_ instead.
-In case you decided to manually create an handler, use :meth:`add_handler() ` to register
+In case you decided to manually create a handler, use :meth:`add_handler() ` to register
 it.
 
 .. code-block:: python
diff --git a/docs/source/start/updates.rst b/docs/source/start/updates.rst
index 644cf31c..a0f2ca0c 100644
--- a/docs/source/start/updates.rst
+++ b/docs/source/start/updates.rst
@@ -15,8 +15,8 @@ using `Handlers <../api/handlers>`_.
 Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback
 function will be called back by the framework and its body executed.
 
-Registering an Handler
-----------------------
+Registering a Handler
+---------------------
 
 To explain how handlers work let's have a look at the most used one, the
 :obj:`MessageHandler `, which will be in charge for handling :obj:`Message `

From 79a8cefe5deae972ba086e9b29f50b4c925c779c Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Tue, 21 May 2019 14:25:13 +0200
Subject: [PATCH 077/202] Add USER_BANNED_IN_CHANNEL error

---
 compiler/error/source/400_BAD_REQUEST.tsv | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv
index db2f0e58..cbea977a 100644
--- a/compiler/error/source/400_BAD_REQUEST.tsv
+++ b/compiler/error/source/400_BAD_REQUEST.tsv
@@ -97,4 +97,5 @@ CHAT_NOT_MODIFIED	The chat settings were not modified
 RESULTS_TOO_MUCH	The result contains too many items
 RESULT_ID_DUPLICATE	The result contains items with duplicated identifiers
 ACCESS_TOKEN_INVALID	The bot access token is invalid
-INVITE_HASH_EXPIRED	The chat invite link is no longer valid
\ No newline at end of file
+INVITE_HASH_EXPIRED	The chat invite link is no longer valid
+USER_BANNED_IN_CHANNEL	You are limited, check @SpamBot for details
\ No newline at end of file

From 375aa85505a0c1bbc98b31bdc13bc2c722d9487d Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Wed, 22 May 2019 03:33:54 +0200
Subject: [PATCH 078/202] Update sitemap.py

---
 docs/{source => }/sitemap.py | 44 +++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 16 deletions(-)
 rename docs/{source => }/sitemap.py (64%)

diff --git a/docs/source/sitemap.py b/docs/sitemap.py
similarity index 64%
rename from docs/source/sitemap.py
rename to docs/sitemap.py
index b4d24c6a..87c27849 100644
--- a/docs/source/sitemap.py
+++ b/docs/sitemap.py
@@ -18,17 +18,16 @@
 
 import datetime
 import os
-import re
 
 canonical = "https://docs.pyrogram.org/"
 
 dirs = {
-    "start": ("weekly", 0.9),
-    "resources": ("weekly", 0.8),
-    "pyrogram": ("weekly", 0.8),
-    "functions": ("monthly", 0.7),
-    "types": ("monthly", 0.7),
-    "errors": ("weekly", 0.6)
+    ".": ("weekly", 1.0),
+    "intro": ("weekly", 0.8),
+    "start": ("weekly", 0.8),
+    "api": ("weekly", 0.6),
+    "topics": ("weekly", 0.6),
+    "telegram": ("weekly", 0.4)
 }
 
 
@@ -37,10 +36,10 @@ def now():
 
 
 with open("sitemap.xml", "w") as f:
-    f.write("\n")
-    f.write("\n")
+    f.write('\n')
+    f.write('\n')
 
-    urls = [(canonical, now(), "weekly", 1.0)]
+    urls = []
 
 
     def search(path):
@@ -48,14 +47,27 @@ with open("sitemap.xml", "w") as f:
             for j in os.listdir(path):
                 search("{}/{}".format(path, j))
         except NotADirectoryError:
-            d = path.split("/")[0]
-            path = "{}/{}".format(canonical, path.split(".")[0])
-            path = re.sub("^(.+)/index$", "\g<1>", path)
-            urls.append((path, now(), dirs[d][0], dirs[d][1]))
+            if not path.endswith(".rst"):
+                return
+
+            path = path.split("/")[1:]
+
+            if path[0].endswith(".rst"):
+                folder = "."
+            else:
+                folder = path[0]
+
+            path = "{}{}".format(canonical, "/".join(path))[:-len(".rst")]
+
+            if path.endswith("index"):
+                path = path[:-len("index")]
+
+            urls.append((path, now(), *dirs[folder]))
 
 
-    for i in dirs.keys():
-        search(i)
+    search("source")
+
+    urls.sort(key=lambda x: x[3], reverse=True)
 
     for i in urls:
         f.write("    \n")

From be612a498b834cbcc1762c4cbdbe43165dd3c794 Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Wed, 22 May 2019 03:34:13 +0200
Subject: [PATCH 079/202] Add robots.txt

---
 docs/robots.txt | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 docs/robots.txt

diff --git a/docs/robots.txt b/docs/robots.txt
new file mode 100644
index 00000000..0ecbac7b
--- /dev/null
+++ b/docs/robots.txt
@@ -0,0 +1,3 @@
+User-agent: *
+Allow: /
+Sitemap: https://docs.pyrogram.org/sitemap.xml
\ No newline at end of file

From 7f78a1a504d73ee5d4dd874e36ede0ca33557dbd Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Thu, 23 May 2019 08:34:33 +0200
Subject: [PATCH 080/202] Add MESSAGE_AUTHOR_REQUIRED error

---
 compiler/error/source/403_FORBIDDEN.tsv | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler/error/source/403_FORBIDDEN.tsv b/compiler/error/source/403_FORBIDDEN.tsv
index ddd8d26f..dd1e98fa 100644
--- a/compiler/error/source/403_FORBIDDEN.tsv
+++ b/compiler/error/source/403_FORBIDDEN.tsv
@@ -3,4 +3,5 @@ CHAT_WRITE_FORBIDDEN	You don't have rights to send messages in this chat
 RIGHT_FORBIDDEN	One or more admin rights can't be applied to this kind of chat (channel/supergroup)
 CHAT_ADMIN_INVITE_REQUIRED	You don't have rights to invite other users
 MESSAGE_DELETE_FORBIDDEN	You don't have rights to delete messages in this chat
-CHAT_SEND_MEDIA_FORBIDDEN	You can't send media messages in this chat
\ No newline at end of file
+CHAT_SEND_MEDIA_FORBIDDEN	You can't send media messages in this chat
+MESSAGE_AUTHOR_REQUIRED	You are not the author of this message
\ No newline at end of file

From d34daa9edcb5684e823a816c865ea290389bac38 Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Thu, 23 May 2019 18:57:59 +0200
Subject: [PATCH 081/202] Add pyrogram.png

---
 docs/source/_images/pyrogram.png | Bin 0 -> 48928 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 docs/source/_images/pyrogram.png

diff --git a/docs/source/_images/pyrogram.png b/docs/source/_images/pyrogram.png
new file mode 100644
index 0000000000000000000000000000000000000000..caadf9838f058c96fe1b584afa75a398f77f7a8a
GIT binary patch
literal 48928
zcmd42gjxX+Kn4GKi#{7
ze?p#P;(g=B!zv%0w_q&`FNXJSF18>?8wRlVdm9Fu4v$E=!zjboDg1Z${LLIxVH)M}!O0`CrAWs_{yAxC*rQdm%eDpjvjiOh9n7?XLtM7l
zdT;!#C|EYqH~jGA{EP;2v3hywDYe#PvC{t6)YSjo>R}ek>hi{|cK8TvXH~WlDKm8x
zh4w#gve;#{dxS<}P8FCthKr9be|+$Fo-%9LzwnZ7_+{oIeQ74%^{ew-`O(RnvR;?N
zVlurq3aM=mI^6qEBV^H>Jkm@ZFq316GtD+!)!4{%*9koDBaeLO7DVP$GymuW&;gs%
z&Nb6dfWJA#hP3?&@3=TKY;8S6?@!NFL@C$*MeBT=|0DY6wX@d1esy>GzJ|#5h{Ip4
zhIb4NGUN0h#;Al+teW7Kz_{9~ccb-->Xmr$9Z@6h5m7G57)N3@(~C6c?QgZRnz1k6
zaApi=I{-)Ad-f$%`s2O+^k*~~xC!{fJ9pGCGLfrM+aBvhOI-xGga1Utiw(Xot#&lu
ze}#Y`b+T|$u)l;G$e3G3uij+waZ+cvwmVk?Ag<*SBIH%^Z+|HA9G$~&KKO&`wA8x!
z`IlDQgx03$Q9?<6z=-v7^F-S#hOni~&fDo)RKMS0?ek9$;F`@wW!Bf1qkR{X4zW4f+fgiTXV?vxbL_nr&dW1`ZS^s+Z_AHQT21MS1Ksb-N&5L6)%WDqcOR{!bgAmo*V{a<540{hXZNxh
z$!S_H@49`@^<_Fzob?Nw&Wg!TxXZBf8U}hnZm}4U&(En}5sZ$~oaPuO=kpZr?%bSZ
z_V5tcc!t8Pzg^QyPoFQZueTK0tYF8!cb6B^Zr3)D&(Y8;pkKn$HO{4_Ad-lFD|~0n6UId1G!@BdcJatc0#w);<9TtfAd|?^jvO9o`pQ%
zp81jY)FbcLw9Tg20NfjcuI{{3_)u0bV|=O!$e^#{K5Ln*k!5|_ZRDOjPLyBmP&oUp
z!M6NFeP(7_eP*y|DH5i+A=*Iu)}w!DzjIU2rv=g_1d8+Mf36f&or_7;<%#5aY{Yk0
zGv**ZBp8Z?8*;qz?36FFdmqB5WHJR)oe~_jMLCff-O3(^jDJIY6~#O#%Hni%nyh{x
zAgtn0y~pVF>X7^Pdn2(rwZOyu2ET%=F4D9dLZfvjQQ3P&l3k>C^gcFg8&<}Y+dtW4
zj)?kr8mk*I7WC4USSk+GRfDubH;?hxt#b*;5_7s&Co|Anz}u(<4{p|F?1NnOCipP!SbFKM@^4}Xa^_C6C&*=k$A`PSuf>dqG7@7WW?
zA5xU)1btA&>Pz+_gl|=
z^g>7a!2INBK9FAE7NdP2>_z!4Z@@r`?lTL+Z^f(A7E~E~Z_B5}9o;SqXnH-QdN3|XZxFJf{&ULtT0S*DI
zVZQ6ni4;cGK6@IV%l>8$y5>E|gtB97oZ*`v@^=DKO_YOg2|Ca)_!1~gwPLH_K{=SL
z==QG%D#?1g3O3#ZIv{X`V^Y8z`!cVk9b)5GmhJL$a#EnoGdW_6fsA;L*MxBT)AXLgT$g+WITU6u6%(IMRB-YnB_
zS+@S9BbwqZE~Z0w($}ybMrQ>1+w#2G>hURmLu)F+xCh6&f6DS_7=`J|sN^W_t*|JW
zH&XMj0GYEt++wyMVBq@pkkjO`T+)3(qV(xM6IM43Zj^nnIHSB5y#TipC44D8J@Fq2
z`K|-YsFv7WbGnEz!DI72q0#@!$VUpFg?#%AsFj@H+)&PUS|wO2`@B|1)@7XO7!&X(
zEA$S{=HCFcVZ-Mvd8q%pll2GFa*N6ezj#3QDJF#dNhsllReF~KMpiWVT*;lwev04+
z(CUc>wql8~TFc^vDI^WiN#;=b8+T9bQF9@Ur;@>=VLvk$)DB_|6err)AR}N;blL<$$;Is
zg;O0W)0co@zKF-wqnrt$&n?Om&-!a?gMKvU327*vJ?UW{@9~z)N^$V2PI?$gFrlcm
zK_?)7Xd2;o%jaX+@i)ppokTBh{Ltpm7?3UX#=H_&kYH+lHSIi0B!7Feh2K-UcQ4(o
ztYPs
zi2~mdIT*G7+@c#b<$P9c=LTeK_ZWE?n;=CK@G_2xVb0Sc
zSNLm@C1$+(_&>R((Xa{P16q>>cJxXK!9N#mD}n@Vi9xXym52
zX~A9zw*TE51D7>Vb((wmLq^?#MFMgnpD(lrTY*(sk%R*tV9-GRpHRBfl;n@CA}_7p
zmRzX)WFRu$S=D1|ejL&Hz;<=zRu6lq#9^?N&UfS0=PmW*J~9Vn16y*0pZ@B6A_O&w
zt~`+cI{bO~(d?%J(Ugvf7hay9QeqX4?$FkdqU9Cu)6f7e|4{YUhJ$xXh$21MbEcvL
zdlcfc*4-4`0>Do+?kdZ|vpnHN8{4EsBRn^Nh4xWMio&=%B=<1!4+*u$NIhdz`6=mk
z{Ib|?3<844x4Ukp->2j)YZ8uU1=&|crj_sg7sKDUA}s+(C^C5uR#tAZB|!HB$WZ
zqZw_o1?GgVNT!ZLLzc*nmG>l?lBvO$w?PR}zkHGKkNbWe4-BH5)w5!MD!!AU;1bcj(=4bLCD@#y;j??f{d0qomNG9yCND!`
zIVGm8l-HX?YEAHBppN3!g=&m;+8woGgM-hHEAzf#bZ3`9LR`jg!xU%Kob29%?vTg&
zAIq72u?5)bP?WyQyt9C?0^AYsKxit_KK+i3m9|Y(On>|$`{`fK|0u!+I=GcoV-J4V
zd{GbFI0`ZqA(WB(>%@0o)Ln*nt()Z;V*s}u2m6!sLknRl%2*Cd#p9u7b^ASG>vYqn
zzt(sujY59d$d9mwq&%JZmbUxg=Ii6VlwvBbr{?Oc*|;={XY`jWB-ZyrXLIML)*{w~
z895$@x)w_ih@B*V0`pEs-FixN05E8NwlcrfcMmGu5K?Y?hvdH-;If{M?4OfihVdtn
zzbd>&t3%B7NEe3^UlNDW@Ka4hZoMh&gs)jLV^voMXGRWq6qk-`Lm!W$qFkucHweU5
z)LMjIo;AJuy&REBk3(Q*y_&R^{J@7>SSDI~n7CC^B3tCg@7=s6CY&qSFP&F!CB
zDG(JnWj1@Q9DbD8d)zoEdE`DUc{Dqcj@pA+kQG7AoVyVT4q4ZUo0oKaca
z;#GXjGf&Lw<*v4hc$Hl$jXo_|8&6i(UY#Dd)-LW%psCbxD6QbUtpJ>YXn)=dz8{Ut
zS5Wh|LAZ7(KjFQm`gF!1qi>!!V$5rhSq{_7JA95>DlyUXH(&ZMac8#@SUkHgFm~(u
z)m}*w@NEF@uOd2M=g3OAerK#h?{|TY*s^m}hRUVFK5f
z-~PV8_qih#t82$O={Fkd|J9?=dVq5MEnEcmw}(3newIm+M|Az>%LAp+6O*!y0mMsq
zaN0IqB|55OY(+miTFUjpkAUX-9rJg);pH*%*=-_uSe&r+cyp;@ah>k+sc|J?Vn-@?
zqS3_u`n?u?b?SzmS2dn0-Y_}TJ&Zsih_xSq`fcXIR5V){Di4v3(e9ciGPfw
zY+KNN{J7qpd0FOv;}0JZib<>d-1FMhS(OSGZYO~(9q`CyUvg~S`^U^DrHbPgY`}>m
zoSH{-q$Rt&aC>;o-Hb{t_#eOlJsyBFbu{bpb(7X}pRBxk4Pj|tn^5JO*W+vSBw#<=
zt@12(m6nZrq(;Xd55_cfwEwxn4TxgEFcJ#u`%rR!T+){vUB`f1!xU=?|AU6e1`Lm|
z=r#5wfPKqUF;!ZJ75?}aShL1xuU=)A#eV1=qH9j58B
z@0AymEdzaYJ!~$1WwE{>Qy214<*)`94m56#D<)eW@=w0D2ZUlB5iZ7S=dTUfQGOl_
zs9gxh!)walnRv>%&^{^l5Rb?!8#s39HP|1T==?E3eusLv;&S_;Dz=_955wq@t9TM3;;bhCTW{0H>;68TIzK9apFH?hEw8UA0z;~i+#BZe2dtz-7fk5m$MWc
zB-hkroFrg4?0ZhfK=!t%GOdH(_}MJ^yNK(t9JV;J-Bxhtv4Ofucu@bp4AvD&
zkU3xI%j^L0BdJP=Jm=PHJ)R6o&3%}ayubO_y?7gDvUAPWPa`DrCu>hub@;9a
z*sSr)4{y!Y=8W*5_Quv0?Xnf*ukG{cwS2&EPacn1YpbLEN15ybk0>AEO91YOv%l2!
zA805Z)WEUt1IpUqd$wI!{%aFzX^r6jQOn_-K7ffhQH{K(8NX}_O8ZS&bI|@1j|wkd
z(q@*f!0I|SQn2*+s092E@!b_-nUkJorpt4Dq1YE;tGRnUk`s$JLFw9AHdS-qdY%}l
zQMe>4O5e!`t4wu0euIqyFG!hF*ETd$6TF(aF49`y^`I8t5yXF9eaHKnepvLa#BFZ)
zz9(t)pCRPvKeAW3S3{-4KO&B2HDaXPPgJS?1q2%b9*<+vUAD|yT6@;jY`K93X93ghk`C|o?HW~4c$xrk6
zM4T_T3M7!xdhY3Wu#?Th^!S?W+X!B8)%}5a!J0np(4Yb^(r?{~@t>c3L*mCGF=!FB
zzNGulv>w0tUtHq0*mt03$i06q{TCkxepcFcBtex;
zuBBFolm!1W$?;P{G5WBJEq-72Nl%8j59GqGbTa?r9&d9EpY)N0^cT#JccAv!PartN
z5$V6M`>hCA`}iE!PaH*3eaS>JV_}j%+$jB;;hOXlJzlnmq%WbfOBMu{cW2Ss`LMIt
zA^v}ZJ9z6weAxVm0=WK)10TWd&D;q-|8GiscD$RXVJ4+eTBY$MEb}X<)OV5a|5zo$
zv-)y~8YZxn-jh_PM*9CN~7Ly
z2b>f$Eq#P^9&X4W*i*CAMJuaSJF7qu8CdM#LviUUQ1Z6abKIT>z<88?r7=X^X6yBp
z9Iw!L6O{Zi8x~|i#%ZsHItQ^#=7Sbv#R|1adc
zJ8zZV?Yh7wx-t9sv2WxGE;tGqkUI=J3XP317D}|(W~NJ}=>_=-x|GuanL_``M~{~;
z7WKwA3*+r;HuCIcCSJ$-IiUEAx2i?L+tquAa%rpc-_k7CYBhL%6%;t!@~U}uolzKw
z@sz5YrJThnRciA|XVoj|VMo0nkX{ZbLRG&}*wnus6AChTQXrTsZCt+Hw!=+5E%_$9F@F2%DBN`hZnB!
zIofAQyJ&Tb>B08T*}4qulxkj8F>CVOEXDH9PgU|((}f|m5Z0^x|alm2LSP+BIYku2RdIF*O+VbZB55XOTXv)e#PI7B?7`0iHNyV
z%^pXCJr!oF#fXKEYJA+q-VqrM*aeep?l~z&vCHDkrSO}C6yv;N6l~1bEAA&_hR<Fggcu#nHDOrO{>0O}K_$YEf4Q)FXobhO?o%
zgHA)S@phA|7Q;($wo|;;Kn;l@9=nUrO;}A
ztM;W%jbMgoA;3gkB=|O@k|apGMU*UhLd6h(Q8Q>ArKp`&12;!SMNM3n-Aj~st-tfx
zvK6f-zIYY3W+BHk;IUlSZSAXQYdbC~`&GgcIep`E*DJ`%;ShF8w&;-qbsDeLmw;s}
zY~q1nUj{2^=`nq$wY0krcD^qamR6TIm5R`W1$D+H15N|1^@JuS3rg_EVK;8{O3L1I
zgDqDPXIoiD__J<6UrlGddb52@SW_5ioZsQNlgXo=?E$-^J?U)ZGV%r+kK~-
zve7z}wNP>0!k
zrpaI>GwDV?8qq1GjyQpFPR)@do1#egTCd~1V5XSfbvk4deikm}@t0TG)cjZ^h{4O!
zEAwR^*xApxGQ-qe7N
zrunEfO7w!^PW1@oC
z`LsTL=M2@lmGX_0qLuZ@fkmcKSDQ{&P^5C*0AQCJ>HHwLym&xl1lXblHS?tK1Ozjm
zzg39JeZMsPMi-!EAQ-d!M=fPB-y5J`?Z~~d6Ej#*SHBQ+aGDA`c!JZ
zU#(qh5D(>t1HuG(GtJ
zw5V|VV;@Q6_ZmHQqX<0Vu3Y
zrI~XSLk#qhXU5EjbUraWI-c)ieDTv;AMojmc^Px^}eg9VHGvH-D5g&uxZouEnVYiWrd2#)D&mQ&fmfxr9u^VW7k|m;
zgERHd_Bi2Uw>STQ&j>#N=d#n2doIn|Eam7euXHaXhaG`#i5H;%>RExxD!8};2kLeE
zCiN>;%vqI2iQ;~dCf`*B|8Qc#b)VFL{-jyWs3C4EIH!Pd`w;cf$@8T=URus6|)
zuy+fWkXy0zCIK0Rq>m;l%h$9P*`opZ2(#kJC;9Sguq?DneEYTi$@(k_;7KYR*Sms-g@j40Fqr-Y9e=92me3^p|Va
zb2m0&b`|yXE)}pX2C}PpzH&_|Q5PinN=uE^xqRq4a0G}Z+Z8n$sr#N@!XHzhitAx3
zW*-J;vnCy~cf8!xp~k|atu?#x)O3*bolE#$UGqfesC@|x*j!Z=3l0X5W{AHgK{mUrCSt5*YSHIAvQsb$EF25-2zSYjT7KevwDHTf{Ze
z6o#I=>prUk9{6rDkaT{U=pNHlvw-DE)FhR)JAqO)=2orP_R#?_J15*4S_*}h^MN--
zOuJ__4RlRjvt3PgwNEE{wYf|$!sX?EU~ISOFv0;Zgob{o(DbV71AC}+W9CpJ?T0_y
zGqLh6=hIu;X<}qO9=!~;)N{s@qCjV6#4X*>LvJJPz-2)8v2F+CKu-whNbD^P%)Simvsx=>rrN^nAq?xO2
z#&=~Qn?G^&J0O@roB8*rtR`}54=cM{K9od>%0=>
z#-(gPRSdq^D@bb95FZnmM5YZtE$(9>3{N)T97pRl=DWZy_B~kO-uvWBk49QPW1^=t
z=LV9{SQuVyzL+h2^}N?#^khw(@+;1B3Zz#Sk3m40GK-x5pnfI>y6xis{OlnK81mS6
zos;R7N6h6fIdbVDYe%XlyI~~79*Xnf!ishUmSg!L`+uj@(tm#OSQR)w5BBFe>%Lsf
zgfmXPF{4ffrxpk{OL@LlkeSM*j%<(QMeay%+$ef}T|g*}ZfOk!u5Q~+we3}a$}h_t
zp&N=_ZDqNPQi|DP&pyf6<%IX;Fzb}j+i=rkzR_h9q5$i
zq|8*6``DXMw22P!#KSWCs;9?oJV$~1F{XxIpqZLUe-pRy<%$kLIjVJsR=`~P#v;}*
zU(3{;w!(@gmFeEq7WtEJT34#R|U@
z({cF0eUv~%@@Wc@`meh2og>f60lO0ft<$8_gZYn#^(ryqDbrK|xCX2ma7c9L6^8js
zC#ak7W&TyfztVg_5)k=IHhcPqz@#(`JyaX2aPyuBrzds`!LE%ChncaW&V~Y&yV6(+
zW{k3{nz!3jnC9Cyq&S>@Q*Ai3;*)hcR4Qe|ikiq?$mBIb49E$ngw_F5<*YQYzBhsS
z%xXyjYFdQ_=geDKl3+%*M$pWZCn#m?0PM`lrdHiYB@{M5h@
znwK4RLoGTSEut{wCpBi)y7mj4p@cmF=IqE${pRa>fyC_5MDN;&jl-fdd-Bg
ze0ENRKc-=+W&0$Nv6I$PA@q5sFgN4OZa3XQI>C%0JrvvCHXFY{Q)P
zq!=#5h4boF**{G-$l
z(=He7we&{sQM3pbMUAZ9^7PaAjg3Z@3YhMVaMtv*n
z*o~hn8Ju*stT~=1$n8
z0e18y4Gaj1#Oqy^Fgb6ZngnoTf8XBmNLvREKYdBfX7Y7L(+o2{GJG+l8)u&++rTNSsWCN-<#O=_*?1KybV$
zH^Ozt0BeTZB0d`X*jj(B9UrLs?YTU~-sriF#EY~3I$}tn-NfK%qw3cQAB>Kp*cKqo
zsu8{$H4a1^n!KRDI|Pq76W8C))_Y;HiTW)tf&7KH9eL$s92Cw_Iwadgt+;>HwS7|&
z{#=IK_n<~n)n(P)jkLCO?>~Jp*UU@-h?T$p)~B5_OdpiJReHI8ygCg1Y86`82)|g4
zY0K{4if;pCXz69TXB^iLY&t}b-
zTD6$U9x|6Sc@J_aBQfkUu*Wo>qIV}rox&?oTW`DBUD>PdPD}EXw2u3h!CmbitrMv+
zf!#J2?_YbX6we1tzR|Cho1$X{HQx;<%{jSRc-ZuAXXZq}|IR&8zPl}G!Z|OiOCI(u
z^d{_5(9^Rk@ApsOk?(HZ?1!D8=)$O&HqXB5it&2)Id74o#7#(dYdX)Sjx1zLtk3Vc
zM)g(FxKZ+n6g<|E;gYe;V{9d+?-yy$P4bzyii`fT^OZkj#m=v=rnJ?6K9WtvclSVR
zDE&y)qbJ+cd%m8ubdxrGbs?pFstjE(w1v!JZV`W`jN=`;?w;)Bo0Edo?KW-~xep2I
zxIQ6F;>tJI~j}`Ia_p?IQCp#6dae6u<@bIm+Lp2XHlnKcbI0LQzE@y!)H002uwC%X0u4t
z8Ez+Gn^OMpnYIcYqqyfflkBdhFJ$vago5hKj>kw=dAi=&mdCvJ7Gg0b|4(C-I$bmh
z-ca3bT4V0sSV6h5^B3g{I2?_<(kMgYeGVCN2#(sucB{i#yUa>V*T^~`pGwd*`{W9i
z&bO2(n)|dWa;cjL)+=Vt$tnYsM!V?R9bJk&PF!rX3w1!d)l4j~
zl=t1)E5wJZ>SAY-#3K3Kb>8P^zQ_vrpCOmb6aTuPwi7%zzf1PQm1
zUR(7>T(Yc@RB-`YrjUd!-MHz30-v&{S8#4UM}%VIbvVB9)@6aR8l~F`EuMcO?|#`>
zROya7ucz5DW5En#L9{B=F0j^%k0A!S1_Y6JnHpbfEj{J%=&pA
z#?(td7muoH;xaIhMX~)OGF5UPrrs>Q_YH$h3fnp)66R_@d{7rNi}{7SOb{z-#{)9`
zAK(B!46?M3UUI2a#Tnaw4Mjb%a!LJwI}cls8g5E`s`6icPuoIr(?OM~x7O(&X8NMw
zr9p8LFd;G;dtPtz^eOF&E5?>0c}T%U#T$Bs(>3=CQtfidp_E#XE
zjQ{EeR4wP$Dx^evNGGaMmsO=0ZG|@V_n0LQ$m*G$7TbIW#v_l}Rd*Yaenl&-tAmB#
zA9Cu?RLPLHFOHTn`$@5L&fw2juE1jXFVbX?V_1)_bdJ)7Kej5YXP{0L@v4NuN&*4>
zk!}XbZk!3xfd3g*TiWBD;16aWqo+i;fsG378@${Qb|;ig3B>cKB$_
z>dOu?0c@|$X-agW+3(cq-rEXATS22lCn5*EkRnOe9<$~u>+z!ahBK>+Qh^MMMfmAc
z+hJ{gg#_N`5ls%%0`@_?@X3lSV
zbp$3aE&j5?&L5$^tyROPZ+t5nUw3|s9ZDqrSe!A%FTvH?zz->@M!$xNcLUJpT|uYA1+;J0IP4U=Daxf)#8eP`4)s|j
zSNeslo)DNEWFx7WNu-mhc?w(boX?*hkq-OX>q-qgrZBi5mhP_d?ds+%?p
z&FwtV57Pj-GS&BVb$4uOB$+Vd7CRQ5vbQmSSA@P7(ALop`)j(5zjlKEaq0ua~aip
z#ozhjIlk!WFJJB^($$@HL^(^ReVC5o+&6uUJhyv4D@Q;4uv%G2v7>J7boFI~^E;0|
z=T>*M&ibLCJHb_aG^wCSZ&R&9Ju~OVng^j*C-$S#S?c%#!5=$T`;^?T!w1r8H(N}#kJ>`jHlO@wI2DUAY;>LzGE;5we3&bfTUt`4
z$3`Qni?D*SIISug8%U}Z;4wd4>^lYw%O#r@frV>V!&^L(>VH-HLZ%$LsOsmXRL*Ip
zWUh>_Q=f9K*0TG?;*-Q}z_+=a!Ygk1AL1$0kA?kfJUzs@3rdxo
zCfh;xdu7mL>5ejhI)UsZ)XJs;z-geb)!)lPy-r>jmeetnA+9gvq+F@m97$*
zt;EDX0$^c7eX3`%iHtHT=cXKIbnuNLYgE_`0_vS!0vx
zvI{WKqNAdEnAIkd`GVo*W`=tm@73vqfKpka4o|rlu)NaI!3yFu-19I|ce1cM1q6Mh
zYkL=$A35d-Q~?Z8_gf8B-RHCkSne*HQ0`W$N_1sTcdH;7NSeU;4U(nNvR5nEC>9JQB~xYdC_{91a2P(r2k4SHuE>J5i*Oa7>EQTIsKTclBAeo#W2oy_q>gCFn1
zE4uqijQK8`w`rJAgNH6P$d0g(&NycvFVG0!lvJl&Qx2#_7`Ap3HVq9t+kg2x80YC|
z4oyt8ElBM@OXmiqdDIt2cBfq)Hp95(zt;GK1kvhBwrvr#k@JA`dKRi0KvkO4^>_S+85bJE||
zMO>^3PPC^2PXX7jNrXWn^tq6w7L*7nD@wP5sg{s27?-;+$1MCZ~0TDLu>(
z83YieVw}2xa_nW6x!5yMkRtwP0iw|(w4^BJ_!!fp$KNbLm$PH#nmN$Sy1cj
z@4scEjL^0jyvt0Rob+5FjU%5gUew*8Ai)|sRU%9lU1xV%tp?Rou}`R*=&yS7S}iK7
zKC7izS5I#sA*J0K99dwM0DQOYgy)ygc4v;AGXBlWQQG^8X^AI`d&)o;py5)#5I3xR
zYstAe-Z%w$pA3Rqcm3SWs?R$@xM_R?QQ(vi0LS{M}WwtJc#4Kws>bKyBN
z4-;P~VIqdXaoe|pC&2i2l0LvB`-kjB4!*g&?&ZIWl`T#Jax@>;tIGnJ9ILwSy`FVoMK|`i0-&I%eN3tX&add7Q$Y%2X40`UZQ`PYXL6a89%7Qe6`wFg5AS-9#`n
zdy96lr8Wv&$5%`G2r9tkJ4BSc?TD`%Fdo4D%6gdK6w>qFkIXa5M77QieZ*&ISuJtL
z$*)+BtSu|C+P-MoL#E~avnM4IM#C4zt$2zayxVkp(IqPt_DRGhIZqySp(l?jht6Oo
zE|s8~?(QVyM;usH)?`Q;hdLUXR-YGk{REjW
za-2slMPN;ICAAO&@y*$)BhgIQ;b`_E+eO2w%X3$kUUy@tPc3A&$T2UUH+|Gc8-eI<
zNi&V`OuaU&=3d}CC#k~U
z+#ga{sV5zPfIHLy7cf@pKz(LOyUHw31*~sIP@A%f&dPc?793q5duR8fc_L7%gB?TJ
zCzYgJm|S6uedcdGBlh%9{ePkxW|ty;&ChL>ZF;tSo0H?+p-Un~not)~uuvjcELkXv
z2Xr&ac~p4Rsldbt+U~vkUgT@*(UwBXSK`2n%fUJ{=jqP*51oQBg%u^B#4W
zP*TKNw02mf@uD1H)~j1RLOXn8WLb8R8L0|lW(dW^R0C3qyboJe)_!`tzG%^bvORGy(*x%ASj>i_6Mm8GSAi(tf7#*BlHVdCjG|^d3sh5o
zuIkvB${f~(i^k#=jt{7PQBk9`@_TUr#{JN
zp-kljKok($vJ+W7obf+DW?NT1xD)7tKe7|I-fAa0)7Y;IFCEZs=Vk?93
zDfZ1Px)X=cwT~~-zowcNV(%HJ2emN
z0K)E2{{yLVlqsyigitRm*Z`c*zr;dTDe?cCgUI&=jo>Si{t6k-w+$v8idyy73MUnk
zVkqmLyET_^yGRiJg1}M#bZcc@O*MRq^tO|WOS-h@W|Nr`&X5sIa5_>YbW>5Wcb!#~
zsysU3z=9I;mX8Q;4Br|o{0nY+>7@zNGT#abP@j|kmTMD1E%G-b-^%nGkv&pQUk7|j
z)#sgem#kN@-~7D)NKlgckvW@AMP>DYsJP7~Crif;)d;!A656-!RC2a-YHe+MXehg2
zfk=7ek-|4gc88gJBi}0Cw)|4YRrZ7*elII4YolqZt`cIwaMHmVI=0rRs~lE2Yr7-$
zf7+-bv3Cof6u;Q|Xo#ThAH-1)OIuR`J09Y_~WcXDYZS;y
z2>RHY_gSSvjN+}POtqQOoaV%8k#
z$BJPg+Ia}CREy`8rXGgF+&t^?_mI$Lf9}xn@o^>sdov3M#oU7ZhGJsDRo3>4&c9Xg
zr`YKEG>6{7@Rrx&rqqaWTOD0?yj5Q*JV^9j=AY-4G(?=?eYEh+2XxMWmS}Oy$EBv@
zLueNA@s90`1|y|pB4432VQ{&MZjeO0MX2OSvs?VTbLlS%U80*nkFCQXta#HDk35|u
z1lGjwQ?VnP?dV+Qx1Tm%{w^qxa`PFTwn^sEXNR&LP&^nG(n*q_ik`}J#EX`6pzG~!
z_uG!zvz{fsp7`Bee)WCVIWhMA=$fF;Nvo&~#Y6*lcI4J2SeRiX+8>)Oh{QiHrc4!1
zNJUX`#8z?V3_4hhG=DyjOMn}HdIjs7q%qvtSo$!H
zz@zN-f>Lnx%559;)Zf=yFW4{xP;UX9r>(nLt(M
zg?Z}wnuz-et$q@M>TUtPb?<8QCrV$sqBOB?R5sV!#YWcyJymL;Tl;2edIz|Nph_{B
znl@oU>s6E_7M!;4#p1FrOG?s&J1NdJQ-=ulY^phrc+fr!spJoXnUa-la|^U}j$who
z)YN;@Ne3U>Xhdysk8<_TgMF#8(RyaP_I+?x|yfMi|pGlqrmSZ=aax8$#kZqCY5TC7Sna3oRD*8CkRIy>loyN);3bvFAc?0zmNPuMXt~>{lBdopbHJHu?b#x^KN0yH(
z+v>d&4yuHO@cKASFoBtRe5XSnzQ?S_MziWYle1~6f^u!yjdI)_
z^#b+k$L(58r%H$G)QU%X5VG-O74fYpa&+_qDpJ$RM@8a<7tqyl&72
z%029EuwGeyw+-?CXu8JeIJ;;a+jbf?jcvP8(_muTwrw`Hn`Gj~PLswqC$??e`R-kJ
zt(jl5=FC1@@7~XT&Y4#5R(;GkH>u7A^S{b@4?96?T!`4%i%pPKp~#r?N-NPN2j&jv
z`j)AWG$o)sNW`AntC-`j`<{+I_!;~(@0#${Hl6b}MObr-Vn4O0-yW+uXEFKs$p=G>
zjG`u?r&wE3JEl`RMbq4l-)%5k{Oj$>+AOL>N1@_5V696X2pk&beUyLceB-itVJBw%
zbY#;l*eFlo9SJfvR#hpY_>!H->FgTA(P3RrKGkn$wW|5e?bpS{$MP>?7Svh(SAi4e
zahP0FA(wvp@>;8;ySj*A7hkZCbqN{hTfO
zf31p5r8sE*8J73kR31GW&%S)=DRi=$n4ZXM0H!sHC^k>Ub2xV=E+zf8$^UitC&Cyj
zz2s*rxGq7LBig-vT_R209?q%mAwbf&G>i3;o|Wq40z9Zuw%-X8ev)IWq+6~5a}2`tlp;KM7<
zu%Krdzxn77+MpME3=3pSjk7!7bcdujwQH&HPYq~pmo!xc*o_GnzkLq)maw(!sCea#
z)sK1`+5w}1C!$|4TBS3WMpl|`^`_o`b)UeT-xmtf9>5p>vDVKtxs#WDlr@%U7DkJ!
zS|E>b?A!|Lb^v2$@+w++V>5=;WF$Kb_nt|v7qt%IK;Z2IeCFB3-R4cN=7ESeScPgM
zZ(3n&9iFjC{s2Co8Y)@vvo6(CKgBg8ValqV?O=?RkJWpIj5$7e=_1
zy_~g&p4YNWR<9TXrLsgU*FWlA#N2)v(yN!WE$3+TP=hG~gHO#t1jPmEaP7y9ufWa*
zb=heG(!-z__xhX9(Ro$*^u@c=pgGOz8&SQyZzIUr5N}1`K%mWsEw9SLca3cmoAnsr
zHx)QOxu+pKB*xwL>XwH9Bionuv9~<38sKAx>FK&Ml@V2#T5I2|yz-`wO=ah9$+cf&
zz$j0le*a?^=ZZfugGsku=1>#29?d7ku~fo8D!OBjjaKRK@p|W+esFYQe#Jf%Uxqk#
z3A(BG!MO>`{Oo~yX#R!s4NhII3T4#J>u`CRyVl@nNfjxUxylTC4g}JTdAD11e{EW7JdjD>*P;y9CLTjae)VB9S%Q-<|C1UOIxt_Y0a{!8TEjAcB-=|vaiAT
zRrc%`_YkInZWi-WpNJc126K({??`i|@Oui$XnS`2vp4Ph497AzgW9e#3_ZkUC}Uk?
z!@5+*bh63FdpU!I$8%x6$_Guw@k0Jy(<&i
zOeNNGgIN|VUB@?8oXdZa36hZrcGpPttCgb!x##*uKV(%BWTIVMt=K;~sH>Y2OlTgYY)EL=IT9
zx%0={nn3tbO1x5pYjFYXcu;B3GPa~5)LnGc^rpio(rs=^)_VfF{@Xk%gOb|z`LMsN
znWw&2p?->&;&f)sLE8z4GpxHlP>ZhZYr)+CDQ8pC$2qcqe!%&CFc9eJAp0MIZO$@c
zi*E88A?u9;)RIYUtK6?s>*SIlL6w|(c7FEDg%tOe?^*d}{UXV(bI>-s>b3M81TIN(
zV<$Y%{GJ0B#aZqaH;F#pVQq?1Xz%a|O7244er`
z@aQ$bPWG+KjCO+YcvF#8W}+fb%My@gX??(zQAof@l*}%iCuULg2-nV#HZQl~J#k;+
zi(dc+tSjHT*zcdRUV`j;?aZ=EKJ1v4Ezv)%G`OC5uNwJWOre4}sQr|v58whZ*!t1qu0snGNV~P5whI)yNVrnRm`?rG1gRpFm
z`hnYT0cs&itHKiV`~{OJwil^#>pTl{;s_w{kvr22LX+RzakYvoCcNR3akjNtdqo6&
zERu%9{JO|p_H**Vhey6$Y8LvJHT4uz$gf8cUQIAFqx3jc2
zXJk>iu^LKV;a?n99OTMHx6s;JdBD;al=yF;%B>R?Opjl7=Q8rzQZ{7&lCw?Tgat|!
z$o$?X~gioB3iVKc1%o;s-AF&d+lzHAF465youxWfmi5p+rr}x1)|{zxl@aNX`poa*
zNJwq~-h4a?F6i+4h~tSP$g8Bf0)Ekp{#?PyRdy2V#WWxtvU64Iy(WD`y>~NmohMZ8
zg;j=;RKpR&fsrwDf=pGTsgNrJHb^{FCvN~NPxvm$7rsNSw0GpaGWrGND+!Ap`CoJ$
zZunfZ_4wc&d2@^Xb)vix+=A^L3xfHJ(Dl#=kx^s=vjVR`rV3PQ8;~e`c($!af$D*(
zanXC$TLPNNP@~9)nCU>BI
z_gR@FC4lb;_-?Vrg-bgBz>892O+>~AKi%-ydT!viR$)Y3n0
z0nLvK)hD&NH;vh#$GJ@fJq{Ua(ovgs^11=qzI1b->QNMr)Q_xJMR-X*H<3_&nQ=$a
zzLJU}Y19=We+cFHgZC(N!1uvrNPLnM$wvL)8{QwEnCG+mns%!#(0o^8aHJ}XS64nM
zMv@1V1GgC^L<>U+`14cn8@kl@;rrgY5n{9oMN4tU)JIXqlz(saf(lR&{)zo6bjsz#
z3Nju1!~GlxV{CzOksp)&m#?^#289=G-qLLOT_xb}99ZtHb0{px;_2Sx4ltbN
zc`}Y|;VRi!Sc7}TkkU(=4u
z{RJ!O*LSlt2!lS9=NIZLIn0fpqZY(+H6Cs?(<&6%Oa~3*l5Ut+XofK&>P%y(jT{HA
z26XwijIJtDJgT%~3Oh!C$x8LgbllsO)Z*r@u?xLXjV<@qKAJ+X-O9=r0wh@?LDuv)?8WWf=%xr#SqXd
z{u-{Zb0hB`+C2#bSN~}W^iTn)*<6iR-&h_KW^#i#Z%v)zL~;}0UtcGL84shc&yVjX
z&RT3D?6qyhg&9+J${Gg9zByYom`c&SgAy0mBd)|(LgR_G0iyS9U?1sTU}(t0LKqOQ
zX#pEr1~4_?OZol>Si?2_4sp%r@7?q(AN#96BHxi!~C_j2clqUG+b#3YmG>DTI
zvWTNg7+UywYPYWu)-AJziNdJWSNcEm9
z`?5{?l{h
zx@tW%hkuitnTvitQyc)qJt8pTIx_>w2YP-kRX}QSB&=qK4zMzAOU_I0q02U3Mz!iG
zP=txQ$=jMfAE1qy-*Fu$XV)UcA+)RaXxRW{ay3oMR+!T5f){57;US)VKxv8
zJgG?L^mA$IW`rpxk3j*@K*+33>@E_?`a}k(o-3=GRj5DaX)FKj
z&(V4wZVz2dgShVbP#l2?Ib`4~Fgqt4d^k2&XQTVQ;}Y2y<+*vP$36bxzH_X)O|7zN
zc(Q42so`JEQ&O>%sm*W%>qrE5#J*dr(YuM9BM|kIyoU%cBPx@`wWe>1=vAs&x%P?h
zc~=!R!n6g&ncJ|)^RLEG3x7f;$=XXQ1LmFi7JYDXvVG^5^eoG7d2#}gzOa`u&$bX<
zRVh=?Z8DF9_72H}R57&SJ_li%kMH9@RUfw}LZ(c5UBD?vv9u3K_2mFA-&Mzj6)!H0
z6@2$1WoM-BDrbPWE{*$dJ$WO3{lfPC!W@Ub^M`NfP7aTrdP(o!x6JBI4i`}Fnmg(V
zPNZ9h6aVo?^K?2C>Am$2-CImXr|Q`uKePURnm%~IJo-((?Xb{Lc2y)v&oNTgtVsCv
z)EF3Gw+AnuyFwJ(O=*izr@t_fWo;`qWDLLU61WtG%w6bfw8DNniB@^bCk0|rt}P(I
z(KX%klxBw0-*Msy>FoihC??^tdCn*^)6UXKTij*QyP49H8qS%Y)#_^yZ-wnXqhd8_fqI0I)IWTkZ>|8^c(~y?>vzgk5kgyUr|X675BBMhmK~e*BBOBL?;BIB
zou~hd3ESsN8AC)H@zEE|d`Kx*qMl>wwLsM^=?PaOM+;O?6zR>VLKDVw-2{ObkQOXl
zbgfa_@+R8#T7>VMa05N2+-U7eDr*Sqz>!_=uHuJEHSp(GZYkj&ZW{-BcXwVw8~oN+
zekGn~h)+k5&f81sEzO&|4k$m==z?j*@#MH-+lmlPqzwB#fQ?8Y&Z>{6za-++nfCYt
zLx+;`N~fV6RQMt}p5tAC)_gRG%5(N~;WL$Y-E7kyLLG0X(PdmDT)!<13{ivtP<99E
zrEmBi%EordnG_EeR5IDI(ViLk%z9bY8#C;3&5oZo
ztP@x=w5wSL%xBuyfHV3`L2a@4^DS(_FU}sLOFmJs&J!np1*UV-4J6`LebW>_lOME1
zV9)V=13o)Q3Q~88YfEga1Grv!lvg8u@x_=U>3f0VE(xZVXjl2nerUlH(R~Wkro?kI
za;{$383kb=VFgaIm9^UzWug)>Z*qLNdzN-~V
zU)JBn&HPZ#AB~(J&K26n()2ps1vI+N4%TW>|B2O~W8?GRp{$Q~=a#*Jj7h4b0w@|2
zl%OA1N!bKB1!g~L6YP)CpIOZ_xc7pR0Ih28Oq9fsJuaHv#?FA%<^=;a#Xd=|=eQF+
zK$9Y-2I5)-v$pis7Z$iYn}UjLxo2IaFScpUQ$jyZL-Su9Glg*UV`X6UC{xMceWwGN
zKWr-!*YFeHO|l9&o_R^!KrMuq43%V|D#9AFCG7b{dABaq=@~s0C#9w0_9hT}hwuUf
z)Csi(`_AfHm|+R2xvNyf8dbb!=y)*$Wu{s%!X!#&_V`aUj=rLg*0`+zfQT}GxHU-N
z#>;))?N({0;?6I49Yy!d!G^l^eRI-+EjbAcn`myMo9g_TmWs;{&hu<%~wqq)omko
zPDzB+Fm2o1BPPDeTBAOZ7{VSo@W>o`if6^J)5Hpe0|qoDf1ilWawYi>(B~lcT!lI7
zZp3~LK|c6eri6d@y8xlJvJzQJB;3mxJgn*|F77W@8Z+yKN_aI8wP}H|{LHAivHevL
z(|+MopoYG{={MDh-Rc9=^NbAea}piqE60~(Jx9eT8SPtxo=>;m(kt&QPnjZ1$`Qbk
zdp=`V+Z1I*EJ5uJ+YkC^Aw%YSJgeV-D1MPP3`;PvlrD`z_{%$1AdvUwLn+dtLom*>
z(A6}WR(^YqQZ8zy8hbPPbzKkgOP((Nxvsm{xd*y_(```g(_*1rODB2D^z-J+-pgkU
z*;W@L`&YrEtb}Zq=alGYj|yWI!YmEQ(O^E~a4YcwnIEm}Rh=y4;x&w%l-b=Juq}j=
zu=Si)RLg|x93)#?d{u((u9%2Wq6c|A?aOlU_hlJiR7d0&T+_Kf
zl7`yz;n1NR?vw4vwHG7t8~Qw)_r9i-+9u$Ii{`
z@uX9kaxpP}e+NH};iA>fM=fT&#ZUiC>1850TlYV_nYTmDj0u<41rKSY=K{|YMCX<#|=zDow&yMn?%`1h?3l#31@^dKoR?3Wm%c+3E=KjL=0mL+p
z+XivW1FIZMvDV69r{9ZLM4xvV_w)PceUUIfQu?v+pT=sCbm59DuwgL(Qsp3
zqh?|Vobx4HZSs|ttO*2
zO`z2iGS{y#|H!5}A^Jl#ChlgD3xkTjUvv~tYan;|k-8@Qa>Ky8{Ul(a=T%I*fw$K4
z1~>Em?%+-yaMp8lDs21f?S`PR5-89-;4bo_(cu&xbUKwIHL$>4!1J%4RgdfR5J0-V
z00D4JOYcs#!Ole=bzTB-CuaIc3ox2Qc
z@aiYRW7fUl;=#+N?4#w&C?SSnW;tl!fm_6K0YpVv>9Bv-5A_cxHV7Gejj2@Uyz6dj
z{y8m4?}Gk;<+|zG^zc#B7ahJ?3b;R{ypamN-XgLl@N05PXK`t?@EEJtN48!gh11|<
z)3hyWo&-l#Yb2Eh@k>ekPl*o*wH!mulAJ}!~X{^
z1m(kv`qyeVemm#m!?@Ih+UQZUhk1_);;NfF5=li`2@h>ay;->j_nhxP?6$nI
zbCtd(LpX3#S8k>wjX|IK)Si4GetTMvGnMH1dIMK5uq!MQe{urxqe3>u?I&q5j1&_@
zdu_pyS?PbF9#ZP-ZU;`S=w;kj)n6F%7AiH$PZxzHglr$_cDqnIR~ED#NB9b~Raq}*
zxG}z9J^^H3ETa9(Tj@_1%q|126J}ZsW}hmm;?rQ
zXq3Ay#t^8r@EsLQsCuZ?1O96lI{!rd7014q4BXEkMqDRqx9h*XX9;+^Uwq7YjIhgZ
z-%}LmexAe(+j-v}L~q!=nEJ8yu$}%sw&;=f>@#6OZaDRD>zH7V{Gc&}qDn%%eD|-y
zorhFl)tJ2rNVJ;EZSfZ>kOPIgO+oM71iHtA<3nVh8k9lZDbiJn_}yoH6eN{!doxd>
zam|xrhT&;Lmv7_w&Dx@jP@qZtmU7Eg;>P>iFu!f2;9KDoC__Xf)he>E{aYKs);-*d
zuS|WNV5CL5Y;X-et_i!N$;nIAD_kH?`b}H-_~6J>riJ}
zDp*4>3R?Nq2VnQ{hMPxAD#}g=
z;|Sl^`VW_^FDjQ?iuVhUs%5b2c~Mf}hX%b>(%&o9*ZjDuLejMz7EsS8i8uNEu{I(U
z$s$=&)%SsMI)5(ucX;(g*AHFp7kUG{RwB!>Win3AqjrR5>YK^Zjt*(=wX5epaLl`?
zDANi59O|B=#}qK^kW<~zjUUVkVl)_AGN4{bSIEv;?fBJ<5IHJ2GU=Ec8S%nxf2%it
zcJ6W88L}ioXe{?7xwr_^s?JLj+c*-t$xXT*T?HyYhJ@ga|&v(al{@pkBHp+EdYE03=@b48@
znGe>=Rymlepi)h9gWNUKR<~XpyJDQ>I-$Tu#f*p*i2qkrfL*+cvTn(I0xfzEwa_2ejwez+Bcu$f^R)P9}$vG|N)xm7T
zcxsNY%h^A!D1PJJNe@1c_NTq$|L#e5AkKGN*hbmwP?ATW|CWiL30Xxt!DEa@J9iX}
z9WmGsnJ1U5bnYj?$EMha9&8^|#G{2g*%+6a8GGeD??>Es4AU@c=J1ohi1!@}bdz{m
z)IN#(0?WPY0L+~3XXFCeO((Cxf>_k@9SL+7B)zmaLMpS$ZKIXfcDK-AT-O*ZwaU-k
z$^{8c9Nn;?$Fc|+Ih8?sTNe#`IR=hS1OzrPpl*ACYnef*Tl|IFyMWzsEvERV2cnHY
zVwzeQ^URq^-^Q_Gxx@kAMc81+=hnNF6dqV7u%TeS>>F*~a#b^Nd}9znXunLkY5VDu
znDfUHv$qn3n=nfw0Pr3&l|G?-7=h!7xPh(4e02z+v~L??cVDYxCCHOW-hP=~>T6Gq
zmq(SSAWxYpORJK3im?c_2{B2Xv6oXs^aY*Yjm=86?6_a9=R@
zF1*^u-1-XpFgEw5j*^2I9jjWR=(HM$CzXZkbaep&oW9Rw6`1`cEl+k{rM(x{hGI@U
zstu|%Vffe7?9h|@M75h*pHUK&L$wnbI+yXiWR@-Qk;wXDsQgtYK`FaK^aDQQs91B#
zrY{rHGbzQ9j`i;tpLTya*7swLyR}df#rj1=&r{iFh0yQ<>_&7`LdQHMJWaK@082dwTC;E>NeGV5&Xtp7<8hmQ*N}`Wzss7sEC3+kFb#
z%ve~pZM})s3>Z+(iowNaTi%!AoN{8esj`4kf9K)9{)e=U3;LEkFX3L@k
zVXH@jh%u_6%qsBl$^+L}e!`O05#scR=dm3K!Ed3Zo&O^zoanueGJP4St9~auMk#cLWhH6rqa##AOZ>vAkKltYF-UG<@_ojMn{sni$L86PK%nPKrakn>oT%!l7z_P@%Wo{=jnEz#(%#CQ
zYnql+In-J#@AwG64-WBkBfd=Tz5sbn!(YBcKV5x>_mc1H&u0K8Y6ny#4h8v@XP6&%
zM304vbM2P_=bSubQKknlp$tI*u;!tz1Y8SSI8i^9ajArJ2O7n-&UGNPWm$wHshSY&(h`DYORJ-%Dx3E-)~jsW%QdpqC3rE2E!t*jhXQ
z?@S+ue?18&>ciFlMAObyd+PkXZ&neu&|b;xE_uLm&+%dIy;UF!sbMGt5|zmP9XgP?
zhhV0h>Q@MgF`h1)*&}*1^8M{*fR2YMn80xj2E|ZAe{4~OW;<2@xI`^X{0?P)@lJa;
zR|{co5cyQO6YPT++YhV4q@bCy{?@m-4>+Cekwa%Gzbtq$4O3mK9f0pBVnUVb!5$e8
z>wOinHx~ic(&7G*Zg5CPYJ=P=6OQqWMqsf$`)vxjfqQ!-^W28+%>FJ%_L3g)bn!mn
zDL*faEwEHI8ZKu~xf&LrEt?83Yd=BzxSnq4U6nm!8#lz1$2hs_`3a_f|?KMf65NRv&{
zGe8YP-q@A%xuj_bf;cgJo8PH9XeWi=?|L8jl12sLx8X%&hVb(O=5UMJ4QffA+cwrPRkzn2T(4k+-)485s&_cF$Sufvj)1Yo)w0_pCX`$
z&+Pe+I-?seRGad!s0J#^^28`pFC6FF5QiZhj2a8i{)*QD`xatuq}XH28m%+oerzb~
z%Tt7E1=qB#{3kDgYnZc{EtcyKooqdbAreA
z7$e*IR?T!ξZHTiogJDl32mR9){duBKZ9NM0%1NBvQY1PR=A&Hr|4xP|A<8Pm4uf@_=C-n5j{D?2xQyFldf~LkyYN&ol
z^nvHMuE>tfGVkk%-uX)Gf70i-`#Hs0cx<8Q@sJ@-{jB|QOcU~gGZWjgzO0?AzX-ft
z6*RQ7^n%mu5ID)(REXRONKF*|KNp}2)-vwO5&A%k7Q^oHr5hokdeb^#=C38L2B8S%
z`G#GoJton&zKxH1oo|I!qoy4Q(hf#E(1*~6RL+W&sa`lwxT6lZ>hqEeHn)6AulPz#
zxMDw`yAe7G9Fh|luK1SRYLB&>#G&h=0%EVc-h8g{5@UiyI1L$ZF{k>7E}0KpUW41h
z7}0`KwjcVkR0mnm>y;CQW{t`deAMREgT09sLnfgDCE0}tlRhCfkQE52`qA*jG+I=O
z6{b;_>$ON8KI|HsqEzdSnHl>+H-IYDaeCD0z{x2-Q{6-A^c@@xPS!#(&*Y
z0^6*%cQY_G`l1|l5N)3#-r0g-jx~2~`
zpKCK{*oCze7f2Oo$hcx5vSNGQPm@F7np&vFbb$TDRk^nAk$Ti!(j)K;();HNhBZ>n
zH()seXCm_G@Q;SZ+r
z(XS|L|4Ay6H+S%n@VYq-it#NtHW*FNHBg17gIfOzYX@IgsZ}8ie%*;-r)1Md@kJbt
zRc3=Z!<0_7^vRG`-z@*x^tOIvm{Ks;#Gs**q!TLbLVre1Fg5@iHi~^}2X$P0+$4=m
zYL4>GcU#aSbj2rE4#^cn6wDAQk;`z`aCR{P^fs$VL|*@`yibPN4%uVeY!a;d?;8St
znVmSYTi*imy8hYtiX4zaYBk`mTd3!h_(LjHltpJt)K9>BYEPro30q3JyZ5Z|@m}9xa0^KoT3e;*U_I@MO
z*YuTc%M<+tpxU}{allGP#)mnFiLs6Pc^g%bj0xy+b2RQ93FqglOj44FH5>hzkL++v$CILFjkrggoW==MbJ
z{!n17Gdh+LWsn64p4+#XC&<&84pCPf5Q21P-h8pA$uIZ{kp
z)qzA;9GQ}7=K;p9Mqpty322V2(KkMqUUmz@qsJ>I)@}M{69O|>
z7dZ+)NbceWe3`Gd9e{!;wl{MdBtm0fpzO-1>(=P#s^w_sQ0?4-S0{Mm#
zx>T{A>_SqK_R!tZLR{Z5>cYI8s_}!@l*cVZ^chVxmT+tSv7UnPtL}Tu73b4S7H;t(
z!e&UmPQLvM?C>4XX4Ur_@7u|k(FlViZuxHZSkn_Pa1Ar2Mh0o(nYs=p0MO$)zi(%;
zbO90{w+y7L-3ljBRemg<{M>b7_w5C-_4x{M9)7FXL}Y$)H+Ro
zf&REf0N5Sle@sFKXMJ_FJxbi}ABpbWab*3ZTs^aGG;Tqlch|mb>nS#Snb%WCiiqH7
z4zKKWD}N0DkBOTc(Io?@hb^wAsE%mZqT=Aa6ZRu2f1ILR5AI&RmQGfoS|QTD4d-*x
z{c9iNlvdTXiXL&B=kNadVEo~s8O%({TTu*+`$(C%7UU%CYQ*E%1=Lri-*b=OgJ$00
zH-G%S0BvscpMUo~!Adazh?Pt*zu&1+FLrUob555(2gu(p4S&=e7~mvOC5cA*~kCZ?=&Nf?>PR*
zX<3K{QARG$*w{5dTLsA;mnv!Ukr1&N8ro|90Bk`s`?6#0k^H3J!+8S3d7k&I{tx?P
zjR6keX{WJ=v*k9t7>__~@Gox~$>inYqvYZzzhoGYQ*h|^uU7J5BFmxfX=#WkwHL-9
za-+PQu?pwBB8}LzoXS(?mSCDG#bVn!Cixz1u;-wgpM%nin?Q0Kls}J{8K40^Xu@H?
zt>#j-2M%IL){fx)DvJ!j6Q1HGzLbtYVRE0VKaw)-`<5b&1ympu-RY~DB^N~PP<$rg
zMn0Y#A3a5x=qft&cA@_SD(R!1UJRVtLIsX1dooS$o@>{`=q+O^nH>bJ2k`)=(Bbi)
zz5)+ZkXDA|o(Ex~D|Y8uPZz8ZsTyE%?+Y3bCU+d!%P#*$*)b;shmT@7S!3M711wFRitrk2)m0-K
zSlkRurP8(13(|n1zvec*5v0}K9h$@U-dFEp0u9ne;5n+6lMV^mU|cmJz8=@`lPq!7
z5ffCuB+9qctouBHqxlTZ(%Vqvn#N$>Jv*i2neQUL)iU=|;5@vfB&-#=2hq_k2jPEU
zh`q%n^GWdxk3M;PSu=TP>lEqOp8!RxYBI}7<@yVY?VRGFOqrbRYbllVNbF4CDWywV
z0WuvP^&I7}MNk7O_bC*)BcNwpOY=A?DNrkT(tA2HwdFq@F76~coikK}g({5FTVAkm
znG!mE;Bg8D6-NYN9hZDbfI7rQZac!iRendU>mMTPq|8$we_$t5GKbJ#+2S4pddGkU
z@Tf$I`}!~*)=Y;j6;owoo>AxYac?C!(@%vyx@nHYkubdwuk`yT^iSI_mfDdvGUS0p
zn!%HtRq(k|U$)SF7~W>0Hz*O77f*Mz58EsX%~t1wQ~L_5(-B0x-Z7qrjD-chMu*@a
zw~=k(3%hUQU}`yseu~5m`arK&pVi;M_H|
z*|KPefT?8u8^IU4A#`XH=l%N*uGFO=J7X~xtAxrwTGOhP(4eCt!)VaXK~
z`f!+oN42&QkMq;EM&u2j5q3&ewdd0vH_20k1k^$9Hua2j&a?H*t7>2
zT=$2roS`6!qR(|
zp`I;ghMWQ&mf|6k-diw7PKa0|UeQf=l!Y9||HK6U7v)P8MuSt$9E$GpR&%%BsD+(W
zt7R{X(h?tKiTKw_y71MC!WU8KZj)7Lhj6M%I-`v50QW5lzUuNOAMsEx`Lw{{!$9tk
z33avSBC!}3uxz*P=QqVlU+-(d&dmF!x89PbGxWX^z1f$ZJy9?#WY~3x7IAPq_hDLk
zWvhV0L%&_k>=@Sv3x?k(H1jp84>xY*DR{r&3#}=*=OK?<84A3rf%A9_RfwN(69eZ)
z!<>x**Zib)1)m=3(~p%p-z>?!^~7~ecW5E^R~?APw)(js4MO_|;glaP2T{s>-+tyb
zzQX$*$IGIdXP=HydS)w|Prh&%-zsZoNDY9^*lc}j^k}BaVb@?GY)o@)tCsZbUym&$
zvyrumc62
z`N>-KTK&aHs-jJJLOqP|D8}k>K*S`gL&3ujEWB}fCfHV_Tk4_eQh*i}YMa~ts;g1J
za3f@L&!qal*xxXB{lRyf&=||GMpwrQ3)_4@Uk;AHeoAhq**v
zM_R}K*t;DzfW`0|6r=m-94L{SdSnYoT9JG5Ybh{_?*`ptpxU}I=~_}ZG1Qz+Ni9KL
znHj#?)*-fed@m-A|1UW+Epfc8T3m=oGBm^%pcU!mu%RCYAKRo}8Kjj^BZ}!dfg3j+
zEp&%bE&c~#-8|>|g~i@vw(*AmEZ*-r3(*x3ORp#@3b1S@x6B`&J*odVV#So{x0|q=
zAwDT7Yv~Rebk1zapnxKOhgdZ*p9Lsr(aIo^iJsnv8pjRJsbx;GPH4pr1K(UCO}U0d
ziIvK4EJM2YW&HoPQD&iy_}Vv~*r-LbV1-6Rb`r8G(u-(Us>OP-*no=XsKxNVO&t-W
z6*LfZT%|IlFE(#3gEbcP0sPao6y8jBFKSEf(UaO|6kFQ=Su2#Gbmqrc4#iVo3Jw9g
zN)6_Qvpb`$Xm?2e1O3ju!0e$@B46%+;>s~^1>x5`B5T2Imsf{)+Vptz_C&mrSv1Ga
zpx^%5^qf@?WBLIXP|jN47rXBZh}YT^Bj8iGGZG3ZOH2vCir>8N~MRWdV>0My_dq*%>Hw_n-$}x~XF{mdXtte28Ge-uw
zYxMbkPf1ma#0V&_htlTzvTFv{%p7)csStl1uTUj7UH=Di*V6JV+u9z!Z`Eedp5l0t++hJ82TFY(W@^MIncqx?
zrq~R`uIU;PoDqlldg)N#E>K_HZJQ}hF*{0tf6zY3p+7Ez<6R4qb&(bRzS7s^T1rR^
zdpuFsB*WYj
zuLz4NfyDr^JyXNqCh8#D|Bw4nHuTzMwS=tR=Sx%G>GL6o>91*uJL_dvbnK&CO)jHN)XuVRuwZH<
z8~qi?O>HotXDBZnPrsm}>g=S2Mkis#I-B)_Rvihx7`F8Dh`$F{<}3LVewcU=n2FO2
zrh|87Om&N=dKIw12*V4Co7|w-73$~SGM2mq8&mikW_8jWNJrQB>Idogo%P)YN@J0E
z@YJw3
zSwe!jRKKtVm_YY_p7HyH}E_TuXu*OCD2(k?ZJQ05$UJ9ox
zx23}yBmc;EYS9j!EP^a=9UZ(N;v!z*XN(nax&Swi@WoOEhs*cx<@B(4F$oeNo1)kN
zz}ui8zkmRk>e+(rAADg`D$cB+J>6Ky&-_*i_#{b8VQ&zv(N7%jEUrvM9p4R_TRq#_
zF>5`z$+}t#Ut@*tvL9rKGhsOzmg
z4ZH4e5<2c0xyNJ;{sGB$E{4y++Y&zF%ym>>7H{e9Rf6_;
zqVlgNI)Cb)4(WDj(CjwXPA>|2cB}iusBQnPWtG7i?0wrk_7r~3SO|MMxRlciU5g^)
zvjEHJG@HRDeL_9S8Nvj|_Qr=d^FVUzV-VX!Yn{W0O}#hJgH|uyqw0nu82_YVfOvH4qVxPi1cb-~m;Oae&6Lr>3@)zHcoujN;92E8ZZ
zD-#%Xn+*PQtac?H$o#*yIfl~+Xn%d_nN`o9m0^ZS_*kqr&@kfE>Sw@n%*m143)8nf
zdq&3apt9k%k7$}h>EPuOx&gvNp+_aKe44fWk9pAY(^AO59vE+l<=Zv+=d)&T+tjEr
z^zS>P>XShMQ2}$8b|O0Ck>-vK?aqh-@&=~s8cx^DoENS-q}Wxk5bE9<@~@Ai8tvMD
z0z7?XaSML^{c8EExqJW9-di@*)dOpwxJxPS#f!UJu|m<}?pB=Q?ykk1P0`|3+&0DC
z-5oaW4tKrhp7ZVggqzP<$;!-RGV)~d3E@C?J<79ssu613oeNpuwl8T;?lX$=Kw!mhn)_RDtKyU-F!XD9j~DC1NF`FZ^wtgAV1
z_m!dmUUS|;xY}-UhYYQh$!`>!z`Z~SmQVjr6V~en?EHzow#gdSlq-HE@+7G>`#hXq
z{JtGjSC8;Re;@wlnNxkMtnLrbzg-!@pfRYP(r4Qt@oGRC`O}lR$kaIg1%I
zzPf%-N3I7K
zhfdES47?s|&j2zM^@aV5^Am;iZW5}%^w;zMd>(iYkfsIotqW960H~<1;*7W|V;|Fm
zGV!K0!Gq%z$p_azpCd@hakkpMIFgL&v~<{moZ31u+u_RCXD9LljMOBJsF$jh=F05G
z$w|FAA2UY0lfu%Zegpr(*K*+!`40D^fzJ2BlwRmm&|$6D#9Y8YAaA~&+UP-}_K_6&
z6JwsJB3n>t5s20@A-_m`dG3v-<8JyTDy@@O)jw|6v3S98Gd7J>?a=u|<
zSKkBnRRfd+;$AF;QrPj&7@Uwl++V;fA-2MKU|e__RnPebhJ!q($M5}yuJHhHVn6;L
z7)r_r%xk+at&g|C@|h+TG`D@hEH}XB55fM6(J;>cCMfu%*Lc_bXU~u+_dol#wyi(!
zww`2fJf8h*7ux}dQ%pisy>8QUSQ!3vmZndvYcQFeTE~2{R$oGXVWD0-Rk`W>5WVuZ
zR)9TMmRH(1M^+f;Y6ALX*+=Y*5M_abK7Ijq!1LlLg~cnW1vTz1&^bX^RfRUtU
zo95KQdV+tQPC41-I*21vpf8*jRk?{e4|0r=!OHw@ZGX@c-sN4)NEjP_n2bRxU_>##
zxmUC9Iq$Izd)}Qa`RSqQNSTY{%pXC-6$7(imOF}Ix)cjJ=+b{M<;uq+itKim=qJa!
z6Rw&;`(#oM$mKC~3K>TuG~BZN*$kpEjR=3eQ$aH!(K+Q9>B?G%9yWz7RP&t5zD!Ff-j9>UH^+s
zJNALx#ZYi-d~UZ%^XOpvb~OTBf-)rob`>^z_j-|*HgO1yW2RgPf4v@3S=`t~e!Zem
zNjS9i2ZAbwAG>WRfmC=uP}qm+5Ur3|hY5M?pLf+fYUqRNr`8J{d$zGXcdcd2WB-vU
z;CsK@7j0jk=t0Du47u=E2w(+pVH%9x5ml&7?dTrVn``YI$rGn&H2(PcMX{UY=oUX%oy@1za0}LE;cW~Pdsh*u;)oNY87097
z$haC(rVvi~MbUB20IBUZsX^!_sB8529kamtmnmO9k;6_4>RHc2FCY7NE-b6`G<(Vv
z5ke0r8Tc=a%nS$y*y>F`N;#JyrHhXo+_aNXGh_%Z+j0P|mEsrAVDWK@1op
zDLmQAKH7g1V`)-}p#^LoXg`8Y7LD&!=uNo5kcf^xg?Qx<*DnqM-X0`_`s^h~(U)q)
zzvp0fhFnN?G1|XAX^e>V&BP>?cu~LXPTax*59Oop4%{19ul0
zU{Uly=A0b>{Kl`8uzFE{*@(du0IL@x7$3gY?O?g%7Rl=is*TGcs`eidt{9J?k0z;!GC*uH}(RN
zF{X=AtVl?Jc(Vt906q7K+c%|H+~k#YeM~S2BE-8PF8xNa3xjY;L%y2*xpKyO&NIJM
zy9-f|aMPX#mi(iKCuPbb6h!1ZQ%w8SMUa{f$*vUmz7$(3_G?L*U+G`#P}YA8cy%ej
zuXAqtQfLLK2Jk{Td`J+}$!w%i$#4ZL<_Wo6=7_CH*du%>q-4g=_UPBPeOfUMb0xxz8MaL;pH%%{tpYV|NaN!3*1H0>LO7p&XU~S2%Pv>F`UF6k^z1yd814i
z{Y#|>|AII{TMfsD+YA6gMjc0hw?*_vh!==2rFe?l?_NF~!tKK4jr5XT8v6`jQNX3{
z>s)mc^E8ZS-Pc>by>`~sRkeKup?k&xJBV5M7KS1<`+9Si-)bE*)#oD2PUEAJHkGXF
z4W>)|52L|gDR4ymo9{|sIP4-fe3gEOm-e4MMpvqhcsWQrK(>ZH^Sl?{?z?<%l;}Wj
zEZ}ixvwiaIp)K{<9FUO0cB%ZTSf`Y*QWpNM9(;2<09<`&A93j0=zX9PLv^Hd6mg`#
z{r52q=0KS)JV-;VrJ%CQR!B%z@)hYPd^)j-dK1m3*L1X18cGlegQBw2sAGONCz#7(
zJj2<-%(nGQ+H&sSAKjM2#Jq2+l_k%4J?$#xn%CLuXO63Uh*(UN0l>Lu-X*uh;hg)4
z$7&ed3r}ZgM{~)wEVWdPuKej7P|Jn@9$!hP^egJ|d?f%ec!BfK2DfTJoyGs-xf#Oa
zr?<9g=m>T7#qAVv`Hdm~=RyBZ4xS#63J`-=*C$W)HGPKNw_H4~same$IC+?TWG9}(
zJ}|0qC!CKZxb$`0fr4Kxt%XY%L1@F;bb?L!7vBYbK_$Z}5_|b`m^(G%A691YJ9a`7
zfLwEcb}xstzE&!}&zs+d*FS8_qnU?+m%v#8ns6^?zB)n~o?4SifiK5wPs<2CPE+}#
zHiClnvHYJT`%Oi9U9*3?y$q+hMg4a3xy&OLHD~L$pj6i3nuOCI*jsQB@!AU&Jv%;m
zJFo=V)YMNDxqr_P?*3glROezGYTY4wJno0zu$t|@d==8tk0@@&Ocdg;$mJ}
zX!1NV1S2ed(jxb08S-wg%g)a92@MHW-Sp4KXfE4YM
zi!(oeFXtRCSR@DSh3>)=Yf0GZySt*S`BSOo_Y7I#LP4g!-l`8jQee
z9#JQKW8j*=0lfPe^+)Z}U&4BEN}>#v(m8pY>LCO1w;~FV6#wS}M{0PHq?Hg=rB+!T
z9n7rBPM}EEc~x!wM53T^uj+ME&p4(eV()ye}h6#R>_;vjz{k1X?c4Mbjo?S1=*rK-vb;
zvs?B3r?}8~P_GrBZSerO12151IH(tyht8rZ_@M6vQvGt?RLbR1jj!=jS20+enlgrv
z@Wz%##ZgfrwF6~B&a;j)OBCDAKKG*nCgA*OL(9>>piEuXr&>RU*ub(J&T6bIzAZ-7
zjmwnV|CkIO&g03(P7iQ=EG#Xf9q@Fe-_$Njl#(t*w~Z;r+k=&X(-#V1;Kd$o
zk2D7Rm+@i3mr4M~E#?EcAa{Vfy3heJdE_6%C(A~vX|nzy_un#X3@th&L{`TM=ZxKywGzL4f3q)4~?cssiMRs-P9JX!Pb*{W$j
zkJQGj`d|tyKj`+?N^NfOHcvaMcNXEfOjakh_8PBz#ZWbr$7ESKI6qQCwAl{EKx5Rh
z`fS)To;&jWr^rp0dS;)h(@>=}`UCFW$)`jv3TeRI$XNaNdq@nhzWF!obJ>s6u~!%V
zl8LvtIi#G`MeiNGNc5@moLB!RUpMoqGyW5y@{~t
z65lDREUAMQKLqJa$O*dFNx@}!k)1jK!mt~d*Y__MSGL$@?Ij0JIUX^OeB^TIf44MQ
znpF$xti&ZIncoH#UMmMC{HnRQF()8p-TSY%dX~b$sU#ecW#vGbO6|6iukPB+->eCy
zSIc%3v!Bo9M4V>wQofR&Zcm^4a;=H~+?BXaWodwkCsHGa^71_qqbpOsCcBu4Hv5^J
zW}``=3H_>RRIt`A-F((l!cg@ha7YSV9EFYQ1PN$!&tDJ>L#>B~HNcLA4eXYjq5iDX
z8&jQ-vc$4Y4vc5;`biI3;RxEer-GNtLP`?u$clVWn9LDz?L468eWg6aW7bQK>D@I`22iN9+ses&TzX^qAY`WI#4doE^Xm|sm6gz08>`)Xt
z<|R_Bmsw}(U8l)f`?J7t*)x>mH9>aC@rT@S_eX{mwZB$qN1Zg0aYY~dL%%caGJr8F
zAShh(Q16GWPocnVY{D&Gi^oX^#Pi5*?S~}yd-`loy1uod-Y5)dwu%%-0kFG%Jvr@
z%q3jpF`TpDI{zMuYAddRQ5Qj~AeOkEEgB{Tdy+LyQQy93n@Zgm=?z$+9tVBj!!rVx
z)od!DUzkEDDly$Fhhq<^=x9H}bgJ)WA6(vBJ_<>rN|IEY3yu%8L`%{vOxDK8i9F<_
zR5~B{8UNj&*Gw6E)}KGAtgGK>P&btR9qEnvN%$V^4~_6^7!n|dkE7f7zU5}2%F@Kc
z0Yv^aI-e;wv?dcGmk1*gr)Qr3gxjb0kM)VWX~NO`w;Z7wM<%9~Of?6Xw-NizE~{N^3(vN0
z3em}-t9E_K@P00lZ(~F^`)|mSQM=1uO$M@E|7CwasErcFs$E;e17ZR6xy8n`zfA#0^g8
zS@@!solR3)$^pS*=Vz!0I|zT+aE)$j&NnB=KiErs2L(?IOs*_k4g@K*Mp?-lT27HT
z1Mooo+uT1%;V`T5ye7+HNG66R$Mu)_G;L9NZ5?
z7)6xMkFFB>8cY;O3-#xEpWSDByG&@7*xD=2%qE)XmdI6`>{cRrd8FvFd(Vr`=e(19
zSrM|WHoGjh+ua)l9Qzc#1*>EC{id(|2cxw6P}kLvYLbJcn{sf>T9wJ~Ec18GOenK)
z{uSk7@q=FoZ;){Rx88aDD+Rtt+|A`I`m+!lloQ^>OD*!604DNnqu8Vy!lXdtJe@8NmY4V+!rO$zFG2!w6WSPtshO#CR+65a#aemyh^x8aNGPY->9qP
zOiEsvO)aj}9MS41bJ-3#rb-iiz?Y(=iYQvx?*OsD+E<}V!;~fDUwT+vq;uYLRYu|2
zRA-&1&C%=(Gx|ytZP8+ncvsj=z~qtyO`LwMc&)&WuVe|!`l-=3t@VtXr-d2(^tPvb>6v_;
zy?c|KLs@g0bFu#6VSW2l!na}bvlVNQNIYW(pLyRP{Ix4XuR)G(Ms14_!FC79E+EqD(CYhSk*oa1o=KQJ_0{#^tVo6w(GK|N({$$GIB3zxG&@Fv0tvK>Xb
z%F06}c+g{yF-Dy~LG_ztx9$I1@3V)iy-~ArwJ*<+wm;7`#!TPnVrG$q`*b2;^IOn-
zX=$&{Sc#Utsg`*xmyBi)WnYY?`jCXjbUCA*^+BvDKS4RDsK=`~niH&9B28JAZX)AI
zZGz{)Af4v@IU~Xq&y*zA9L94!9QlHH)L5btotMT$c)s-j>Ye=}N_8|Jyrn4ASWMtB
z{;hYpqG14b0(XeH!>Cf22KW{hZu*TQuQt73vR_5wji>wl*e0rvJEa#U3-g8x~%9-lONj=CaU`@T5!3NK<07aITOjbZ(&Yv%KvO)al#w^StOz*%7ed^9k>YEX=
zdh9*T*QQ$Gpio~hQdGXNZT)B+DBLG9Y&qI&-3`>o`_6{2E>PRNPVDN(wCGUs$1SQq
ziT{VmE8ZFNHo<&CS8U$>-O=yGfTYO1S1lF<7C5h{8yZ-WMGW9bG7gFO!>lWig37B-v+vRCO1>veV0YLal|&{n$9J
z6+wMB*S3=*SF7`pQQKohZLgV(5Ci|^L?_OTXT-M(I`gBGroZ>v%ihd@2(7f~HM$jg
z`YL4t8*6BdKCzASd7xwJtgfChiTY$AaW4PkAF_rPFXP>ymW_wn=?Yke7&?qF4_=TO
zI&OHeBp3V($4J`ax9eftz870wk3y0ppMH1nce@cAP3D2ffwz!`=)n^?%|i#2Hm2+?
z9Tt1p-muxo{h^epPBOzMP{8%&{+s%99Wq}PaEp3*7xKf4{M}zHZha-(B*?yO0_RRX
ziI@NK$45Q{j{>OZE+W2hLRHtsq=?hS5);%)V9pP-L+IA{Y*6sB^jI
zz-zJogvW9cO2c&}19jyq=H4YE#HTD-%N(35^G(H8_CwS+nL5+d?v|ar=r2pH^YWDT
zs=Ap9r&f(_%_k5itD_<6GcVOlTwa{?#OY4pv9Iyc_kPk9oYf2(l~qO9|S=-Fh4DTFQ}n}xsEGjk+u)4ml=fSnkYK%|+>6UO|X3FBEv
z(*rqn+dEC*J4l)DwN5^6nzOp+feYsA1|y~Y>y3NDfZ93rJ=ai9b)Mz5Eri&fHRpoA
ze>~NAxWF&=46RWpK9|Ec!;L^I3O#Z8KlBK``-`NW-oZ3Mqbmw|X{uTv|2!iqWH${M
z7Fv)4gN*^{<0rH6SB>3T6g!rPB|QD@O=6A)Vx8@*_yN3tiTJiM;jb%Fen%v)yp}pB
zlB-9)$7$(nxz!-*t=R1$2d{RsbM&Ga>$=7X@aU?xBDJjs`5VRBw;I
z%ZA(7z~Ae63l-YNIg&TZHdb(*puW4D*uXQ*+PfcgSaxKP+h*e)1i)HYH4#PD3%a+M
zu|pVl)W4rKqinrhdrOR-P^wDQrsXY>E%Kq6+kL-*bmXY%ZXB|vHlFvIV$74Fyo~qs
zoxs||>Yn!&@bX0-iacxEc&3a7Vzn3r8bTo&tKjor9>xjvSum_Gf-VO$Gc&v2MwiHJ
zqc_k(5f2`l(rL_6$Gy7kYv2XHvb4%;SeY-m7O9rJi|>4;x7e!}k4GGV;br{j(BeGx
zkkD2+aa^((_b(k~PNS9$1Qlk!6|8U5Qu2o?JOf(I^N$RL;n`j5Rl6DGvbboPNe1RB
zyhnq>DdJf}YM8M1vb}rQV&eRL<$y;8-Q1cRY%0QLXJGFa5m#8znt2|9%fpFG4QBU^
z5>UGQcxv0;{$KuJ@HpWz3kw*UXav)ELQ0VZ0`!s(#r%s|R5D=*tuu4O{&m^X7x&M@)e7t-&)*
zm&lmHmInftixBbCo+uVE{Kxg3vl`?AMa-CtJZ$Eo&+r3EKxH5dLDQ|+u1WEIXm>KM
z-z0}e_iyXp{A^BT=CroT(WTKYDw%v=P>rH}eb=EkOOL8VHc1*zIuKeEaR45>ZBL=r
zganfRdRG|Pm_-z_H?GBw_oK*&uwQO0)lO-|92*-0_~u1NCX8u=|LfbV>uxi_8u%4&
z<*>J4!)JxQ@|=I0^V*3=qn4i-+taQ~j@;2=>eld53xpkSfKCGQlKaw0-U#ikdjiP5
zS0;9Rm91jC|HlgY+Eo~L%gR2>R4@q0+=E=Ur!12q)A84Tcho7Z@cCFw-o@S#a$*o1
zObzTAN^Cs_v)fFeKHKVU648CJ&euaFYB@U~?XjHCK4Bzol&ZE+k@vw($qJju
z_L>eN&OOxN;yBadTDPn%GW7G*73=LKP%YJA46>YZ{DEiq_3Rt1NndV&=wPt90JGW#
zpLnG=dGMNi&_UMxvJOY&sO8YaXtFR^DF8NyU7e10XUe=R2U9h^HUv99*Rs~tEVZ-h
zle3puqb5<~ym(N`^+xZSPI9Pa*YaC^c7jN&xkB&^=BKDbZQ)}~)
zsp-Ds7M2y}9nLKkAT>Q~Q%Z2nN-*Ky4wg-?5#;x`|N?S4bHc7ad
zEcVjQwyxFM#u^=S32GB1|A4|9*H0Y2A%vo5cwri2;)|^9_*$Siw;kMh$Vfb2uE{|k
z6#}k_I)n5@k4Nj(yX53wHo8Nw3_Y!MZJ=>mBpWmq#jg*DH=XJ@VJqhTO+*X&VX@}i
zG&HdzT=O?vxTneYE&~RGn7;*B7uCmjGn6mu85h8R!gm^R!meHCc)0Y5@TjF>>cn3z
z;?a?Hbce#5-4Va=WE9%0eDVQ6%f_2*ac
z4*Gs?zTG)vS{tAf|7P)ouZ&LQl0zNWJC^2vRl%WJf&&e1k=XI;kX}+-)V{-$^es4jS{Qd(}#673)y3oZu$0W8jBJ0o7TV}4RQdC~Q-6WgXq2*Lo
z@_r|q(?><2%wjO^ZP;J}BbmojUv%7?_h-h`G|OIYz$G!g8DOXMzZJa7Dq
z+kDxRBti)@{9Rbav6+1~(26>VBnw)e@Xr7w5Lyd4Lz{06%wjYHzHTLXh;HCHbN6o3
zs3uE3^>=D1^_sVwBwUDt;k?#=>ZCP7&%l;hfFZssI48!GCpvsC?kG5C^ls{`c3Tg6
zx7KMHWnRAP^vXbGf=vyD5VLZp^P5@xV}*eXQHL{Z6iw85`<@g1xF3UcZTx3q*t5MT
zva&Y&*XR4lDRq8r>(gL2m>XRBnrwo*)N0j3>xHOy7%&4L@t`Sh#T
z<}O7JZxJ_4pIbB^SJ)0bFSHvSTh{p-7+>0%^IK^8PoWeY=TCp3Z3r!62)VzrzWHu|
zVrj5z=S>dF(WK694cCksg`W?~1vQ!8t6XQK{JT^_g0;IgG-fBdd{%$URe{`Iickgv
z$Vs`@9r9jASnZC#b5U!G-(qzI9t@6OX)KteQSa2IMe&EZ-X=(yS?E_1Jm?_zRz{op
zG`4k>kLfqr>!(7hrx4+4i~9)#qesI|UA=u3phN&eR;j$f-=+TF^(CP{ludaIyDGxA
zK;~%oCkI+jA6V9XeKSSlH4|oHrgn@QUYdN_LCv{CWztucX|CR8hI%y
zRk8RBJmkL}3pN6d?_8IQi)mkt67I>KF;j?NuL+|&H=0bJX|y`dzd>Ib}v{eN9PgZ1_x+xYBLC%eNWH^!lQ=Z-UR=XDTJ^UCtvUx=F;lMiTFR
zhUlcrMmtmp!ljE!(;1uBUP*QF~cm8&%Z+O3Wt%|ZrQe?^DlKLia`FDCqm5f-#
zZu+Qx{3%zFVtvF8F^=_?nD4!)@--@KSLHJaA-tJ$>7zroq-{7QGbPNf{do(o704P3
zYe;b8d)wAy+WLmNI{A~{P~p(TpQk?OnBQjGyL1dTmf0fb(}>C0D-V0Zx>
z@vG|}ess~WUr~kre2$KInfpWHew8UsM@i{+vB(y9j|xxD_72xwXmoyy))mA>9%^WP>SuFQ#$&DR3-Tk2jA%FaU}3djmYs}@
zkXe5WgTyZQA9UujBeDuvX?b*}wnfpQWvRYD{DCD_%JT2?zojRlT>pSFaUa-{ags~@
zAj3fhWXL3UnfVna2_MjFt=y5bp4bT5wV-&@CVUo|DgKp>b4Q2
z$y2m1fQ@AB)wb()L5{RM9huabWxtk{Qz!-nh1K*;QcTVBZFHtu!%4AM0s^5j4Imym
z+uu?S)-L`53_BJ<(v@&@K@X6>EkGO!aqX54Rqt)MNy+*=g85l9OEHa}A@NqT`%6um
z(-!o*6ZlrnL5)kY-CV=B7is|}sotj)ByjmBRRf@xzCE@J-fNuIAq`UILwit3Wt~BFE6r!7yy7i$_U2zH_!S)?
z(@8IOkAb*$HJXH5e=I^qz;98XPqFmj4^c~J9mUIKpS#erjg&;MH?W)(Flm73NSfC?
z0T2B)C8a-A8nOVY3*#;&Wuk-Z
zaZjR}o{VxGyR15Vbb5Y?zj?L8Mx+1leQAWp`tA_o-ic1b^**svR^D*~!l~GQVpRgS
z)`s-nrE3WCd13e06mWftm(P=gPIxs5qG|NeI3-Pbdpq3eF?`+nDka%l9uyA!o*s;9
zSAP++%}i;4Tjs#!y47z5sAmT?wfmg3dUx6dLlm@;tx7l3SjC^XSPAVj6ja};s(-p0yx=xeDajq`Q3|ZaE+WE$JZi%atA8{Tv9}Cy;r_=
z->3txRr}s2YYHxKy>iX9mK!K1U^4L8o8+7H|DD0tYjSDHr`Xna%}~{KfV0@!bh4^(
zX9T9e{q1Plz`jqgDZlwWZ#$=&tA#O^5M!4^Y$3rdB@Y`b;YBs*3|7ZujcQ80$^R6)
zvYNT8#eFBt*;a>hYfspK8CFb|ZsDc5%y_)%pW(A|7NAu;>0l4`4|PUntlTriStuXX
zG|A}^;}8^KV@>At~AZ1(>OHe^E|vGhvb2vTL%%
zZ|BuF%Rp4G{s<2I0Gljd^*9#s#E(Dvyq`nd{K|_G6)`XuN@dC>1QRnlMdMx3fXR48
znaBtbZj!(mDx+|92%H>$!Cv63wHwKgF-2@m1JD3ocG6ceR#T|?=L{z=X~XT3sQ%>K
z>PyE>ZmO)5`QcUkAA4pH|MdzshOU#tSZ&&8Q$`h};Q6P1r_HXw7XJ1V&Ur0#1S#rr
ziwUa>ZBR8?j}>4fF&o|OPz@-ehA;h++0B38=Eqo|Z6LtHx`d%Qyz5CW=vu;DZG7=Q
z5MHY-J}T~H&Qh#7`U}GuLf{{eNUus>ovwV{&_6=%lS53d`CSs_i+(dZ(!Rl_Du3sV
zufoq9LMqB&RuYUPj&2>c5^X;Cbi@b5qaEqA4@|ILPL7N-P9&`hb6%2?y{O4~#Bk_o
z>nrWsWfP!TQO|8c{jp<*lZ{%}pnR2=AX7S9hVqOTSI|##yY?3`c*(*qA^SXVZ2LSM
zBOOjwNevn{8&YPIvtxE_52I#mAUSi3VP;A}x+=gemvu_Y%SzZ`tJ0MFh=s-aJ;?so
zXxEh`p2v^A`*F|q>)Wz&FJ8OW!P7G)b+f4WY9B4lrP(9*
zoX`be9kT2sdfj81$Rx5}`&BWkXtSmEN!c6eN_@jnvS9+f5A6qe#ILb_?Os#=7!Q1R
zq<>0D7S@FPL#OF?Lc9nS((A-Lfh~i_di(?V7u&6QgxnzA++ePg_rZvF8zQS@967d
zkPX?}T47I@H7;(#KNWm?62uo2K6)jo8n8btHv26(Wu55Lwa;s?#4T3Rp3UgQrSQ=#
z86bja%s;)2*(V324+6V^4WEr6&BOzDV!zi
zs`q`w-djph(K66wsL~L2A(+uIQ+AEEd6Dwv4+*ccxd+G6F%1QQIoj?0(EObxnzI#v
z=rJbejr^YE-#A9FUwRo;aJPHyK|OHgA5WVmwL`TNsND1jxO}YavfizW;;%m^YvXfr
z2e#J@0|RBKRsSkHobR31rihVCZnU$vD&>5&4pzcz@_EO!Ec-q-*i_q734`}3ApYRO
zZyFqJtpP{_?pKOI&|H(jkL4_0vW2F$y}Gwb2a+GE0`iosm|`{5q$HwSdq(DcbKQ|U
zAOpvYyPx>UtizU+$UPb#>x=^
zLT>e!_NQBX(me0c)mu=s)4`Q1b^VWNKM?fE###>DP=%0%9wALiTIrCJmUhdYR;sn!
zGZZPhXP=@y(xRDSVNwDOx3yi1C9>WeOPO_7Sx5}5>~P-4ay
zc1>u*9$n6!cbc5D7K>BJTp2YMAr5dfTLu(d>BVR|uJw(V?VWvEUuZG25IwNAowi}-
zOpH9lYhVCG7KP>z<;xY_yI#Zd+@5sF^NgY5>FQ6J)`ChkWl#UNC@kT?TGRK5gZnjp
zj*os`ccSb0<`$GvX7lYxA|ocS?$Fo58tr3R`}~nV%B^K35#;oJcZoKygz$UdVPvM#(h9bVps(S_HAe8s(_$GP=N+~`Wbm=hDW|9Yi$F+DXL#9;c97#30
z@rc3AJKx)c38=2yFUtAz%c?QmMoU)H_Q#prj3PHG@yji-exQj})a;y{E6`DI!Fv(j
zf4V0hP9Hk@eKV*m_q0uP36Sk(HJg#GqsDoiEFvB6wahP2KpLa4%c=KV_G|2m`qAL9
z=xEmo^jI=By~+#~mh2NhN;6^l&XkFWDf0jgwz8cF3uQ0^jy;J*%o1G8&6l6{h>9>_
zu!4bn7aSMf6~5iydY{&h$rr+?pg~*DV9^5)`74A}0XnQxwdntJy>d{M4E6cb*F1M6
zX}g6m1?j@pR?#CjHx|W)vs_!%*Uo(Fn!r3_0&a_}>cZXlx8bb`Opx+5qW?F?x$J0r
zxpLeHw8-uwYSU43@YWY3B(I8yV`d*A!gvT25f-5f=kfkWq||lH?47`E7nlWT&5i=r
zMlev^e-kJ-6g@%of&gPQ0+xsFgz;g*-0SR(ly>-T1N>L@fB!{e-!l2|^5%Iubc=X*
zY9G1T8a-p@4OxAAOK7YvVI#7v!7qBH$b{LvRm=k_%w_HDUhF3T+AGOjNk3DVJ0<$@yU(Vx^<%5j-+S-C#q3*vwm=
z_iQ4d^K5|QR($?_Lj6tnlH0YkYCZT_=YFw@h1lSe?+Nwu|hgM>oKUNv>=D>HHbeJxZ5Up^GLNKvdTz
ztxu$du?llXLHD*U*D5J_*H(?n3m1FY7tjJIk?1ePjv)gQ2QZd4=lsCNVW2q-L66th
zoqDo%Nv^gwYaaO)XSR5ueU_U#^m>|8M6)wMp1oWD{`}2`#_*9Wpv`vbRIkAkF242{~Q*-C}X(LYTVG!
z_T+ABC=A(z)hz+Jgx-Xjrb*|*Er>`AVNBvLgRDu*mYS5MRMDs1L
zQ@@-yp5EARi22(v+B>iwt&fIa`CHLxQ$Kuds8)g*spy1?1g7%?a=pP(nWf77ozh2O|e`n6qI{G`QZ%h?^Jx9Vt?l2_HyG78?DCEdQSo0?SA=
zT7|!>+;OB&K+{MFkyPv0C|NJHTmzABx=Nk!hzOjIq#r5%8%+glF;+HUi1&haf%IJ%
zPGS=3sz6zy7Ze
zHP8n;&^w?Y`hn+pa1^gyBt@1cbD=`54{$2GRfB+40No=(AXH+o_)rVb>Oj)>6buVy
zwkImFa#edC1w8$!@BiCvaCUa~y8*u!QJ77@1Z+1<2QDffcn$CQi=p&!BkE{R6`*_l|&^QGO=iH2nrnwg2HI1-06SmOWcIObHYSo_4>MZza$WR!RHh
zJUs2ejYYRnK82c+QX=kuxgwzkM4iw~i2{_M$zkze3!n}0SS*K_^nI}&3{fWtPn?n<
zN80rku?&D86UIez_#Y`GLo&8JA1>j+ydwnru+D)W*hv3SBsDWa!vwthij2bx1kxH2
zUJ#|G)ws1ppW5j(=t1LSVJ$`f@03@a)(1Sv4>5#R#v$y*L>}1yR0Y2VSxfYy0rx@F
zX6cu_WE(E9<^SK7z=RY^MJ2HnmPh$NjQ@|T|9|`cpuqFZJ2Yn+bcKa6A2SrtzDX%c
JR*4%0{XfJV4qE^K

literal 0
HcmV?d00001


From 47c06fdae2cea91a033b491b769061160e84ccfa Mon Sep 17 00:00:00 2001
From: Dan <14043624+delivrance@users.noreply.github.com>
Date: Thu, 23 May 2019 18:59:29 +0200
Subject: [PATCH 082/202] Docs revamp. Part 7

---
 README.md                                     |   9 -
 docs/source/_images/logo.png                  | Bin 13344 -> 0 bytes
 docs/source/api/client.rst                    |   2 +-
 docs/source/api/decorators.rst                |   2 +
 docs/source/conf.py                           | 214 ++++--------------
 docs/source/{meta => }/faq.rst                | 104 +++++----
 docs/source/{meta => }/glossary.rst           |  22 +-
 docs/source/index.rst                         |  68 +++---
 docs/source/intro/install.rst                 |   4 +-
 docs/source/intro/setup.rst                   |   2 +-
 docs/source/meta/support-pyrogram.rst         |   2 -
 docs/source/{meta => }/powered-by.rst         |   4 +-
 docs/source/{meta => }/releases.rst           |   0
 docs/source/start/auth.rst                    |   4 +-
 docs/source/support-pyrogram.rst              |  26 +++
 docs/source/topics/mtproto-vs-botapi.rst      | 106 ++++++---
 docs/source/topics/serialize.rst              |  55 +++++
 docs/source/topics/session-settings.rst       |   2 +-
 docs/source/topics/tgcrypto.rst               |   4 +-
 pyrogram/client/client.py                     |   8 +-
 .../types/messages_and_media/message.py       |   2 +-
 setup.py                                      |   1 +
 22 files changed, 327 insertions(+), 314 deletions(-)
 delete mode 100644 docs/source/_images/logo.png
 rename docs/source/{meta => }/faq.rst (76%)
 rename docs/source/{meta => }/glossary.rst (83%)
 delete mode 100644 docs/source/meta/support-pyrogram.rst
 rename docs/source/{meta => }/powered-by.rst (95%)
 rename docs/source/{meta => }/releases.rst (100%)
 create mode 100644 docs/source/support-pyrogram.rst
 create mode 100644 docs/source/topics/serialize.rst

diff --git a/README.md b/README.md
index 017b513b..4e758b5a 100644
--- a/README.md
+++ b/README.md
@@ -16,15 +16,6 @@
     
         Community
     
-    
- - Schema Layer - - - TgCrypto Version -

## Pyrogram diff --git a/docs/source/_images/logo.png b/docs/source/_images/logo.png deleted file mode 100644 index 1f06fa81657108d18dd969b30709f49e8f1f3a2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13344 zcmbWe1zR0W(>02_yE_4b!zQ={hoHfOyIXMA1b27$;O_1g*tom92mR)L-d}J|?Q7de zPjydMtyR@EVM+>8s7ORe5D*ZkGScGTAs`?NfZzTIaKLBr3fvO#1!we4N*vc%zc-{PeTF-*5#CuwUIKm_1p@)Zaz5sk1_40XpHn**-^Wa^ z3tkG!{|{1|l80kdV3orcc2nIYey&1?N;jkTYd08C;?GUJ{whU@oG2ji$`@frt+({T z`|MVSJ{NL3wtler?JGnqzKQjlEj2pIdlNF!fN+epnmNroTvGL8-rh;-fL&CB}pA+JJ>0J3&f(}*c(;z!l7z_wa0YqbdNw;cb z0{u5_Hp~o#)dzH|oaa9LaaK)*b8yMXa$+nXCO8-k6@1E~?6rLl7)DVae|&CQkjJLo z6{d>+uN4EOs%)DAaUl$*i);_t74kCRfObf$57)pyF zU;k*7X1R4_YW?3{Eh?Q?%NR72&fbfTriU=&YF6PFHQstGK;k3o#5>*+B0HzfmrxsT zg}9{@D*x}IXSu=kEgyR#9p~9A-9ElpBIm+WarI39-H=gwY>w}6Cfd-~(J7E)iay_` z>i+K>xx|ctcgQ(qy_csM#YH}}#%W)*sfPdUqwW^(JMx!4cYgPcSNB~}`B_X$0|?5NPP2N=`><;NEAk>@NP_eZ&gN*GW~r`{jIO<14Pv3@9UR zn1995DI`=uNH-%)mn8K}Dt{g8R_K=XpQ3Y-o}co&v)sL>LJ@kxa%S_!C<#ZuK!4jDWTlri4=862W6$D z&l2bfICb9y)!vdGev>YR#jgv|f9_-WJjB2}h$vM@S8~I!zpwvftgD|<+Fqg-+=nEq zsf@MhYhR($3Uv58=NKZRYtsfW9A{J+dy3|CvfnuK6q~U(x{|I+RuSeG^PGn`sEe{H zy4T^uLO=96Ceawfsludzsct37E7ISY;LtZ%KHK3@$x6pJ9AJUt)dP{a^Bo~%y}PJr zGkMr|Zo0Ba>Bp^OqHYsPk?n9)S7$3O?2e-- zDr#`EE$y5V>w{qX?bZrDOY}oySleD_rB0KDHdP@;+_?Jx?989w=QS~Cts+NOz*XIq zi(pLSw zjz`ylcIp(!9uBa`{2i46o&!4@mIb^k1UbZbfLlP8NQo(t36cIsHHhfOBionJ@ns8b z9CU_LdGuq8U!<)=DXK@Z2ZF3YZg;X!-8AjDH$N~VA9OjaTC7P-HU1QDPqCxVEdNwi z$k^iHd4n@RC+lcGX2D7O?t8I%i9ah|ntpLQ$Mi>}?@bb#ZGt1JrTn0q#>GfL=dX-i5&!W@)2}Pe zzg3zpM7R_SiwTJWPX_;`EZx`T`?q+Yi6!%q((Puu@ciHWb02y2`v)Bl92+w3tLilg z$$ta|3pQWJTD0u5g)YvTr~kU9p>BToUZ^Pi(XKu1IO6VV+dHEwB)Br&5;PDInIuA3 z%eQ)t=s|#J{2m_<7#5mKh_^uDdv5{ZO=WZ0M}cd_?95YVr&OmQ7WG4j(skVaVMp!J z`fUl;i3VT8`R=53rn~o2mC?)*{F@XhyV*(B$H{~SSRf>bwg+Y=%qiYe&+gC>-l4^m zNdCqJm>EY2>B{T38f}42!i|3Y=Tfi6)mWJRSriRE#Ij!6Hrw3h9L5(|E8Moe)JdTb zXH!%C>5D(2?6dSdOuN#}(jA#&=>TSC_?v3gdrtOGpHQGL2HV5V)e z3pEI5P^}i_0|-)di9T+fjaSFkB*V}2An=G`^?*DPnca{n86ZPP9Kt#wwfyTKt8!C!%D&=%tQ zIcxad^Q*eDbVF12-#WwH6ONEU$*IkZw}Et0?Lo6X)pnAc8ADO z-t9*emB6Y@bV2k2&!_GCdl%=&mt}&%pbUsai^3l?*;xtFBy$~2X6O9oihm)SI(#*z zh*GG|@I%X*yc+zFufAO2Z++TA?-5wLE&a`u;a1^o3e44?0V0p{_mA?1Bbh~@HQob4 zK5a$D39^u;MBTS-$kC53$D3_b1py(=t5pT(zqz}ooBH?9WyDU412ai#^x-#LTkLV` z!H2|4P~L;o`KhKv3iwfsC^(SAkWK+|qEwBV#q1(oUjTmwTS3UR#+|e@P#vs8WyM=* z;6=iq*Rl$MBjL9bGPW~0$(k&`V76Bm#x+0Q8x$Bk`>P$N`hDc z{`7K0<@NYM7H`g|aQU=&+X7ucN{$>mV9IkJHEwPviu<0s?viV4BD@nJ=chW3o4IF3tBm`5ZWTBb+>6tvSuA}C1P2IO{jZNq4tpYN=)QW{B zgxS;hdf5}7dcXKoCh!y7Rh>63px-kS;rwO+=iNkzWlPD4CKjnM)6>RpYA^TF&W|9K zQ0~T#lHmRdpJUCifmqw>H?QM(M#a$o#=X^|(gLdU05Uww(Y*jM!NvdM`dR=0_OL#x z0?HKPxwqpbG0O@+G5Yb74UMSxm3!6%zYmgOA$wX;+QFFT%E_?d7>m`0{p4M}wVrl- zIpnt5eCQRt-ccS{aW8%d^4;S9;qH;P$=nqqH>`5$bwPI^nA=lZ;HYRtqw4&D`aa%% zU2f#VVIU*D%Kb1itYpgF`Fi6-&8yakA6>3u(j zF1N1PmAVhhmXyU$n$&8`dkrRje6rYHj4>Ht5I#b{#}`hPna|?SxbQtiVXoVHwe%`5 zmrr5c!23oYT>s~g`X3+QrtcU4KWa~e`lukJV_DJNYVWKPFq?OHe|N0x=P^whnV;W2 zTgY^Yr$FUM(d6?u(ds3^zk-;{BinRx+|<>TYI-Js81_K{G~&c$>VzjIwTtRAB!G|f z(S8>H>-1Fb-SKizG!M09S<#1jWA^7L|Di&92fk-BcF&YA%gPHIVp3`PJ1t?kwCIj- zXyjOxj#$6g@F@)+%Nen*b8g|8q<I&iyZM*BVTU z4ty+HyueR;63Lpe$DaUb%#VqWt041XYo5MiTe&Q%8&B?BbJ$F5kieC26qT6a=JZKi zU-o$RN+EF?nd5&?a^sMt|A?zvHtqQ?GC28@QQ3e%O^X&jFGF4x%NRC_p+IHGQJ+id zg{t5;e02Wy!;Epwu2s%aRz3)e<(W@pnWQ#!HE-6J)ubwzx50kn#yi_<878*o){N6- zwv$QFg6&xEFP0iO-y!|103-P4&bnUM? zfGpqV%k$Ug`DHVXy#D-T?=ENvv-okre4cEXYxOLy28OTFdU(I^Q6S8jI~xNGnb+tH zMq>W1+Ko#pVj^k8z08;{Um=y`==q+uN&ZFdb z-2V19DXF_{Ym2n{tw&O>NtC}9}1hj+gWQzDIu^mqN9v=+xVA-E=JTipc@0s=IWi^lWMYwo^4|KWJZ z2#^!&8T}|BDw8dBGPjp5!rk+%JaO5OQ%?lV3rn^o{9Cw-S38CN+=05enZQfONEM&0 zCiYuDQQ`7nrNUVB4tzr0J!6U^r(`P)-=c`%aq94`>q**V7D?XsDqaf66JnD zx@?hdFrxskdNafEHo6jK<8DXz*{6Hef8IaohOEd)*dTLpv0s2g1!Bm8&wBlu0Noq= zDW7`-(LSLKR};Adxx*lBsO{n=&P6Nd5W*Z<%H!?wYNY|s9o~I`BWk`?)2)l8mkZ}jW%==ocg6d=B}%L6#JKICi#g|Y%I(u5evHG})C6aA$jkl9%$fP( zTEoG^IKj)hmy^6?PQBc26n}|&aJ5bya~wPeA4ba}_H%yA3P;qcI80Odv33Ab&ZIDa z*->O^f3BpJVXXZ>kAsZLi-jS)`Q`tuGJ`Ru)OE^^Rs9~~a}WgLzi!66!?h4t)X4QC zQjKm~*ivyFgqyrj^=S1>_CP{*M_Dt02^J-e-k^B~rAX6}HLcd9q~9&kE``zifoEVM5Bi?h8z>9L$+MzD}L` zM~02itw7XKQso@MzY_UXCF4tIqZ|qofB7Z@$z(E|MKGs9}LWFT!Y5)WB8H| zd%)YNC~~eU)?_u3m&0_L^Qwd{dVvEi}!tbTisZnM9Qgyj+2 zO158YYm93lk*6|#>SVXAVJZpwvP@R>Zgv(1smikw>z0+!(kKR5-IlQ%q_x{zHa`*a ztAX`^0YeeBi+c*C6?%}ntU~M)g&e& zWCPT+>+Pf8^PfY_X;r$wPvfBXjsD+hwxqxrnjbYJ4DZ#kF3Eec|nF|*FJrMD849OXGLris6!XbD|~?3F|@DxyVbo~_jH z>GRG+cj=J;x^Q_=w(95)gl0JAS}_haYU7|E0&2QAFOaxg^O7s;`61tY=GF%%w%3k# z+Y@{cf&i{6j5`zhUHaycH~seO##F=H<&XM<5t)q_gqP~epL{o zw7>p+6KW`c&FNfI(>%E0xd?E`g+X~m+6r~t1ta3C%KKsPa1GxIEpZ}BNVpZBz>rp~ zNT-|n#`W6qV6SbAoBIaWl%6dkF%eYWAKh~?C}JJMO|y%dbiNRVa2Pm4oM(ie7REE% zK@nj4DJ zkRzD4x^w<6;aC)^HM(lrxaB!l)Nf^Pe(d9xlCtde6`l18r{{UT!jmAOywIT)Z?T?% z6lJYGLOYoUPeHIVnLJh5@ETmFpfP z<>^&hADO*(2S;{_jMoJ|ayZNWTE(?<)H7Y71*-Do4GZ4FF(x?n!i`(MDPa^cM2G9x z6r{$8B3ve>WF-(n>WV#vU7sbM(Rp_M*58UrZlAGsqG2$nQoWMhD1Z2t7sp`YWI75t z?OvcRK3+ZM`sAEqhb@(F44d$l7i)atD%HFCQuVk=GY;yqPaEO_-2Bk}#WUPSCp-C5 zJ^n9I6KqGCt6k8b5JXq_E{=AwBfz9NnZP_tw_E93wx1V}nrv-T?(2{@e3Hy`Qr;-8 zEA$pBgIabcQG0rmEh8Tfj`));QI1U~UFfu>o?B89$iK!BXOf818ktM_2^~0`iT8T2 z&DyuU5A`%Cf5&Yq9)$UQ;x@Yf0qSqUadq9@dGaI4&BrzcaY2%NtF6+OS(h;&w zy&^}{{|p$VkVDzD%bs;EKL`)k?U(3Bej;*x|6&H;->zVO81|0{YtXT-@gpMrnD0Bx zkwTB6MJcwbJieBbM0W9C;te$}(iJSh^9yJi&%;Nk^qp3+xVzu>@~Ir8{4<=En#G2@ zo5_AZ>~~KZS+k6#nAxZ$j$Fkk+Cd~Uobxe~Q5kKvq58< z=ZI2pV@bYbkKTBF{aPa^O6Fx{ic2p`oHnen7QK`;;QU0eSe9qFIEybvQC0;;`hDK4 zFaC!wkB`|)i~ajrUhS!918bBK_rnHRN#{NMDof5oYdAk%&H30JL&|5nckZ!+m~LV> z9x6=qgR$rYX}QtGD;}+2rAOC$Dib_o#gq$cZ-Me~P&8KdiyQm#j%+OligUaj#rA-#T-gS&bA$r|kFc zd9Iwc2-ad5Uv@n+0=%@iJm?DPD7oRey_M`+))a$)NE5|z@sN@SrPk9mt9z38CA(&b zBWl>GhDqX}w;Jz-!vXHXC;QD&Y|GpK)TAzt8%yTjS$<-cAE%OK+K~5*1=L15e!wOh zOO((FDPZ!8%-~Yu-9g{GK1|)6+q7;tGtJ`KgZghZQh?FubRaKK3H*FYJ-Z|d<7112 zsL{sdOO^<&j56R3ew~k%8Q(z)QxqFemkg~$-5u~*FkDqGsdDXIh!|RLzMmakUqKcP zA$j;$i689|_wYbYFXA+Tm}t%YdL7f+Cf9Om+vevfF_SsCx|8O;2^NPd!Bm%dEe%O| zxfCK}_z5AvIC*H@aV6ZDbiIqfHpvl140L}LAYT9?HOlRJ+Lw6P+o!k)9tJRi=Qd5! zhT>6J;KMUSaLpe7c0m?)H@j#@Czp(nJk1z=SfmZ%Gl5fq9uwJT>j8N&2ZJV4BGCh} zaS+NHLGXMJ-~xqI83+4UO4C_RDo?qkQjgw-cA3F!38$8o)E?%W5!sjWSj5U`4$)E>=b#4H3>qLu*Kb zYi_~rcRoIrbr7wfyA0YcenmMVvZm$yP@5?JsDvZrm{wU zOV(t|C)s+Nv?1%Br$UiSg$mV18O?*bLIX6fj6!Wk)^Et2??S`hf;*Zti?7v*nC-fH z;0g&_x>BwIO4m_bg@=8er=+FWl=qa3LHdo#nJETKoA^@~L*#ny)&LGdK)gWI(M^Fn z=%|5_#!75J7zJCKG;jBfz7`h~>z=m;c4!y+$U^wn!UD3Ty)c}YTY_C*KrpEdhNgt_ z*iYU7B)PE93X(sR#}st;)Sp>ZZNE1kk|tYvr-RJHF3$SaNtBCX!GxB2`5Ledk)(lv zSG`RAX>!;UH!-7Ia?`++X^DoV;`tNOofCUe39)eKAKD`rf!LP_?~u|17mPC0GW^&_ zozLC_-I5*f@$gj~?OoJ`H*l{AA+n#U_b_hg&p%3!;8Zi5m`5QH5)bK?b8rnY1l?Zt zGEXi}!1uk}V4V{u8#mU22F9wNrG>916|kmZ3jFRICpI<{E}^&j0xMmc)-^t0XZaGc zQcQP4m3&w^8XuSo0Cc3Ad;Eek-oL`oRkLq?jBh6;*_2jYtW*WfrlKrvOID$Yj;LuD z&m@oLR_w0V@D;kDNMD$7W^I~dw2Si>!ZUNOXM#f0n>qYPmcrAEvnLAZm4HY9YLQ|8 zo7UX!q8vVY>0AC|kGSirYZuMWD|F?K9|Ub}W|^@v}uh;y`3BaXxPR zvGk@MVS&?MEn8&zcPPm#>?>+yBuOSSB-$k24Gg;sVHl2U=>{d8eygr z*1hW>cSZU}mDO`4VrGIEy)nR$=Ab1w=RcM?qAsJd*m$$}VgP~_>NS54 zq~lx{F{sGOd{|J!!VmUGEM-xxqX1?mhT#-8{RyeV0uOspHAqhSzWYsRdmUnypwLfSdP>qz_iN;e)YlGJ3WNbBvYf~_UIzcGHo}${WO4d@1r<#N8JMdu8;PF={p@6NKO4g)3OMfl>-&v zJvh!a(?Zcv`TK^DWvWnJ=1qn_#?w+0lK2yA*kIZ59p!_>?*MAkK1C!hnqFG<&;au! zU31K-Cco*TbrBfhVv}L=TA!^q*Ml_<8yo~XZkqVzDYQ1>HP!Bm^KCPt2cAyA9Y4AF zUS%FwpbnolU(pe|SRME0N0xz#;~{fKIRWAF6yAd&4T;71L{v`ip7whyLo+g~Lx&jv zD6gKWT8wUKYrcnK5yT0v(*=HC5PtEbWl!oc_sl|R^WnDs@qPnnd~r)VX@4Hn=C~=70;D40i~-{rY5+oN)_2o7&vHLv<>Jn9rS(L}X-NUd*x-=J&0FtX3_~ zJc|Yi<-|-6@GsmD|E!OTX1U!bxkmJu9zDqk0c^8r=$*^^@9%cwAU-6Uf1zXuW~UpM z2#N08Vs&e*<^|xjO!~r6S<3tz%49BAA+{NgsIp|s4z)6Q=3u)es0dnd^58AO0teI= zdLm;q+v~NfUs#CUN#G&))iYrrBWvEEp5zFdO)ZAHb3JrWh!Bq8l}%Zc`|gMA@Gta} zq5xBdsko;fIEx{d z=eHM{5Q@yHx&cA+Xy{d^MEzTasqay#7RJ8bP^uiuLNt*u<^YS3H^M-B7!?H;*E9Vl zs*{7j@{IXZd?$z~WQ$e?rv_tfW<7KMk5+4QJJk*g*>MDG7zUx*TB8G39>xn6j)8TA zyms_dxDrlZ5iM`jIgZG<@Ich$eM9;2AFdSGM(9qk)OAJ2=J4J3159qv_>HKxWM$w! zs4rLjnYz%WLfv0;wm&J^(%DUj`llIZU&INsP&dnQ+)nZN3sfpHFTZn{ z8YFLSxp3;R7*wf_Y75D14?8vnvu(XAzrgu$_q2aL-;zYKE0jdZgV_jqX=&Zg7{&J> z$hlYc=5j0Pa}vpXrBxKlf2$tKLoe=YHSojP&284tUGo_a$&Jk;gvQSp>a|^DD};0> z8N>2wPkz6XK{tJhbhH$@Y>+D`p(mo!Qtj_K@I zV;PYi;LY9m5Pd zKl^eSl)zBZxyEuRvO{6eVD3wZOakyrlW~yVIEQE>Iar#R!fNGwRN|SohMyBe8J^iF zUVpax=~Wl$HOiEw?~vpUkGzu9ohJ&9De$Kn_=95Oa(~pnDFv=ZReZXFW8)lv1$_rW zn&F1#w$~AbZav$t^UK1y=KJB!^%aFX=+(mv45QX{MI!&c1}LW6y1MRdtb$Z^R4X^{ zCZ3BlvJ%m?2V<-JnkJH>O^NOSVgY1u59TIHJfig+beoEC$0v9i146Z(R7ttnS4r1( z$W0a1xZbcXQN+YUlef({&k@HvK-hxYF66c^(dH}?6!a`TyP=!)W9kmil$F^H_A{4K zU>gx7t~Ziijrou-hcIQ65r5ts{HKxO^DO@vHT(@?thQz>wYJ%T@^&ha*UiXEh!ysV zRN=Wn_GfVGz;RzUoUZ-?YacfpODa?gbG>J&d!6rQ&Y%*CFh(V+)gHESQvXU0z}68` zW4W{F#~sMUhbwAp&EFlzAIsnuKpAIY2i3TI2-xaV+JvCQgIvO`n1bq33qsM22xhPe zy)L#*d&q+*n(Ug=4D+}$$i!ey5n=B-EHL^+pCtbL+c+esqMtgL+G!`|&lJM_xwHEz z<2M?=aN1`aT0BC5qo^VcKZdJvF%hFjy#dF}TaFQmbXFPx(Hmrbh{|#uB?xoxuYai% zh;o97Ve!h-g~mDETo~^JM2{v>Tmh)oh5<1N%b@r7SgC=hPkzzFK?d;TtKJvnD<7JTo4z;bTN-W(hOb_I70YbN>Q0o2o82if7pS8*kBiN!x-FsqI2>I5 zTnLdrnzE?O^=AJxja&~q^5B{mdUcY5O6c*JovtST0sr3dE*sFSCNE6t-gMgF*>_da z6G_&!iMU2j(D`bqGmNL42zje2uMe#gk+D7p7Y$bhUmSWik)(8lY^^~^RSc=DvRT8# zEs;;Oqg7s<0|aE7?XeERTeS8h;%ZsGA|srqy6_!h#7?U6Zr=}?f7OJ;EZQg;yU-us z;)V%S2SbSeVMR|WAoIjGSkEXapI^;by+1$;frkGT_B%JW=^z}+#TIQ<8*9nKCKW5J zW;2XVXQIB>tE0{Fs4eUAHsI1Ey%uyx4CPJ_<#+S1Q5z~$jIJ(-LqBuoIl;}r4j^IF4cXPJP0y&Sb|pOE5+sTCtxgl0ov_LY9%G#+h1oK=y+Z?{Ii zE4QzY3~Jz>q6D*RDw=;1^wDhUlc7KvfA z3uC`-T0wY^F3LGp8aTU6-SsCJXJrSC%f*q%Na1U2+>WIf`K4S<5kt2)Om47Pb7cF? z#ae72n0gz3d;cE;D00F1OUtJL523CFyR;!@533ymiu9SUr0{zzzF ze=k;RA-lDP4I&Vb5-$;7IU7WJMR<~mPQ2Urg2L%zVMN74FGdB${r&f5u#^6v%j{DK zw=lfP)!N5}WP*V1{9Oc)hm@bc+iz(d`u@w4FBD@TApcoHBz>u;Q&bXpDr=wte)E+^ z6{nN&U$Y_+_MeIf@a*y4;MZI_8@nbg4e}C(Cbt!KgSl;P79QcJk*@VjT$jOLKxCK6 z+H9*l=WQ0=GCI5nBq?>%JoE)L^pwYYu52bUPSvYrv#$jLyS=2+a!Gj>{eFHuBnh0> zR?U&@A*a-w#_0V?2%m93rK-;qyJ$pog>m(n4Isay42Jn|aCebnFymPSe{X+prBmO2 zljO|N9BRiWl^DG;>{b@d)6KYVIoJENz7(6waPZE%7>w~fmlKkI#b#k)$kL)YNS<*Y zT4H~HGyUgF_len*E|&Xxpcef_ty~cME^33covcD?beSuIG6(|%ue z7!j9OBn1EC59D0r+BwJ`8!Dqn3l~)-D6eWd7uKx$QD&SbNotq8&>8ltr55h+vMX#E zRykomRc{CsEL@Vg>s2;BO?X86RnwoN4_M_k9x8}9{1qPI=}h|8Flcrk%|i~NSz56H z&uz!nQ2uEdD5CfJWG(Zqe?3Ms-Z)HpvSRav>r-i2M12)YT)lvJS13JBeuL4|qS@=d zpx3PYG@Lf~-Co0A?5c+ge;ld{TzV&Ek!ilaQp?k@^ItC`%?ixFBYmbcrDFr4wW8(J zud4ENaSmOgp3P^@(h&6y)4_FubO^isrmN!;dwzQ5Zmm}OQfzTUm;I>qwBdLdzuW5tcxQAPG2}hO~l3v(__GbOKh$+)C}6 z|Ftmmrmyf+2u0QRQkS;5h76&FEGSr<2Nx@Z{6-5=)V2|_YbY!GR%7LriF%LN)U*T| zB-wG@E?kI0A#xsyLuc0Me!A%~AwriU-?mKeA{7hwE55a3}9wz%q?K$VbV!0xqvg%x~dNh-r(jwn_S;vl)I>grzu5aS?q$PyDy z$pRgxp9GH6tp3(@YxHv-#J}VUqM9L6fZR5r5hBfQ4`Z}3I>4oLBPE1GCZ+DbFMbtz zah6rg!1r`3JeJ&GG(X4XfYNm61%1+ckydfu>S3UlUCGTw%88TKE)lcMm`px^A?K!D zYT=w3%5oH1Ni%R#2|Ta-5=Hu@Hn=_mPmRrir0?zd?d_<$GWFvE7M$ifeHx(VGn!u+ zi7=RtIP4aKTQ~l>jhlUws~^V5Y|cAbn0kc&hs@XQB8MC(rib=6f8>DcWXlFPi9{g7 z%BQV!ftX$-wBiH_gfSYQNGa?1UZYpqLDa(h|CY;((MQenfc4%3+ay3=)xyA7`$f@a%^_OZT;S4X5gX))9yuOhHV%3i|C-~5 zNTCL%gG%w(YY@KpCsNi-dDi1{{q~o7U)UZ0x6{u!-utfT@?#Z8YC%;GRx^zKH#XH^7kKAt;y3sBMnE3^t)1VE?60i!?u0?KTd>N=r){Ej0ht5TbW4ww=M3a2!AOW+HELcR~@18Y1Yn zS!l2EZ{2r7vJ^_AY*ckkaPr>MT;T&N8YW89B)VlWN;pKFDRjNrwJ$jK8riReaC0Sa ziKtk+pA-!5!;40*5xhicxs-}_8ymqKsO=S7)3`%c30lToIV)9jUzSBW+8=R}=26Zl-uQEszJZN9W$jm190=&Nypf}4I>pEB$AxS8QF9|M{oL6SpQ4f(T^M>8e zk1KI?j?mg4LMX*oU7V-c&~&tsTrNLc$d<+H)Rzf|?X5YN(e3zT)1a1QG;XeUEa~=# z7xAzaF6(9*ImJU}tWLbVLJGEmSR z_D8!j&>OR-3j$b2m!c4qwl@L&s2CgJtcpEkXnmkT65;&e@U9AgTA#MLMe|TbdROzM zrT9!TCAc`srmEI;%KPlC=d|0+6E=l;rRnrhh^hr`u+w}FyJ`DC&njO0uld0p6HLBU zAvltTrmegu!0=#=w&QV9i{!S!!^Nb>fBeyk=QmKe8XOUxoD?mvV5(Yyb@{mR;_lE> z!3WfU>Ij{`Hn9avwTq+lxb+9jA4e_t+-Kx0%$?1wY3HIdM|C^f{hy}Nn_p{T4_hB+ ziZ}k%>97ZaqBDY-)}PyC(A0cmiQLua(cn^xte&IFi|vO{Rh+QwGI=m3rT6Uq!ttK` zSBdqlnh()`d0Hz4T~&&-P@GyD$ww*Q)Kr+Iia^K|7)?feeMcxxa&0P&@DaQAy3fZ{ z9f5Z;OMKGgHY!vU%%wx9VPO6FyUqT;3Tw{y!iLjx2=GN^-@Z=BHOoeKh<}ZnN#tL9 z{qe1eC!oyF+XZ|_cR)sPtp99FOH{^41J1%i!~Pt;q2jqUA{PC=8oo(-|F<2jr=eXh zu0q@$BdJD;Z5LLy8c0BOk~FOK^LKlZJyM-MI$oaMnH2NzOul`At;G~#qZ{FpB)G{{%C#g7Eb%Pkou|h zwCdv3&FC;qA|7<-qaCfMM@dv)gQYZNk>L3(5UDvrSavUq^NH}>lbYp~%lfh_aNJ)@ zk>x|88(NACk5u3&SjqAF)PtIKm=Y)IixeDM3kRRY){${eb(-LD^R$h=&p2%+LyWEu zW?b`W7sjJxmqo)_Gc#DT98dG2$cH5V5mpj{b0K})^ZC_g4MVWg5MC)oK2SXDLjWgH zs<-Zgw=uu0_yDQBV3&r(yuor zSP?AzENfksPL89H@R5=83)vYK)*tZ+(i09?LirnvNZax8q_Q-x(+)DDYwk|teGVV9 z4_YzAwI*>%-2yp?i<3ze6i$#Dk;H-T0$V7(_jfMiATs4)HN#3h7I=0=A|?kCI~q%6 zreW0Vl|bSi(21pZ5!B{96Sy>)nsw%I6v1Hd{*dGPQ1R@6dv{oWx%$3e9-eMxH6(y@ zE{sn0EE+A*A=N=9?3_m-2rKN2p6ExD>GPYt?BeVza%Wu2F>!QHXTsN@s-3$cO$YY#s`!m?wbDEXGu2 zO3U9P@or&tVZ@73P}W`=JMW7FP#utg!+OMz8{vT6rCS}nNDEZjP6Flg`5Ke-$8VYe z8Bn6*qHxYTZ8skyKuoiLB>TVJq6lP|v?}(eEm{IOw_5U~S7KXA27hR%5X%UGN?n*D zc3en(h-fIuZLM{pi1gkGJTF?3Jrb;403-BOKY`X2Dy!hc6c&g_;eiOO18 sS%oC3KFoeo0ICH4e~MAg;0H8R!JP_dagqsmmIp#cLP5Mr)FANx0Ysb^=Kufz diff --git a/docs/source/api/client.rst b/docs/source/api/client.rst index 01e3f5f8..9527ca73 100644 --- a/docs/source/api/client.rst +++ b/docs/source/api/client.rst @@ -1,7 +1,7 @@ Pyrogram Client =============== -This class exposes high-level methods for an easy access to the API. +This is the Client class. It exposes high-level methods for an easy access to the API. .. code-block:: python :emphasize-lines: 1-3 diff --git a/docs/source/api/decorators.rst b/docs/source/api/decorators.rst index 26bd64e1..be8376f5 100644 --- a/docs/source/api/decorators.rst +++ b/docs/source/api/decorators.rst @@ -34,6 +34,7 @@ of your functions. on_inline_query on_deleted_messages on_user_status + on_poll on_disconnect on_raw_update @@ -42,5 +43,6 @@ of your functions. .. automethod:: pyrogram.Client.on_inline_query() .. automethod:: pyrogram.Client.on_deleted_messages() .. automethod:: pyrogram.Client.on_user_status() +.. automethod:: pyrogram.Client.on_poll() .. automethod:: pyrogram.Client.on_disconnect() .. automethod:: pyrogram.Client.on_raw_update() \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 5f073186..e079ec68 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,200 +1,68 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2019 Dan Tès # -# Pyrogram documentation build configuration file, created by -# sphinx-quickstart on Fri Dec 29 11:35:55 2017. +# This file is part of Pyrogram. # -# This file is execfile()d with the current directory set to its -# containing dir. +# 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. # -# Note that not all possible configuration values are present in this -# autogenerated file. +# 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. # -# All configuration values have a default; values that are commented out -# serve to show the default. +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# import os import sys -sys.path.insert(0, os.path.abspath('../..')) +sys.path.insert(0, os.path.abspath("../..")) -# Import after sys.path.insert() to avoid issues from pyrogram import __version__ from pygments.styles.friendly import FriendlyStyle FriendlyStyle.background_color = "#f3f2f1" -# -- General configuration ------------------------------------------------ +project = "Pyrogram" +copyright = "2017-2019, Dan" +author = "Dan" -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.napoleon', - 'sphinx.ext.autosummary' + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.autosummary" ] +master_doc = "index" +source_suffix = ".rst" +autodoc_member_order = "bysource" + +version = __version__ +release = version +version_rst = ".. |version| replace:: {}".format(version) + +templates_path = ["_templates"] + napoleon_use_rtype = False -# Don't show source files on docs -html_show_sourcelink = True - -# Order by source, not alphabetically -autodoc_member_order = 'bysource' - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'Pyrogram' -copyright = '2017-2019, Dan Tès' -author = 'Dan Tès' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = "version " + __version__ -# The full version, including alpha/beta/rc tags. -release = version - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'friendly' - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - -# -- Options for HTML output ---------------------------------------------- +pygments_style = "friendly" html_title = "Pyrogram Documentation" - -# Overridden by template +html_theme = "sphinx_rtd_theme" +html_static_path = ["_static"] +html_show_sourcelink = True html_show_copyright = False - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = { - 'canonical_url': "https://docs.pyrogram.org/", - 'collapse_navigation': True, - 'sticky_navigation': False, - 'logo_only': True, - 'display_version': True + "canonical_url": "https://docs.pyrogram.org/", + "collapse_navigation": True, + "sticky_navigation": False, + "logo_only": True, + "display_version": True } -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = '_images/logo.png' - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -html_favicon = '_images/favicon.ico' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# This is required for the alabaster theme -# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars -html_sidebars = { - '**': [ - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - ] -} - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Pyrogramdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'Pyrogram.tex', 'Pyrogram Documentation', - 'Dan Tès', 'manual'), -] - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'pyrogram', 'Pyrogram Documentation', - [author], 1) -] - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'Pyrogram', 'Pyrogram Documentation', - author, 'Pyrogram', 'One line description of project.', - 'Miscellaneous'), -] +html_logo = "_images/pyrogram.png" +html_favicon = "_images/favicon.ico" diff --git a/docs/source/meta/faq.rst b/docs/source/faq.rst similarity index 76% rename from docs/source/meta/faq.rst rename to docs/source/faq.rst index 07f4aece..b42332cd 100644 --- a/docs/source/meta/faq.rst +++ b/docs/source/faq.rst @@ -20,7 +20,7 @@ C. It enables you to easily create custom applications for both user and bot ide `MTProto API`_ with the Python programming language. .. _Telegram: https://telegram.org -.. _MTProto API: ../topics/mtproto-vs-botapi#what-is-the-mtproto-api +.. _MTProto API: topics/mtproto-vs-botapi#what-is-the-mtproto-api Where does the name come from? ------------------------------ @@ -51,15 +51,15 @@ Why Pyrogram? - **Comprehensive**: Execute any `advanced action`_ an official client is able to do, and even more. .. _TgCrypto: https://github.com/pyrogram/tgcrypto -.. _Smart Plugin: ../topics/smart-plugins -.. _advanced action: ../topics/advanced-usage +.. _Smart Plugin: topics/smart-plugins +.. _advanced action: topics/advanced-usage What can MTProto do more than the Bot API? ------------------------------------------ For a detailed answer, please refer to the `MTProto vs. Bot API`_ page. -.. _MTProto vs. Bot API: ../topics/mtproto-vs-botapi +.. _MTProto vs. Bot API: topics/mtproto-vs-botapi Why do I need an API key for bots? ---------------------------------- @@ -75,6 +75,53 @@ Using MTProto is the only way to communicate with the actual Telegram servers, a identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone number only. +Can I use the same file_id across different accounts? +----------------------------------------------------- + +No, Telegram doesn't allow this. + +File ids are personal and bound to a specific user/bot -- and an attempt in using a foreign file id will result in +errors such as ``[400 MEDIA_EMPTY]``. + +The only exception are stickers' file ids; you can use them across different accounts without any problem, like this +one: ``CAADBAADyg4AAvLQYAEYD4F7vcZ43AI``. + +Can I use Bot API's file_ids in Pyrogram? +----------------------------------------- + +Definitely! All file ids you might have taken from the Bot API are 100% compatible and re-usable in Pyrogram... + +...at least for now. + +Telegram is slowly changing some server's internals and it's doing it in such a way that file ids are going to break +inevitably. Not only this, but it seems that the new, hypothetical, file ids could also possibly expire at anytime, thus +losing the *persistence* feature. + +This change will most likely affect the official `Bot API `_ too +(unless Telegram implements some workarounds server-side to keep backwards compatibility, which Pyrogram could in turn +make use of) and we can expect a proper notice from Telegram. + +Can I use multiple clients at once on the same account? +------------------------------------------------------- + +Yes, you can. Both user and bot accounts are able to run multiple sessions in parallel (up to 10 per account). However, +you must pay attention and not use the *same* exact session in more than one client at the same time. In other words: + +- Avoid copying your session file: even if you rename the file, the copied sessions will still point to a specific one + stored in the server. + +- Make sure that only one instance of your script runs, using your session file. + +If you -- even accidentally -- fail to do so, all the previous session copies will immediately stop receiving updates +and eventually the server will start throwing the error ``[406 AUTH_KEY_DUPLICATED]``, inviting you to login again. + +Why is that so? Because the server has recognized two identical sessions are running in two different locations, and +concludes it could possibly be due to a cloned/stolen device. Having the session ended in such occasions will protect +the user's privacy. + +So, the only correct way to run multiple clients on the same account is authorizing your account (either user or bot) +from the beginning every time, and use one separate session for each parallel client you are going to use. + I started a client and nothing happens! --------------------------------------- @@ -99,63 +146,30 @@ fails or not: - DC4: ``149.154.167.91`` - DC5: ``91.108.56.149`` -|bug report| - -.. _you need a proxy: ../topics/proxy +.. _you need a proxy: topics/proxy I keep getting PEER_ID_INVALID error! ------------------------------------------- -The error in question is **[400 PEER_ID_INVALID]: The id/access_hash combination is invalid**, and could mean several +The error in question is ``[400 PEER_ID_INVALID]``, and could mean several things: - 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). - -|bug report| - -.. |bug report| replace:: - - **Note:** If you really believe this should not happen, kindly open a `Bug Report`_. - -Can I use the same file_id across different accounts? ------------------------------------------------------ - -No, Telegram doesn't allow this. - -File ids are personal and bound to a specific user/bot -- and an attempt in using a foreign file id will result in -errors such as **[400 MEDIA_EMPTY]: The media is invalid**. - -The only exception are stickers' file ids; you can use them across different accounts without any problem, like this -one: ``CAADBAADyg4AAvLQYAEYD4F7vcZ43AI``. - -Can I use Bot API's file_ids in Pyrogram? ------------------------------------------ - -Definitely! All file ids you might have taken from the Bot API are 100% compatible and re-usable in Pyrogram... - -...at least for now. - -Telegram is slowly changing some server's internals and it's doing it in such a way that file ids are going to break -inevitably. Not only this, but it seems that the new, hypothetical, file ids could also possibly expire at anytime, thus -losing the *persistence* feature. - -This change will most likely affect the official `Bot API <../topics/mtproto-vs-botapi#what-is-the-bot-api>`_ too -(unless Telegram implements some workarounds server-side to keep backwards compatibility, which Pyrogram could in turn -make use of) and we can expect a proper notice from Telegram. +- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``. My account has been deactivated/limited! ---------------------------------------- First of all, you should understand that Telegram wants to be a safe place for people to stay in, and to pursue this goal there are automatic protection systems running to prevent flood and spam, as well as a moderation team of humans -who reviews reports. +who review reports. -**Pyrogram is a tool at your commands; it only does what you tell it to do, the rest is up to you.** +.. centered:: Pyrogram is a tool at your commands; it only does what you tell it to do, the rest is up to you. -Having said that, here's how a list of what Telegram definitely doesn't like: +Having said that, here's a list of what Telegram definitely doesn't like: - Flood, abusing the API. - Spam, sending unsolicited messages or adding people to unwanted groups and channels. @@ -178,8 +192,8 @@ Pyrogram is free software and is currently licensed under the terms of the `GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it provided that modifications are described and licensed for free under LGPLv3+. -In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or a -different licence or even proprietary --- without being required to release the source code of your own applications. +In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or +different license, or even proprietary --- without being required to release the source code of your own applications. However, any modifications to the library itself are required to be published for free under the same LGPLv3+ license. .. _GNU Lesser General Public License v3 or later (LGPLv3+): https://github.com/pyrogram/pyrogram/blob/develop/COPYING.lesser diff --git a/docs/source/meta/glossary.rst b/docs/source/glossary.rst similarity index 83% rename from docs/source/meta/glossary.rst rename to docs/source/glossary.rst index fb5bc8c1..5f00cbfd 100644 --- a/docs/source/meta/glossary.rst +++ b/docs/source/glossary.rst @@ -18,7 +18,7 @@ general. Some words may as well link to dedicated articles in case the topic is API key A secret code used to authenticate and/or authorize a specific application to Telegram in order for it to control how the API is being used, for example, to prevent abuses of the API. - `More on API keys <../intro/setup#api-keys>`_. + `More on API keys `_. DC Also known as *data center*, is a place where lots of computer systems are housed and used together in order to @@ -26,25 +26,25 @@ general. Some words may as well link to dedicated articles in case the topic is RPC Acronym for Remote Procedure call, that is, a function which gets executed at some remote place (i.e. Telegram - server) and not in your local. + server) and not in your local machine. RPCError An error caused by an RPC which must be returned in place of the successful result in order to let the caller - know something went wrong. `More on RPCError <../start/errors>`_. + know something went wrong. `More on RPCError `_. MTProto The name of the custom-made, open and encrypted protocol by Telegram, implemented in Pyrogram. - `More on MTProto `_. + `More on MTProto `_. MTProto API The Telegram main API Pyrogram makes use of, which is able to connect both users and normal bots to Telegram using MTProto as application layer protocol and execute any method Telegram provides from its public TL-schema. - `More on MTProto API `_. + `More on MTProto API `_. Bot API - The Telegram Bot API that is able to only connect normal bots to Telegram using HTTP as application layer - protocol and allows to execute a subset of the main Telegram API. - `More on Bot API `_. + The Telegram Bot API that is able to only connect normal bots only to Telegram using HTTP as application layer + protocol and allows to execute a sub-set of the main Telegram API. + `More on Bot API `_. Pyrogrammer A developer that uses Pyrogram to build Telegram applications. @@ -65,13 +65,11 @@ general. Some words may as well link to dedicated articles in case the topic is Handler An object that wraps around a callback function that is *actually meant* to be registered into the framework, which will then be able to handle a specific kind of events, such as a new incoming message, for example. - `More on Handlers <../start/updates>`_ + `More on Handlers `_. Decorator Also known as *function decorator*, in Python, is a callable object that is used to modify another function. Decorators in Pyrogram are used to automatically register callback functions for handling updates. - `More on Decorators <../start/updates#using-decorators>`_ - -.. _handling updates: ../start/updates + `More on Decorators `_. .. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md diff --git a/docs/source/index.rst b/docs/source/index.rst index 89c92719..de91015f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -4,8 +4,8 @@ Welcome to Pyrogram .. raw:: html @@ -55,12 +55,15 @@ order using the Next button at the end of each page. Here below you can, instead pages for a quick access. First Steps -^^^^^^^^^^^ +----------- -- `Quick Start`_ - Overview to get you started quickly. -- `Calling Methods`_ - How to call Pyrogram's methods. -- `Handling Updates`_ - How to handle Telegram updates. -- `Error Handling`_ - How to handle API errors correctly. +.. hlist:: + :columns: 2 + + - `Quick Start`_: Overview to get you started quickly. + - `Calling Methods`_: How to call Pyrogram's methods. + - `Handling Updates`_: How to handle Telegram updates. + - `Error Handling`_: How to handle API errors correctly. .. _Quick Start: intro/quickstart .. _Calling Methods: start/invoking @@ -68,32 +71,38 @@ First Steps .. _Error Handling: start/errors API Reference -^^^^^^^^^^^^^ +------------- -- `Client Class`_ - Reference details about the Client class. -- `Available Methods`_ - A list of available high-level methods. -- `Available Types`_ - A list of available high-level types. -- `Bound Methods`_ - A list of convenient bound methods. +.. hlist:: + :columns: 2 -.. _Client Class: api/client + - `Pyrogram Client`_: Reference details about the Client class. + - `Available Methods`_: List of available high-level methods. + - `Available Types`_: List of available high-level types. + - `Bound Methods`_: List of convenient bound methods. + +.. _Pyrogram Client: ./api/client .. _Available Methods: api/methods .. _Available Types: api/types .. _Bound Methods: api/bound-methods Meta -^^^^ +---- -- `Pyrogram FAQ`_ - Answers to common Pyrogram questions. -- `Pyrogram Glossary`_ - A list of words with brief explanations. -- `Release Notes`_ - Release notes for Pyrogram releases. -- `Powered by Pyrogram`_ - A collection of Pyrogram Projects. -- `Support Pyrogram Development`_ - Ways to show your appreciation. +.. hlist:: + :columns: 2 -.. _Pyrogram FAQ: meta/faq -.. _Pyrogram Glossary: meta/glossary -.. _Release Notes: meta/releases -.. _Powered by Pyrogram: meta/powered-by -.. _Support Pyrogram Development: meta/support-pyrogram + - `Pyrogram FAQ`_: Answers to common Pyrogram questions. + - `Pyrogram Glossary`_: List of words with brief explanations. + - `Release Notes`_: Release notes for Pyrogram releases. + - `Powered by Pyrogram`_: Collection of Pyrogram Projects. + - `Support Pyrogram`_: Ways to show your appreciation. + +.. _Pyrogram FAQ: faq +.. _Pyrogram Glossary: glossary +.. _Release Notes: releases +.. _Powered by Pyrogram: powered-by +.. _Support Pyrogram: support-pyrogram .. toctree:: :hidden: @@ -137,6 +146,7 @@ Meta topics/session-settings topics/tgcrypto topics/text-formatting + topics/serialize topics/proxy topics/bots-interaction topics/mtproto-vs-botapi @@ -148,11 +158,11 @@ Meta :hidden: :caption: Meta - meta/faq - meta/glossary - meta/releases - meta/powered-by - meta/support-pyrogram + faq + glossary + releases + powered-by + support-pyrogram .. toctree:: :hidden: diff --git a/docs/source/intro/install.rst b/docs/source/intro/install.rst index f26fc37f..fe804e79 100644 --- a/docs/source/intro/install.rst +++ b/docs/source/intro/install.rst @@ -83,11 +83,11 @@ Verifying To verify that Pyrogram is correctly installed, open a Python shell and import it. If no error shows up you are good to go. -.. code-block:: python +.. parsed-literal:: >>> import pyrogram >>> pyrogram.__version__ - '0.13.0' + '|version|' .. _TgCrypto: ../topics/tgcrypto .. _`Github repo`: http://github.com/pyrogram/pyrogram diff --git a/docs/source/intro/setup.rst b/docs/source/intro/setup.rst index b318654d..9c0cc6d4 100644 --- a/docs/source/intro/setup.rst +++ b/docs/source/intro/setup.rst @@ -40,7 +40,7 @@ There are two ways to do so, and you can choose what fits better for you: api_hash = 0123456789abcdef0123456789abcdef - Alternatively, you can pass your API key to Pyrogram by simply using the *api_id* and *api_hash* parameters of the - Client class. This way you can have full control on how to store and load your credentials (e.g.:, you can load the + Client class. This way you can have full control on how to store and load your credentials (e.g., you can load the credentials from the environment variables and directly pass the values into Pyrogram): .. code-block:: python diff --git a/docs/source/meta/support-pyrogram.rst b/docs/source/meta/support-pyrogram.rst deleted file mode 100644 index 052d78bd..00000000 --- a/docs/source/meta/support-pyrogram.rst +++ /dev/null @@ -1,2 +0,0 @@ -Support Pyrogram Development -============================ diff --git a/docs/source/meta/powered-by.rst b/docs/source/powered-by.rst similarity index 95% rename from docs/source/meta/powered-by.rst rename to docs/source/powered-by.rst index 3e46fb07..03e6decd 100644 --- a/docs/source/meta/powered-by.rst +++ b/docs/source/powered-by.rst @@ -55,8 +55,8 @@ Projects Showcase ----- -`BotListBot `_ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`BotListBot `_ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | **A bot which partly uses Pyrogram to check if other bots are still alive** | --- by `JosXa `_ diff --git a/docs/source/meta/releases.rst b/docs/source/releases.rst similarity index 100% rename from docs/source/meta/releases.rst rename to docs/source/releases.rst diff --git a/docs/source/start/auth.rst b/docs/source/start/auth.rst index 3f76e929..e00b08a0 100644 --- a/docs/source/start/auth.rst +++ b/docs/source/start/auth.rst @@ -8,7 +8,7 @@ User Authorization ------------------ In order to use the API, Telegram requires that users be authorized via their phone numbers. -Pyrogram automatically manages this access, all you need to do is create an instance of the +Pyrogram automatically manages this process, all you need to do is create an instance of the :class:`Client ` class by passing to it a ``session_name`` of your choice (e.g.: "my_account") and call the :meth:`run() ` method: @@ -47,7 +47,7 @@ Bot Authorization Bots are a special kind of users that are authorized via their tokens (instead of phone numbers), which are created by the `Bot Father`_. Bot tokens replace the users' phone numbers only — you still need to -`configure a Telegram API key `_ with Pyrogram, even when using bots. +`configure a Telegram API key <../intro/setup#configuration>`_ with Pyrogram, even when using bots. The authorization process is automatically managed. All you need to do is choose a ``session_name`` (can be anything, usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named diff --git a/docs/source/support-pyrogram.rst b/docs/source/support-pyrogram.rst new file mode 100644 index 00000000..c867b706 --- /dev/null +++ b/docs/source/support-pyrogram.rst @@ -0,0 +1,26 @@ +Support Pyrogram +================ + +Pyrogram is free and open source software, and thus supported by your love! If you like the project and have found it to +be useful, give Pyrogram a `Star on GitHub`_. Your appreciation means a lot and helps staying motivated. + +.. raw:: html + + Star +

+ +Donate +------ + +If you'd also like to donate in order to support Pyrogram -- or any of my `other works`_ -- you can use the PayPal +button below. Thank you. + +.. image:: https://i.imgur.com/fasFTzK.png + :target: https://paypal.me/delivrance + :width: 128 + +--- `Dan`_ + +.. _Star on GitHub: https://github.com/pyrogram/pyrogram +.. _other works: https://github.com/delivrance +.. _Dan: https://t.me/haskell diff --git a/docs/source/topics/mtproto-vs-botapi.rst b/docs/source/topics/mtproto-vs-botapi.rst index accebcd5..cad84251 100644 --- a/docs/source/topics/mtproto-vs-botapi.rst +++ b/docs/source/topics/mtproto-vs-botapi.rst @@ -1,58 +1,110 @@ MTProto vs. Bot API =================== -Being Pyrogram an MTProto-based library, this very feature makes it already superior to, what is usually called, the -official Bot API. +Pyrogram is a framework that acts as a fully-fledged Telegram client based on MTProto, and this very feature makes it +already superior to, what is usually called, the official Bot API, in many respects. This page will therefore show you +why Pyrogram might be a better choice for your project by comparing the two APIs, but first, let's make it clear what +actually is the MTProto and the Bot API. What is the MTProto API? ------------------------ -MTProto, took alone, is the name of the custom-made, open and encrypted communication protocol created by Telegram -itself --- it's the only protocol used to exchange information between a client application and the actual Telegram -servers. +`MTProto`_, took alone, is the name of the custom-made, open and encrypted communication protocol created by Telegram +itself --- it's the only protocol used to exchange information between a client and the actual Telegram servers. -The MTProto **API** however, is what people, for convenience, call the main Telegram API as a whole. This API is able -to authorize both users and bots and happens to be built on top of the MTProto encryption protocol by means of binary -data serialized in a specific way, as described by the TL language, hence the correlation. +The MTProto **API** on the other hand, is what people, for convenience, call the main Telegram API as a whole. This API +is able to authorize both users and bots and is built on top of the MTProto encryption protocol by means of +`binary data serialized`_ in a specific way, as described by the `TL language`_, and delivered using UDP, TCP or even +HTTP as transport-layer protocol. + +.. _MTProto: https://core.telegram.org/mtproto +.. _binary data serialized: https://core.telegram.org/mtproto/serialize +.. _TL language: https://core.telegram.org/mtproto/TL What is the Bot API? -------------------- -The Bot API is an HTTP(S) interface for building normal bots. Bots are special accounts that are authorized via tokens -instead of phone numbers. The Bot API is built yet again on top of the main Telegram API, but runs on an intermediate -server application that in turn communicates with the actual Telegram servers using MTProto. +The `Bot API`_ is an HTTP(S) interface for building normal bots using a sub-set of the main MTProto API. Bots are special +accounts that are authorized via tokens instead of phone numbers. The Bot API is built yet again on top of the main +Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram servers +using MTProto. .. figure:: https://i.imgur.com/C108qkX.png :align: center +.. _Bot API: https://core.telegram.org/bots/api + Advantages of the MTProto API ----------------------------- -Here is a list of all the known advantages in using MTProto-based libraries (such as Pyrogram) instead of the official +Here is a list of all the advantages in using MTProto-based libraries -- such as Pyrogram -- instead of the official HTTP Bot API. Using Pyrogram you can: -- **Authorize both user and bot identities**: The Bot API only allows bot accounts. +.. hlist:: + :columns: 1 -- **Upload & download any file, up to 1500 MB each (~1.5 GB)**: The Bot API allows uploads and downloads of files only - up to 50 MB / 20 MB in size (respectively). + - :guilabel:`+` **Authorize both user and bot identities** + - :guilabel:`--` The Bot API only allows bot accounts -- **Has less overhead due to direct connections to Telegram**: The Bot API uses an intermediate server to handle HTTP - requests before they are sent to the actual Telegram servers. +.. hlist:: + :columns: 1 -- **Run multiple sessions at once, up to 10 per account (either bot or user)**: The Bot API intermediate server will - terminate any other session in case you try to use the same bot again in a parallel connection. + - :guilabel:`+` **Upload & download any file, up to 1500 MB each (~1.5 GB)** + - :guilabel:`--` The Bot API allows uploads and downloads of files only up to 50 MB / 20 MB in size (respectively). -- **Get information about any public chat by usernames, even if not a member**: The Bot API simply doesn't support this. +.. hlist:: + :columns: 1 -- **Obtain information about any message existing in a chat using their ids**: The Bot API simply doesn't support this. + - :guilabel:`+` **Has less overhead due to direct connections to Telegram** + - :guilabel:`--` The Bot API uses an intermediate server to handle HTTP requests before they are sent to the actual + Telegram servers. -- **Retrieve the whole chat members list of either public or private chats**: The Bot API simply doesn't support this. +.. hlist:: + :columns: 1 -- **Receive extra updates, such as the one about a user name change**: The Bot API simply doesn't support this. + - :guilabel:`+` **Run multiple sessions at once, up to 10 per account (either bot or user)** + - :guilabel:`--` The Bot API intermediate server will terminate any other session in case you try to use the same + bot again in a parallel connection. -- **Has more meaningful errors in case something went wrong**: The Bot API reports less detailed errors. +.. hlist:: + :columns: 1 -- **Has much more detailed types and powerful methods**: The Bot API types often miss some useful information about - Telegram's type and some of the methods are limited as well. + - :guilabel:`+` **Has much more detailed types and powerful methods** + - :guilabel:`--` The Bot API types often miss some useful information about Telegram entities and some of the + methods are limited as well. -- **Get API version updates, and thus new features, sooner**: The Bot API is simply slower in implementing new features. \ No newline at end of file +.. hlist:: + :columns: 1 + + - :guilabel:`+` **Get information about any public chat by usernames, even if not a member** + - :guilabel:`--` The Bot API simply doesn't support this + +.. hlist:: + :columns: 1 + + - :guilabel:`+` **Obtain information about any message existing in a chat using their ids** + - :guilabel:`--` The Bot API simply doesn't support this + +.. hlist:: + :columns: 1 + + - :guilabel:`+` **Retrieve the whole chat members list of either public or private chats** + - :guilabel:`--` The Bot API simply doesn't support this + +.. hlist:: + :columns: 1 + + - :guilabel:`+` **Receive extra updates, such as the one about a user name change** + - :guilabel:`--` The Bot API simply doesn't support this + +.. hlist:: + :columns: 1 + + - :guilabel:`+` **Has more meaningful errors in case something went wrong** + - :guilabel:`--` The Bot API reports less detailed errors + +.. hlist:: + :columns: 1 + + - :guilabel:`+` **Get API version updates, and thus new features, sooner** + - :guilabel:`--` The Bot API is simply slower in implementing new features diff --git a/docs/source/topics/serialize.rst b/docs/source/topics/serialize.rst new file mode 100644 index 00000000..32208199 --- /dev/null +++ b/docs/source/topics/serialize.rst @@ -0,0 +1,55 @@ +Object Serialization +==================== + +Serializing means converting a Pyrogram object, which exists as Python class instance, to a text string that can be +easily shared and stored anywhere. Pyrogram provides two formats for serializing its objects: one good looking for +humans and another more compact for machines that is able to recover the original structures. + +For Humans - str(obj) +--------------------- + +If you want a nicely formatted, human readable JSON representation of any object in the API -- namely, any object from +`Pyrogram types`_, `raw functions`_ and `raw types`_ -- you can use use ``str(obj)``. + +.. code-block:: python + + ... + + with app: + r = app.get_chat("haskell") + + print(str(r)) + +.. tip:: + + When using ``print()`` you don't actually need to use ``str()`` on the object because it is called automatically, we + have done that above just to show you how to explicitly convert a Pyrogram object to JSON. + +.. _Pyrogram types: ../api/types +.. _raw functions: ../telegram/functions +.. _raw types: ../telegram/types + +For Machines - repr(obj) +------------------------ + +If you want to share or store objects for future references in a more compact way, you can use ``repr(obj)``. While +still pretty much readable, this format is not intended for humans. The advantage of this format is that once you +serialize your object, you can use ``eval()`` to get back the original structure; just make sure to ``import pyrogram``, +as the process requires the package to be in scope. + +.. code-block:: python + + import pyrogram + + ... + + with app: + r = app.get_chat("haskell") + + print(repr(r)) + print(eval(repr(r)) == r) # True + +.. note:: + + Type definitions are subject to changes between versions. You should make sure to store and load objects using the + same Pyrogram version. \ No newline at end of file diff --git a/docs/source/topics/session-settings.rst b/docs/source/topics/session-settings.rst index c8e10479..91e3f050 100644 --- a/docs/source/topics/session-settings.rst +++ b/docs/source/topics/session-settings.rst @@ -9,7 +9,7 @@ app (or by invoking `GetAuthorizations <../telegram/functions/account/GetAuthori store some useful information such as the client who's using them and from which country and IP address. .. figure:: https://i.imgur.com/YaqtMLO.png - :width: 90% + :width: 600 :align: center **A Pyrogram session running on Linux, Python 3.7.** diff --git a/docs/source/topics/tgcrypto.rst b/docs/source/topics/tgcrypto.rst index 2af09a06..454bf05c 100644 --- a/docs/source/topics/tgcrypto.rst +++ b/docs/source/topics/tgcrypto.rst @@ -2,7 +2,7 @@ Fast Crypto =========== Pyrogram's speed can be *dramatically* boosted up by TgCrypto_, a high-performance, easy-to-install Telegram Crypto -Library specifically written in C for Pyrogram [#f1]_ as a Python extension. +Library specifically written in C for Pyrogram [1]_ as a Python extension. TgCrypto is a replacement for the much slower PyAES and implements the crypto algorithms Telegram requires, namely **AES-IGE 256 bit** (used in MTProto v2.0) and **AES-CTR 256 bit** (used for CDN encrypted files). @@ -28,5 +28,5 @@ what you should do next: .. _TgCrypto: https://github.com/pyrogram/tgcrypto -.. [#f1] Although TgCrypto is intended for Pyrogram, it is shipped as a standalone package and can thus be used for +.. [1] Although TgCrypto is intended for Pyrogram, it is shipped as a standalone package and can thus be used for other Python projects too. diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 1cfa7c79..8c1e3001 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -66,15 +66,13 @@ class Client(Methods, BaseClient): session_name (``str``): Name to uniquely identify a session of either a User or a Bot, e.g.: "my_account". This name will be used to save a file to disk that stores details needed for reconnecting without asking again for credentials. - Note for bots: You can pass a bot token here, but this usage will be deprecated in next releases. - Use *bot_token* instead. api_id (``int``, *optional*): The *api_id* part of your Telegram API Key, as integer. E.g.: 12345 This is an alternative way to pass it if you don't want to use the *config.ini* file. api_hash (``str``, *optional*): - The *api_hash* part of your Telegram API Key, as string. E.g.: "0123456789abcdef0123456789abcdef" + The *api_hash* part of your Telegram API Key, as string. E.g.: "0123456789abcdef0123456789abcdef". This is an alternative way to pass it if you don't want to use the *config.ini* file. app_version (``str``, *optional*): @@ -104,7 +102,7 @@ class Client(Methods, BaseClient): This is an alternative way to setup a proxy if you don't want to use the *config.ini* file. test_mode (``bool``, *optional*): - Enable or disable log-in to testing servers. Defaults to False. + Enable or disable login to the test servers. Defaults to False. Only applicable for new sessions and will be ignored in case previously created sessions are loaded. @@ -170,7 +168,7 @@ class Client(Methods, BaseClient): Defaults to False (updates enabled and always received). takeout (``bool``, *optional*): - Pass True to let the client use a takeout session instead of a normal one, implies no_updates. + Pass True to let the client use a takeout session instead of a normal one, implies *no_updates=True*. Useful for exporting your Telegram data. Methods invoked inside a takeout session (such as get_history, download_media, ...) are less prone to throw FloodWait exceptions. Only available for users, bots will ignore this parameter. diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index e51f3425..09cb9ca3 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -2928,7 +2928,7 @@ class Message(PyrogramType, Update): True on success. Raises: - :class:`RPCError ` + RPCError: In case of a Telegram RPC error. """ return self._client.pin_chat_message( chat_id=self.chat.id, diff --git a/setup.py b/setup.py index f0d6d030..a255dc5f 100644 --- a/setup.py +++ b/setup.py @@ -122,6 +122,7 @@ class Generate(Command): if len(argv) > 1 and argv[1] in ["bdist_wheel", "install", "develop"]: api_compiler.start() error_compiler.start() + docs_compiler.start() setup( name="Pyrogram", From 4bc7345328605e1d97090260b346cd791b01cd9e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 25 May 2019 01:49:52 +0200 Subject: [PATCH 083/202] Update setup.py --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a255dc5f..146dae9e 100644 --- a/setup.py +++ b/setup.py @@ -132,7 +132,7 @@ setup( long_description_content_type="text/markdown", url="https://github.com/pyrogram", download_url="https://github.com/pyrogram/pyrogram/releases/latest", - author="Dan Tès", + author="Dan", author_email="dan@pyrogram.org", license="LGPLv3+", classifiers=[ @@ -161,7 +161,7 @@ setup( keywords="telegram chat messenger mtproto api client library python", project_urls={ "Tracker": "https://github.com/pyrogram/pyrogram/issues", - "Community": "https://t.me/PyrogramChat", + "Community": "https://t.me/Pyrogram", "Source": "https://github.com/pyrogram/pyrogram", "Documentation": "https://docs.pyrogram.org", }, From bb246f9e605084394c3ad2f5ad9e1562c7b5a299 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 25 May 2019 01:50:34 +0200 Subject: [PATCH 084/202] Update Pyrogram to v0.13.0 --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 07c460fc..cbba2fbf 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -24,7 +24,7 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]: # Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one. sys.modules["typing"] = typing -__version__ = "0.13.0.develop" +__version__ = "0.13.0" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __copyright__ = "Copyright (C) 2017-2019 Dan " From b14ca1abf9f6a782ea474c59d6297e5a18e50831 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 25 May 2019 02:12:45 +0200 Subject: [PATCH 085/202] Create FUNDING.yml --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..f34f615a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: delivrance +custom: https://docs.pyrogram.org/support-pyrogram From 41f010caadc7ac35d153fcbe988a4fb48a4c3ac7 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 26 May 2019 16:52:22 +0200 Subject: [PATCH 086/202] Add USER_DEACTIVATED_BAN error --- compiler/error/source/401_UNAUTHORIZED.tsv | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/error/source/401_UNAUTHORIZED.tsv b/compiler/error/source/401_UNAUTHORIZED.tsv index 54b24dd7..e5cd3874 100644 --- a/compiler/error/source/401_UNAUTHORIZED.tsv +++ b/compiler/error/source/401_UNAUTHORIZED.tsv @@ -2,6 +2,7 @@ id message AUTH_KEY_UNREGISTERED The key is not registered in the system AUTH_KEY_INVALID The key is invalid USER_DEACTIVATED The user has been deleted/deactivated +USER_DEACTIVATED_BAN The user has been deleted/deactivated SESSION_REVOKED The authorization has been invalidated, because of the user terminating all sessions SESSION_EXPIRED The authorization has expired ACTIVE_USER_REQUIRED The method is only available to already activated users From 87ad98142022ca91ba773b2546eaa32e8c176381 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 27 May 2019 14:39:10 +0200 Subject: [PATCH 087/202] Add get_user_dc method --- pyrogram/client/methods/users/__init__.py | 4 +- pyrogram/client/methods/users/get_user_dc.py | 52 ++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 pyrogram/client/methods/users/get_user_dc.py diff --git a/pyrogram/client/methods/users/__init__.py b/pyrogram/client/methods/users/__init__.py index d67a18bd..a33a0f0c 100644 --- a/pyrogram/client/methods/users/__init__.py +++ b/pyrogram/client/methods/users/__init__.py @@ -18,6 +18,7 @@ from .delete_user_profile_photos import DeleteUserProfilePhotos from .get_me import GetMe +from .get_user_dc import GetUserDC from .get_user_profile_photos import GetUserProfilePhotos from .get_user_profile_photos_count import GetUserProfilePhotosCount from .get_users import GetUsers @@ -32,6 +33,7 @@ class Users( GetUsers, GetMe, UpdateUsername, - GetUserProfilePhotosCount + GetUserProfilePhotosCount, + GetUserDC ): pass diff --git a/pyrogram/client/methods/users/get_user_dc.py b/pyrogram/client/methods/users/get_user_dc.py new file mode 100644 index 00000000..27631e95 --- /dev/null +++ b/pyrogram/client/methods/users/get_user_dc.py @@ -0,0 +1,52 @@ +# 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 typing import Union + +from pyrogram.api import functions, types + +from ...ext import BaseClient + + +class GetUserDC(BaseClient): + def get_user_dc(self, user_id: Union[int, str]) -> Union[int, None]: + """Get the assigned data center (DC) of a user. + + Parameters: + user_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For your personal cloud (Saved Messages) you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + Returns: + ``int`` | ``None``: The DC identifier as integer, or None in case it wasn't possible to get it. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + r = self.send(functions.users.GetUsers(id=[self.resolve_peer(user_id)])) + + if r: + r = r[0] + + if r.photo: + if isinstance(r.photo.photo_small, types.FileLocation): + return r.photo.photo_small.dc_id + + return None From e94dcd3b0b06b33ad7f0acb040d6a33b5a565631 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 28 May 2019 16:41:55 +0200 Subject: [PATCH 088/202] Update docs --- docs/sitemap.py | 10 +- docs/source/api/bound-methods.rst | 102 +++-- docs/source/api/decorators.rst | 57 ++- docs/source/api/handlers.rst | 33 +- docs/source/api/methods.rst | 414 +++++++++--------- docs/source/api/types.rst | 158 ++++--- docs/source/conf.py | 4 +- docs/source/faq.rst | 42 +- docs/source/glossary.rst | 14 +- docs/source/index.rst | 51 +-- docs/source/intro/install.rst | 3 +- docs/source/intro/quickstart.rst | 4 +- docs/source/intro/setup.rst | 8 +- docs/source/license.rst | 15 + docs/source/start/auth.rst | 9 +- docs/source/start/invoking.rst | 11 +- docs/source/start/updates.rst | 38 +- docs/source/topics/advanced-usage.rst | 41 +- docs/source/topics/auto-auth.rst | 2 +- docs/source/topics/bots-interaction.rst | 5 +- docs/source/topics/filters.rst | 24 +- docs/source/topics/more-on-updates.rst | 8 +- docs/source/topics/serialize.rst | 7 +- docs/source/topics/session-settings.rst | 2 +- docs/source/topics/smart-plugins.rst | 17 +- docs/source/topics/text-formatting.rst | 4 +- .../client/methods/chats/set_chat_photo.py | 2 +- .../types/messages_and_media/message.py | 2 +- 28 files changed, 536 insertions(+), 551 deletions(-) create mode 100644 docs/source/license.rst diff --git a/docs/sitemap.py b/docs/sitemap.py index 87c27849..4def886f 100644 --- a/docs/sitemap.py +++ b/docs/sitemap.py @@ -23,11 +23,11 @@ canonical = "https://docs.pyrogram.org/" dirs = { ".": ("weekly", 1.0), - "intro": ("weekly", 0.8), - "start": ("weekly", 0.8), - "api": ("weekly", 0.6), - "topics": ("weekly", 0.6), - "telegram": ("weekly", 0.4) + "intro": ("weekly", 0.9), + "start": ("weekly", 0.9), + "api": ("weekly", 0.8), + "topics": ("weekly", 0.8), + "telegram": ("weekly", 0.6) } diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index d93497fe..0622e6b8 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -22,43 +22,65 @@ some of the required arguments. .. currentmodule:: pyrogram -- Message_ -- CallbackQuery_ -- InlineQuery_ - -.. _Message: +Index +----- Message +^^^^^^^ + +.. hlist:: + :columns: 3 + + - :meth:`~Message.click` + - :meth:`~Message.delete` + - :meth:`~Message.download` + - :meth:`~Message.edit` + - :meth:`~Message.edit_caption` + - :meth:`~Message.edit_media` + - :meth:`~Message.edit_reply_markup` + - :meth:`~Message.forward` + - :meth:`~Message.pin` + - :meth:`~Message.reply` + - :meth:`~Message.reply_animation` + - :meth:`~Message.reply_audio` + - :meth:`~Message.reply_cached_media` + - :meth:`~Message.reply_chat_action` + - :meth:`~Message.reply_contact` + - :meth:`~Message.reply_document` + - :meth:`~Message.reply_game` + - :meth:`~Message.reply_inline_bot_result` + - :meth:`~Message.reply_location` + - :meth:`~Message.reply_media_group` + - :meth:`~Message.reply_photo` + - :meth:`~Message.reply_poll` + - :meth:`~Message.reply_sticker` + - :meth:`~Message.reply_venue` + - :meth:`~Message.reply_video` + - :meth:`~Message.reply_video_note` + - :meth:`~Message.reply_voice` + +CallbackQuery +^^^^^^^^^^^^^ + +.. hlist:: + :columns: 2 + + - :meth:`~CallbackQuery.answer` + +InlineQuery +^^^^^^^^^^^ + +.. hlist:: + :columns: 2 + + - :meth:`~InlineQuery.answer` + +----- + +Details ------- -- :meth:`Message.click()` -- :meth:`Message.delete()` -- :meth:`Message.download()` -- :meth:`Message.edit()` -- :meth:`Message.edit_caption()` -- :meth:`Message.edit_media()` -- :meth:`Message.edit_reply_markup()` -- :meth:`Message.forward()` -- :meth:`Message.pin()` -- :meth:`Message.reply()` -- :meth:`Message.reply_animation()` -- :meth:`Message.reply_audio()` -- :meth:`Message.reply_cached_media()` -- :meth:`Message.reply_chat_action()` -- :meth:`Message.reply_contact()` -- :meth:`Message.reply_document()` -- :meth:`Message.reply_game()` -- :meth:`Message.reply_inline_bot_result()` -- :meth:`Message.reply_location()` -- :meth:`Message.reply_media_group()` -- :meth:`Message.reply_photo()` -- :meth:`Message.reply_poll()` -- :meth:`Message.reply_sticker()` -- :meth:`Message.reply_venue()` -- :meth:`Message.reply_video()` -- :meth:`Message.reply_video_note()` -- :meth:`Message.reply_voice()` - +.. Message .. automethod:: Message.click() .. automethod:: Message.delete() .. automethod:: Message.download() @@ -87,16 +109,8 @@ Message .. automethod:: Message.reply_video_note() .. automethod:: Message.reply_voice() -.. _CallbackQuery: - -CallbackQuery -------------- - +.. CallbackQuery .. automethod:: CallbackQuery.answer() -.. _InlineQuery: - -InlineQuery ------------ - -.. automethod:: InlineQuery.answer() \ No newline at end of file +.. InlineQuery +.. automethod:: InlineQuery.answer() diff --git a/docs/source/api/decorators.rst b/docs/source/api/decorators.rst index be8376f5..ff31cb27 100644 --- a/docs/source/api/decorators.rst +++ b/docs/source/api/decorators.rst @@ -1,13 +1,13 @@ Decorators ========== -While still being methods bound to the :obj:`Client ` class, decorators are of a special kind and thus deserve a -dedicated page. +While still being methods bound to the :class:`~pyrogram.Client` class, decorators are of a special kind and thus +deserve a dedicated page. Decorators are able to register callback functions for handling updates in a much easier and cleaner way compared to -`Handlers `_; they do so by instantiating the correct handler and calling -:meth:`add_handler() `, automatically. All you need to do is adding the decorators on top -of your functions. +:doc:`Handlers `; they do so by instantiating the correct handler and calling +:meth:`~pyrogram.Client.add_handler`, automatically. All you need to do is adding the decorators on top of your +functions. .. code-block:: python :emphasize-lines: 6 @@ -24,25 +24,34 @@ of your functions. app.run() -.. currentmodule:: pyrogram.Client +.. currentmodule:: pyrogram -.. autosummary:: - :nosignatures: +Index +----- - on_message - on_callback_query - on_inline_query - on_deleted_messages - on_user_status - on_poll - on_disconnect - on_raw_update +.. hlist:: + :columns: 3 -.. automethod:: pyrogram.Client.on_message() -.. automethod:: pyrogram.Client.on_callback_query() -.. automethod:: pyrogram.Client.on_inline_query() -.. automethod:: pyrogram.Client.on_deleted_messages() -.. automethod:: pyrogram.Client.on_user_status() -.. automethod:: pyrogram.Client.on_poll() -.. automethod:: pyrogram.Client.on_disconnect() -.. automethod:: pyrogram.Client.on_raw_update() \ No newline at end of file + - :meth:`~Client.on_message` + - :meth:`~Client.on_callback_query` + - :meth:`~Client.on_inline_query` + - :meth:`~Client.on_deleted_messages` + - :meth:`~Client.on_user_status` + - :meth:`~Client.on_poll` + - :meth:`~Client.on_disconnect` + - :meth:`~Client.on_raw_update` + +----- + +Details +------- + +.. Decorators +.. autodecorator:: pyrogram.Client.on_message() +.. autodecorator:: pyrogram.Client.on_callback_query() +.. autodecorator:: pyrogram.Client.on_inline_query() +.. autodecorator:: pyrogram.Client.on_deleted_messages() +.. autodecorator:: pyrogram.Client.on_user_status() +.. autodecorator:: pyrogram.Client.on_poll() +.. autodecorator:: pyrogram.Client.on_disconnect() +.. autodecorator:: pyrogram.Client.on_raw_update() \ No newline at end of file diff --git a/docs/source/api/handlers.rst b/docs/source/api/handlers.rst index 90c8e614..f91dd3d5 100644 --- a/docs/source/api/handlers.rst +++ b/docs/source/api/handlers.rst @@ -3,8 +3,8 @@ Update Handlers Handlers are used to instruct Pyrogram about which kind of updates you'd like to handle with your callback functions. -For a much more convenient way of registering callback functions have a look at `Decorators `_ instead. -In case you decided to manually create a handler, use :meth:`add_handler() ` to register +For a much more convenient way of registering callback functions have a look at :doc:`Decorators ` instead. +In case you decided to manually create a handler, use :class:`~pyrogram.Client.add_handler` to register it. .. code-block:: python @@ -25,18 +25,27 @@ it. .. currentmodule:: pyrogram -.. autosummary:: - :nosignatures: +Index +----- - MessageHandler - DeletedMessagesHandler - CallbackQueryHandler - InlineQueryHandler - UserStatusHandler - PollHandler - DisconnectHandler - RawUpdateHandler +.. hlist:: + :columns: 3 + - :class:`MessageHandler` + - :class:`DeletedMessagesHandler` + - :class:`CallbackQueryHandler` + - :class:`InlineQueryHandler` + - :class:`UserStatusHandler` + - :class:`PollHandler` + - :class:`DisconnectHandler` + - :class:`RawUpdateHandler` + +----- + +Details +------- + +.. Handlers .. autoclass:: MessageHandler() .. autoclass:: DeletedMessagesHandler() .. autoclass:: CallbackQueryHandler() diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index 7c061d3a..7614918e 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -1,7 +1,7 @@ Available Methods ================= -All Pyrogram methods listed here are bound to a :obj:`Client ` instance. +All Pyrogram methods listed here are bound to a :class:`~pyrogram.Client` instance. .. code-block:: python :emphasize-lines: 6 @@ -13,253 +13,249 @@ All Pyrogram methods listed here are bound to a :obj:`Client ` with app: app.send_message("haskell", "hi") -.. currentmodule:: pyrogram.Client +.. currentmodule:: pyrogram + +Index +----- Utilities ---------- +^^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 4 - start - stop - restart - idle - run - add_handler - remove_handler - send - resolve_peer - save_file - stop_transmission + - :meth:`~Client.start` + - :meth:`~Client.stop` + - :meth:`~Client.restart` + - :meth:`~Client.idle` + - :meth:`~Client.run` + - :meth:`~Client.add_handler` + - :meth:`~Client.remove_handler` + - :meth:`~Client.send` + - :meth:`~Client.resolve_peer` + - :meth:`~Client.save_file` + - :meth:`~Client.stop_transmission` Messages --------- +^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 3 - send_message - forward_messages - send_photo - send_audio - send_document - send_sticker - send_video - send_animation - send_voice - send_video_note - send_media_group - send_location - send_venue - send_contact - send_cached_media - send_chat_action - edit_message_text - edit_message_caption - edit_message_reply_markup - edit_message_media - delete_messages - get_messages - get_history - get_history_count - iter_history - send_poll - vote_poll - stop_poll - retract_vote - download_media + - :meth:`~Client.send_message` + - :meth:`~Client.forward_messages` + - :meth:`~Client.send_photo` + - :meth:`~Client.send_audio` + - :meth:`~Client.send_document` + - :meth:`~Client.send_sticker` + - :meth:`~Client.send_video` + - :meth:`~Client.send_animation` + - :meth:`~Client.send_voice` + - :meth:`~Client.send_video_note` + - :meth:`~Client.send_media_group` + - :meth:`~Client.send_location` + - :meth:`~Client.send_venue` + - :meth:`~Client.send_contact` + - :meth:`~Client.send_cached_media` + - :meth:`~Client.send_chat_action` + - :meth:`~Client.edit_message_text` + - :meth:`~Client.edit_message_caption` + - :meth:`~Client.edit_message_reply_markup` + - :meth:`~Client.edit_message_media` + - :meth:`~Client.delete_messages` + - :meth:`~Client.get_messages` + - :meth:`~Client.get_history` + - :meth:`~Client.get_history_count` + - :meth:`~Client.iter_history` + - :meth:`~Client.send_poll` + - :meth:`~Client.vote_poll` + - :meth:`~Client.stop_poll` + - :meth:`~Client.retract_vote` + - :meth:`~Client.download_media` Chats ------ +^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 3 - join_chat - leave_chat - kick_chat_member - unban_chat_member - restrict_chat_member - promote_chat_member - export_chat_invite_link - set_chat_photo - delete_chat_photo - set_chat_title - set_chat_description - pin_chat_message - unpin_chat_message - get_chat - get_chat_member - get_chat_members - get_chat_members_count - iter_chat_members - get_dialogs - iter_dialogs - get_dialogs_count - restrict_chat - update_chat_username + - :meth:`~Client.join_chat` + - :meth:`~Client.leave_chat` + - :meth:`~Client.kick_chat_member` + - :meth:`~Client.unban_chat_member` + - :meth:`~Client.restrict_chat_member` + - :meth:`~Client.promote_chat_member` + - :meth:`~Client.export_chat_invite_link` + - :meth:`~Client.set_chat_photo` + - :meth:`~Client.delete_chat_photo` + - :meth:`~Client.set_chat_title` + - :meth:`~Client.set_chat_description` + - :meth:`~Client.pin_chat_message` + - :meth:`~Client.unpin_chat_message` + - :meth:`~Client.get_chat` + - :meth:`~Client.get_chat_member` + - :meth:`~Client.get_chat_members` + - :meth:`~Client.get_chat_members_count` + - :meth:`~Client.iter_chat_members` + - :meth:`~Client.get_dialogs` + - :meth:`~Client.iter_dialogs` + - :meth:`~Client.get_dialogs_count` + - :meth:`~Client.restrict_chat` + - :meth:`~Client.update_chat_username` Users ------ +^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 2 - get_me - get_users - get_user_profile_photos - get_user_profile_photos_count - set_user_profile_photo - delete_user_profile_photos - update_username + - :meth:`~Client.get_me` + - :meth:`~Client.get_users` + - :meth:`~Client.get_user_profile_photos` + - :meth:`~Client.get_user_profile_photos_count` + - :meth:`~Client.set_user_profile_photo` + - :meth:`~Client.delete_user_profile_photos` + - :meth:`~Client.update_username` + - :meth:`~Client.get_user_dc` Contacts --------- +^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 3 - add_contacts - get_contacts - get_contacts_count - delete_contacts + - :meth:`~Client.add_contacts` + - :meth:`~Client.get_contacts` + - :meth:`~Client.get_contacts_count` + - :meth:`~Client.delete_contacts` Password --------- +^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 3 - enable_cloud_password - change_cloud_password - remove_cloud_password + - :meth:`~Client.enable_cloud_password` + - :meth:`~Client.change_cloud_password` + - :meth:`~Client.remove_cloud_password` Bots ----- +^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 3 - get_inline_bot_results - send_inline_bot_result - answer_callback_query - answer_inline_query - request_callback_answer - send_game - set_game_score - get_game_high_scores + - :meth:`~Client.get_inline_bot_results` + - :meth:`~Client.send_inline_bot_result` + - :meth:`~Client.answer_callback_query` + - :meth:`~Client.answer_inline_query` + - :meth:`~Client.request_callback_answer` + - :meth:`~Client.send_game` + - :meth:`~Client.set_game_score` + - :meth:`~Client.get_game_high_scores` + +----- + +Details +------- .. Utilities - --------- - -.. automethod:: pyrogram.Client.start() -.. automethod:: pyrogram.Client.stop() -.. automethod:: pyrogram.Client.restart() -.. automethod:: pyrogram.Client.idle() -.. automethod:: pyrogram.Client.run() -.. automethod:: pyrogram.Client.add_handler() -.. automethod:: pyrogram.Client.remove_handler() -.. automethod:: pyrogram.Client.send() -.. automethod:: pyrogram.Client.resolve_peer() -.. automethod:: pyrogram.Client.save_file() -.. automethod:: pyrogram.Client.stop_transmission() +.. automethod:: Client.start() +.. automethod:: Client.stop() +.. automethod:: Client.restart() +.. automethod:: Client.idle() +.. automethod:: Client.run() +.. automethod:: Client.add_handler() +.. automethod:: Client.remove_handler() +.. automethod:: Client.send() +.. automethod:: Client.resolve_peer() +.. automethod:: Client.save_file() +.. automethod:: Client.stop_transmission() .. Messages - -------- - -.. automethod:: pyrogram.Client.send_message() -.. automethod:: pyrogram.Client.forward_messages() -.. automethod:: pyrogram.Client.send_photo() -.. automethod:: pyrogram.Client.send_audio() -.. automethod:: pyrogram.Client.send_document() -.. automethod:: pyrogram.Client.send_sticker() -.. automethod:: pyrogram.Client.send_video() -.. automethod:: pyrogram.Client.send_animation() -.. automethod:: pyrogram.Client.send_voice() -.. automethod:: pyrogram.Client.send_video_note() -.. automethod:: pyrogram.Client.send_media_group() -.. automethod:: pyrogram.Client.send_location() -.. automethod:: pyrogram.Client.send_venue() -.. automethod:: pyrogram.Client.send_contact() -.. automethod:: pyrogram.Client.send_cached_media() -.. automethod:: pyrogram.Client.send_chat_action() -.. automethod:: pyrogram.Client.edit_message_text() -.. automethod:: pyrogram.Client.edit_message_caption() -.. automethod:: pyrogram.Client.edit_message_reply_markup() -.. automethod:: pyrogram.Client.edit_message_media() -.. automethod:: pyrogram.Client.delete_messages() -.. automethod:: pyrogram.Client.get_messages() -.. automethod:: pyrogram.Client.get_history() -.. automethod:: pyrogram.Client.get_history_count() -.. automethod:: pyrogram.Client.iter_history() -.. automethod:: pyrogram.Client.send_poll() -.. automethod:: pyrogram.Client.vote_poll() -.. automethod:: pyrogram.Client.stop_poll() -.. automethod:: pyrogram.Client.retract_vote() -.. automethod:: pyrogram.Client.download_media() +.. automethod:: Client.send_message() +.. automethod:: Client.forward_messages() +.. automethod:: Client.send_photo() +.. automethod:: Client.send_audio() +.. automethod:: Client.send_document() +.. automethod:: Client.send_sticker() +.. automethod:: Client.send_video() +.. automethod:: Client.send_animation() +.. automethod:: Client.send_voice() +.. automethod:: Client.send_video_note() +.. automethod:: Client.send_media_group() +.. automethod:: Client.send_location() +.. automethod:: Client.send_venue() +.. automethod:: Client.send_contact() +.. automethod:: Client.send_cached_media() +.. automethod:: Client.send_chat_action() +.. automethod:: Client.edit_message_text() +.. automethod:: Client.edit_message_caption() +.. automethod:: Client.edit_message_reply_markup() +.. automethod:: Client.edit_message_media() +.. automethod:: Client.delete_messages() +.. automethod:: Client.get_messages() +.. automethod:: Client.get_history() +.. automethod:: Client.get_history_count() +.. automethod:: Client.iter_history() +.. automethod:: Client.send_poll() +.. automethod:: Client.vote_poll() +.. automethod:: Client.stop_poll() +.. automethod:: Client.retract_vote() +.. automethod:: Client.download_media() .. Chats - ----- - -.. automethod:: pyrogram.Client.join_chat() -.. automethod:: pyrogram.Client.leave_chat() -.. automethod:: pyrogram.Client.kick_chat_member() -.. automethod:: pyrogram.Client.unban_chat_member() -.. automethod:: pyrogram.Client.restrict_chat_member() -.. automethod:: pyrogram.Client.promote_chat_member() -.. automethod:: pyrogram.Client.export_chat_invite_link() -.. automethod:: pyrogram.Client.set_chat_photo() -.. automethod:: pyrogram.Client.delete_chat_photo() -.. automethod:: pyrogram.Client.set_chat_title() -.. automethod:: pyrogram.Client.set_chat_description() -.. automethod:: pyrogram.Client.pin_chat_message() -.. automethod:: pyrogram.Client.unpin_chat_message() -.. automethod:: pyrogram.Client.get_chat() -.. automethod:: pyrogram.Client.get_chat_member() -.. automethod:: pyrogram.Client.get_chat_members() -.. automethod:: pyrogram.Client.get_chat_members_count() -.. automethod:: pyrogram.Client.iter_chat_members() -.. automethod:: pyrogram.Client.get_dialogs() -.. automethod:: pyrogram.Client.iter_dialogs() -.. automethod:: pyrogram.Client.get_dialogs_count() -.. automethod:: pyrogram.Client.restrict_chat() -.. automethod:: pyrogram.Client.update_chat_username() +.. automethod:: Client.join_chat() +.. automethod:: Client.leave_chat() +.. automethod:: Client.kick_chat_member() +.. automethod:: Client.unban_chat_member() +.. automethod:: Client.restrict_chat_member() +.. automethod:: Client.promote_chat_member() +.. automethod:: Client.export_chat_invite_link() +.. automethod:: Client.set_chat_photo() +.. automethod:: Client.delete_chat_photo() +.. automethod:: Client.set_chat_title() +.. automethod:: Client.set_chat_description() +.. automethod:: Client.pin_chat_message() +.. automethod:: Client.unpin_chat_message() +.. automethod:: Client.get_chat() +.. automethod:: Client.get_chat_member() +.. automethod:: Client.get_chat_members() +.. automethod:: Client.get_chat_members_count() +.. automethod:: Client.iter_chat_members() +.. automethod:: Client.get_dialogs() +.. automethod:: Client.iter_dialogs() +.. automethod:: Client.get_dialogs_count() +.. automethod:: Client.restrict_chat() +.. automethod:: Client.update_chat_username() .. Users - ----- - -.. automethod:: pyrogram.Client.get_me() -.. automethod:: pyrogram.Client.get_users() -.. automethod:: pyrogram.Client.get_user_profile_photos() -.. automethod:: pyrogram.Client.get_user_profile_photos_count() -.. automethod:: pyrogram.Client.set_user_profile_photo() -.. automethod:: pyrogram.Client.delete_user_profile_photos() -.. automethod:: pyrogram.Client.update_username() +.. automethod:: Client.get_me() +.. automethod:: Client.get_users() +.. automethod:: Client.get_user_profile_photos() +.. automethod:: Client.get_user_profile_photos_count() +.. automethod:: Client.set_user_profile_photo() +.. automethod:: Client.delete_user_profile_photos() +.. automethod:: Client.update_username() +.. automethod:: Client.get_user_dc() .. Contacts - -------- - -.. automethod:: pyrogram.Client.add_contacts() -.. automethod:: pyrogram.Client.get_contacts() -.. automethod:: pyrogram.Client.get_contacts_count() -.. automethod:: pyrogram.Client.delete_contacts() +.. automethod:: Client.add_contacts() +.. automethod:: Client.get_contacts() +.. automethod:: Client.get_contacts_count() +.. automethod:: Client.delete_contacts() .. Password - -------- - -.. automethod:: pyrogram.Client.enable_cloud_password() -.. automethod:: pyrogram.Client.change_cloud_password() -.. automethod:: pyrogram.Client.remove_cloud_password() +.. automethod:: Client.enable_cloud_password() +.. automethod:: Client.change_cloud_password() +.. automethod:: Client.remove_cloud_password() .. Bots - ---- - -.. automethod:: pyrogram.Client.get_inline_bot_results() -.. automethod:: pyrogram.Client.send_inline_bot_result() -.. automethod:: pyrogram.Client.answer_callback_query() -.. automethod:: pyrogram.Client.answer_inline_query() -.. automethod:: pyrogram.Client.request_callback_answer() -.. automethod:: pyrogram.Client.send_game() -.. automethod:: pyrogram.Client.set_game_score() -.. automethod:: pyrogram.Client.get_game_high_scores() +.. automethod:: Client.get_inline_bot_results() +.. automethod:: Client.send_inline_bot_result() +.. automethod:: Client.answer_callback_query() +.. automethod:: Client.answer_inline_query() +.. automethod:: Client.request_callback_answer() +.. automethod:: Client.send_game() +.. automethod:: Client.set_game_score() +.. automethod:: Client.get_game_high_scores() diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index d911520c..d264eaa2 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -15,102 +15,108 @@ All Pyrogram types listed here are accessible through the main package directly. .. currentmodule:: pyrogram +Index +----- + Users & Chats -------------- +^^^^^^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 5 - User - UserStatus - Chat - ChatPreview - ChatPhoto - ChatMember - ChatMembers - ChatPermissions - Dialog - Dialogs + - :class:`User` + - :class:`UserStatus` + - :class:`Chat` + - :class:`ChatPreview` + - :class:`ChatPhoto` + - :class:`ChatMember` + - :class:`ChatMembers` + - :class:`ChatPermissions` + - :class:`Dialog` + - :class:`Dialogs` Messages & Media ----------------- +^^^^^^^^^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 5 - Message - Messages - MessageEntity - Photo - PhotoSize - UserProfilePhotos - Audio - Document - Animation - Video - Voice - VideoNote - Contact - Location - Venue - Sticker - Game - Poll - PollOption + - :class:`Message` + - :class:`Messages` + - :class:`MessageEntity` + - :class:`Photo` + - :class:`PhotoSize` + - :class:`UserProfilePhotos` + - :class:`Audio` + - :class:`Document` + - :class:`Animation` + - :class:`Video` + - :class:`Voice` + - :class:`VideoNote` + - :class:`Contact` + - :class:`Location` + - :class:`Venue` + - :class:`Sticker` + - :class:`Game` + - :class:`Poll` + - :class:`PollOption` Keyboards ---------- +^^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 4 - ReplyKeyboardMarkup - KeyboardButton - ReplyKeyboardRemove - InlineKeyboardMarkup - InlineKeyboardButton - ForceReply - CallbackQuery - GameHighScore - GameHighScores - CallbackGame + - :class:`ReplyKeyboardMarkup` + - :class:`KeyboardButton` + - :class:`ReplyKeyboardRemove` + - :class:`InlineKeyboardMarkup` + - :class:`InlineKeyboardButton` + - :class:`ForceReply` + - :class:`CallbackQuery` + - :class:`GameHighScore` + - :class:`GameHighScores` + - :class:`CallbackGame` Input Media ------------ +^^^^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 4 - InputMedia - InputMediaPhoto - InputMediaVideo - InputMediaAudio - InputMediaAnimation - InputMediaDocument - InputPhoneContact + - :class:`InputMedia` + - :class:`InputMediaPhoto` + - :class:`InputMediaVideo` + - :class:`InputMediaAudio` + - :class:`InputMediaAnimation` + - :class:`InputMediaDocument` + - :class:`InputPhoneContact` Inline Mode ------------- +^^^^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 3 - InlineQuery - InlineQueryResult - InlineQueryResultArticle + - :class:`InlineQuery` + - :class:`InlineQueryResult` + - :class:`InlineQueryResultArticle` InputMessageContent -------------------- +^^^^^^^^^^^^^^^^^^^ -.. autosummary:: - :nosignatures: +.. hlist:: + :columns: 3 - InputMessageContent - InputTextMessageContent + - :class:`InputMessageContent` + - :class:`InputTextMessageContent` + +----- + +Details +------- .. User & Chats - ------------ - .. autoclass:: User() .. autoclass:: UserStatus() .. autoclass:: Chat() @@ -123,8 +129,6 @@ InputMessageContent .. autoclass:: Dialogs() .. Messages & Media - ---------------- - .. autoclass:: Message() .. autoclass:: Messages() .. autoclass:: MessageEntity() @@ -146,8 +150,6 @@ InputMessageContent .. autoclass:: PollOption() .. Keyboards - --------- - .. autoclass:: ReplyKeyboardMarkup() .. autoclass:: KeyboardButton() .. autoclass:: ReplyKeyboardRemove() @@ -160,8 +162,6 @@ InputMessageContent .. autoclass:: CallbackGame() .. Input Media - ----------- - .. autoclass:: InputMedia() .. autoclass:: InputMediaPhoto() .. autoclass:: InputMediaVideo() @@ -171,14 +171,10 @@ InputMessageContent .. autoclass:: InputPhoneContact() .. Inline Mode - ----------- - .. autoclass:: InlineQuery() .. autoclass:: InlineQueryResult() .. autoclass:: InlineQueryResultArticle() .. InputMessageContent - ------------------- - .. autoclass:: InputMessageContent() .. autoclass:: InputTextMessageContent() diff --git a/docs/source/conf.py b/docs/source/conf.py index e079ec68..7ddeaa94 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -43,7 +43,6 @@ autodoc_member_order = "bysource" version = __version__ release = version -version_rst = ".. |version| replace:: {}".format(version) templates_path = ["_templates"] @@ -61,7 +60,8 @@ html_theme_options = { "collapse_navigation": True, "sticky_navigation": False, "logo_only": True, - "display_version": True + "display_version": True, + "style_external_links": True } html_logo = "_images/pyrogram.png" diff --git a/docs/source/faq.rst b/docs/source/faq.rst index b42332cd..7d7e9032 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -17,10 +17,9 @@ What is Pyrogram? **Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and C. It enables you to easily create custom applications for both user and bot identities (bot API alternative) via the -`MTProto API`_ with the Python programming language. +:doc:`MTProto API ` with the Python programming language. .. _Telegram: https://telegram.org -.. _MTProto API: topics/mtproto-vs-botapi#what-is-the-mtproto-api Where does the name come from? ------------------------------ @@ -47,19 +46,17 @@ Why Pyrogram? - **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. - **Updated**, to make use of the latest Telegram API version and features. - **Bot API-like**: Similar to the Bot API in its simplicity, but much more powerful and detailed. -- **Pluggable**: The `Smart Plugin`_ system allows to write components with minimal boilerplate code. -- **Comprehensive**: Execute any `advanced action`_ an official client is able to do, and even more. +- **Pluggable**: The :doc:`Smart Plugin ` system allows to write components with minimal + boilerplate code. +- **Comprehensive**: Execute any :doc:`advanced action ` an official client is able to do, and + even more. .. _TgCrypto: https://github.com/pyrogram/tgcrypto -.. _Smart Plugin: topics/smart-plugins -.. _advanced action: topics/advanced-usage What can MTProto do more than the Bot API? ------------------------------------------ -For a detailed answer, please refer to the `MTProto vs. Bot API`_ page. - -.. _MTProto vs. Bot API: topics/mtproto-vs-botapi +For a detailed answer, please refer to the :doc:`MTProto vs. Bot API ` page. Why do I need an API key for bots? ---------------------------------- @@ -97,9 +94,9 @@ Telegram is slowly changing some server's internals and it's doing it in such a inevitably. Not only this, but it seems that the new, hypothetical, file ids could also possibly expire at anytime, thus losing the *persistence* feature. -This change will most likely affect the official `Bot API `_ too -(unless Telegram implements some workarounds server-side to keep backwards compatibility, which Pyrogram could in turn -make use of) and we can expect a proper notice from Telegram. +This change will most likely affect the official :doc:`Bot API ` too (unless Telegram +implements some workarounds server-side to keep backwards compatibility, which Pyrogram could in turn make use of) and +we can expect a proper notice from Telegram. Can I use multiple clients at once on the same account? ------------------------------------------------------- @@ -125,8 +122,8 @@ from the beginning every time, and use one separate session for each parallel cl I started a client and nothing happens! --------------------------------------- -If you are connecting from Russia, China or Iran `you need a proxy`_, because Telegram could be partially or -totally blocked in those countries. +If you are connecting from Russia, China or Iran :doc:`you need a proxy `, because Telegram could be +partially or totally blocked in those countries. Another possible cause might be network issues, either yours or Telegram's. To confirm this, add the following code on the top of your script and run it again. You should see some error mentioning a socket timeout or an unreachable network @@ -146,8 +143,6 @@ fails or not: - DC4: ``149.154.167.91`` - DC5: ``91.108.56.149`` -.. _you need a proxy: topics/proxy - I keep getting PEER_ID_INVALID error! ------------------------------------------- @@ -182,20 +177,5 @@ recover@telegram.org, contact `@smstelegram`_ on Twitter or use `this form`_. .. _@smstelegram: https://twitter.com/smstelegram .. _this form: https://telegram.org/support -About the License ------------------ - -.. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png - :align: left - -Pyrogram is free software and is currently licensed under the terms of the -`GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it -provided that modifications are described and licensed for free under LGPLv3+. - -In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or -different license, or even proprietary --- without being required to release the source code of your own applications. -However, any modifications to the library itself are required to be published for free under the same LGPLv3+ license. - -.. _GNU Lesser General Public License v3 or later (LGPLv3+): https://github.com/pyrogram/pyrogram/blob/develop/COPYING.lesser .. _Bug Report: https://github.com/pyrogram/pyrogram/issues/new?labels=bug&template=bug_report.md .. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst index 5f00cbfd..72d308b7 100644 --- a/docs/source/glossary.rst +++ b/docs/source/glossary.rst @@ -18,7 +18,7 @@ general. Some words may as well link to dedicated articles in case the topic is API key A secret code used to authenticate and/or authorize a specific application to Telegram in order for it to control how the API is being used, for example, to prevent abuses of the API. - `More on API keys `_. + :doc:`More on API keys `. DC Also known as *data center*, is a place where lots of computer systems are housed and used together in order to @@ -30,21 +30,21 @@ general. Some words may as well link to dedicated articles in case the topic is RPCError An error caused by an RPC which must be returned in place of the successful result in order to let the caller - know something went wrong. `More on RPCError `_. + know something went wrong. :doc:`More on RPCError `. MTProto The name of the custom-made, open and encrypted protocol by Telegram, implemented in Pyrogram. - `More on MTProto `_. + :doc:`More on MTProto `. MTProto API The Telegram main API Pyrogram makes use of, which is able to connect both users and normal bots to Telegram using MTProto as application layer protocol and execute any method Telegram provides from its public TL-schema. - `More on MTProto API `_. + :doc:`More on MTProto API `. Bot API The Telegram Bot API that is able to only connect normal bots only to Telegram using HTTP as application layer protocol and allows to execute a sub-set of the main Telegram API. - `More on Bot API `_. + :doc:`More on Bot API `. Pyrogrammer A developer that uses Pyrogram to build Telegram applications. @@ -65,11 +65,11 @@ general. Some words may as well link to dedicated articles in case the topic is Handler An object that wraps around a callback function that is *actually meant* to be registered into the framework, which will then be able to handle a specific kind of events, such as a new incoming message, for example. - `More on Handlers `_. + :doc:`More on Handlers `. Decorator Also known as *function decorator*, in Python, is a callable object that is used to modify another function. Decorators in Pyrogram are used to automatically register callback functions for handling updates. - `More on Decorators `_. + :doc:`More on Decorators `. .. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md diff --git a/docs/source/index.rst b/docs/source/index.rst index de91015f..b99fcf3d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -42,10 +42,9 @@ Welcome to Pyrogram **Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and C. It enables you to easily create custom apps for both user and bot identities (bot API alternative) via the -`MTProto API`_. +:doc:`MTProto API `. .. _Telegram: https://telegram.org -.. _MTProto API: topics/mtproto-vs-botapi#what-is-the-mtproto-api How the Documentation is Organized ---------------------------------- @@ -60,15 +59,10 @@ First Steps .. hlist:: :columns: 2 - - `Quick Start`_: Overview to get you started quickly. - - `Calling Methods`_: How to call Pyrogram's methods. - - `Handling Updates`_: How to handle Telegram updates. - - `Error Handling`_: How to handle API errors correctly. - -.. _Quick Start: intro/quickstart -.. _Calling Methods: start/invoking -.. _Handling Updates: start/updates -.. _Error Handling: start/errors + - :doc:`Quick Start `: Overview to get you started quickly. + - :doc:`Calling Methods `: How to call Pyrogram's methods. + - :doc:`Handling Updates `: How to handle Telegram updates. + - :doc:`Error Handling `: How to handle API errors correctly. API Reference ------------- @@ -76,15 +70,10 @@ API Reference .. hlist:: :columns: 2 - - `Pyrogram Client`_: Reference details about the Client class. - - `Available Methods`_: List of available high-level methods. - - `Available Types`_: List of available high-level types. - - `Bound Methods`_: List of convenient bound methods. - -.. _Pyrogram Client: ./api/client -.. _Available Methods: api/methods -.. _Available Types: api/types -.. _Bound Methods: api/bound-methods + - :doc:`Pyrogram Client `: Reference details about the Client class. + - :doc:`Available Methods `: List of available high-level methods. + - :doc:`Available Types `: List of available high-level types. + - :doc:`Bound Methods `: List of convenient bound methods. Meta ---- @@ -92,17 +81,12 @@ Meta .. hlist:: :columns: 2 - - `Pyrogram FAQ`_: Answers to common Pyrogram questions. - - `Pyrogram Glossary`_: List of words with brief explanations. - - `Release Notes`_: Release notes for Pyrogram releases. - - `Powered by Pyrogram`_: Collection of Pyrogram Projects. - - `Support Pyrogram`_: Ways to show your appreciation. - -.. _Pyrogram FAQ: faq -.. _Pyrogram Glossary: glossary -.. _Release Notes: releases -.. _Powered by Pyrogram: powered-by -.. _Support Pyrogram: support-pyrogram + - :doc:`Pyrogram FAQ `: Answers to common Pyrogram questions. + - :doc:`Pyrogram Glossary `: List of words with brief explanations. + - :doc:`Release Notes `: Release notes for Pyrogram releases. + - :doc:`Powered by Pyrogram `: Collection of Pyrogram Projects. + - :doc:`Support Pyrogram `: Ways to show your appreciation. + - :doc:`About the License `: Information about the Project license. .. toctree:: :hidden: @@ -163,10 +147,13 @@ Meta releases powered-by support-pyrogram + license .. toctree:: :hidden: :caption: Telegram API telegram/functions/index - telegram/types/index \ No newline at end of file + telegram/types/index + +Last updated on |today| \ No newline at end of file diff --git a/docs/source/intro/install.rst b/docs/source/intro/install.rst index fe804e79..82ab4c0b 100644 --- a/docs/source/intro/install.rst +++ b/docs/source/intro/install.rst @@ -20,7 +20,7 @@ Install Pyrogram $ pip3 install -U pyrogram -- or, with TgCrypto_ as extra requirement (recommended): +- or, with :doc:`TgCrypto <../topics/tgcrypto>` as extra requirement (recommended): .. code-block:: text @@ -89,5 +89,4 @@ If no error shows up you are good to go. >>> pyrogram.__version__ '|version|' -.. _TgCrypto: ../topics/tgcrypto .. _`Github repo`: http://github.com/pyrogram/pyrogram diff --git a/docs/source/intro/quickstart.rst b/docs/source/intro/quickstart.rst index 1aa7989e..a7a7e377 100644 --- a/docs/source/intro/quickstart.rst +++ b/docs/source/intro/quickstart.rst @@ -43,7 +43,7 @@ Enjoy the API That was just a quick overview that barely scratched the surface! In the next few pages of the introduction, we'll take a much more in-depth look of what we have just done above. -Feeling eager to continue? You can take a shortcut to `Calling Methods`_ and come back later to learn some more details. +Feeling eager to continue? You can take a shortcut to :doc:`Calling Methods <../start/invoking>` and come back later to +learn some more details. .. _community: //t.me/Pyrogram -.. _Calling Methods: ../start/invoking \ No newline at end of file diff --git a/docs/source/intro/setup.rst b/docs/source/intro/setup.rst index 9c0cc6d4..6273b2b2 100644 --- a/docs/source/intro/setup.rst +++ b/docs/source/intro/setup.rst @@ -1,8 +1,8 @@ Project Setup ============= -We have just `installed Pyrogram`_. In this page we'll discuss what you need to do in order to set up a project with -the library. Let's see how it's done. +We have just :doc:`installed Pyrogram `. In this page we'll discuss what you need to do in order to set up a +project with the library. Let's see how it's done. API Keys -------- @@ -26,7 +26,7 @@ The very first step requires you to obtain a valid Telegram API key (API id/hash Configuration ------------- -Having the API key from the `previous step <#api-keys>`_ in handy, we can now begin to configure a Pyrogram project. +Having the API key from the previous step in handy, we can now begin to configure a Pyrogram project. There are two ways to do so, and you can choose what fits better for you: - First option (recommended): create a new ``config.ini`` file at the root of your working directory, copy-paste the @@ -57,5 +57,3 @@ There are two ways to do so, and you can choose what fits better for you: To keep code snippets clean and concise, from now on it is assumed you are making use of the ``config.ini`` file, thus, the *api_id* and *api_hash* parameters usage won't be shown anymore. - -.. _installed Pyrogram: install.html diff --git a/docs/source/license.rst b/docs/source/license.rst new file mode 100644 index 00000000..1c8d99d1 --- /dev/null +++ b/docs/source/license.rst @@ -0,0 +1,15 @@ +About the License +================= + +.. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png + :align: left + +Pyrogram is free software and is currently licensed under the terms of the +`GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it +provided that modifications are described and licensed for free under LGPLv3+. + +In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or +different license, or even proprietary --- without being required to release the source code of your own applications. +However, any modifications to the library itself are required to be published for free under the same LGPLv3+ license. + +.. _GNU Lesser General Public License v3 or later (LGPLv3+): https://github.com/pyrogram/pyrogram/blob/develop/COPYING.lesser \ No newline at end of file diff --git a/docs/source/start/auth.rst b/docs/source/start/auth.rst index e00b08a0..79264bfa 100644 --- a/docs/source/start/auth.rst +++ b/docs/source/start/auth.rst @@ -1,7 +1,7 @@ Authorization ============= -Once a `project is set up`_, you will still have to follow a few steps before you can actually use Pyrogram to make +Once a :doc:`project is set up <../intro/setup>`, you will still have to follow a few steps before you can actually use Pyrogram to make API calls. This section provides all the information you need in order to authorize yourself as user or bot. User Authorization @@ -9,8 +9,8 @@ User Authorization In order to use the API, Telegram requires that users be authorized via their phone numbers. Pyrogram automatically manages this process, all you need to do is create an instance of the -:class:`Client ` class by passing to it a ``session_name`` of your choice (e.g.: "my_account") and call -the :meth:`run() ` method: +:class:`~pyrogram.Client` class by passing to it a ``session_name`` of your choice (e.g.: "my_account") and call +the :meth:`~pyrogram.Client.run` method: .. code-block:: python @@ -47,7 +47,7 @@ Bot Authorization Bots are a special kind of users that are authorized via their tokens (instead of phone numbers), which are created by the `Bot Father`_. Bot tokens replace the users' phone numbers only — you still need to -`configure a Telegram API key <../intro/setup#configuration>`_ with Pyrogram, even when using bots. +:doc:`configure a Telegram API key <../intro/setup>` with Pyrogram, even when using bots. The authorization process is automatically managed. All you need to do is choose a ``session_name`` (can be anything, usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named @@ -64,6 +64,5 @@ after the session name, which will be ``my_bot.session`` for the example below. app.run() -.. _project is set up: ../intro/setup .. _Country Code: https://en.wikipedia.org/wiki/List_of_country_calling_codes .. _Bot Father: https://t.me/botfather \ No newline at end of file diff --git a/docs/source/start/invoking.rst b/docs/source/start/invoking.rst index ef9bc373..1357cd7b 100644 --- a/docs/source/start/invoking.rst +++ b/docs/source/start/invoking.rst @@ -1,8 +1,8 @@ Calling Methods =============== -At this point, we have successfully `installed Pyrogram`_ and authorized_ our account; we are now aiming towards the -core of the library. It's time to start playing with the API! +At this point, we have successfully :doc:`installed Pyrogram <../intro/install>` and :doc:`authorized ` our +account; we are now aiming towards the core of the library. It's time to start playing with the API! Basic Usage ----------- @@ -63,8 +63,8 @@ Context Manager --------------- You can also use Pyrogram's Client in a context manager with the ``with`` statement. The client will automatically -:meth:`start() ` and :meth:`stop() ` gracefully, even in case of unhandled -exceptions in your code. The example above can be therefore rewritten in a much nicer way: +:meth:`~pyrogram.Client.start` and :meth:`~pyrogram.Client.stop` gracefully, even in case of unhandled exceptions in +your code. The example above can be therefore rewritten in a much nicer way: .. code-block:: python @@ -79,6 +79,3 @@ exceptions in your code. The example above can be therefore rewritten in a much app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") More examples can be found on `GitHub `_. - -.. _installed Pyrogram: ../intro/install.html -.. _authorized: ../intro/setup.html diff --git a/docs/source/start/updates.rst b/docs/source/start/updates.rst index a0f2ca0c..b6838ad3 100644 --- a/docs/source/start/updates.rst +++ b/docs/source/start/updates.rst @@ -1,8 +1,8 @@ Handling Updates ================ -Calling `API methods`_ sequentially is cool, but how to react when, for example, a new message arrives? This page deals -with updates and how to handle such events in Pyrogram. Let's have a look at how they work. +Calling :doc:`API methods ` sequentially is cool, but how to react when, for example, a new message arrives? +This page deals with updates and how to handle such events in Pyrogram. Let's have a look at how they work. Defining Updates ---------------- @@ -10,7 +10,7 @@ Defining Updates First, let's define what are these updates. As hinted already, updates are simply events that happen in your Telegram account (incoming messages, new members join, bot button presses, etc...), which are meant to notify you about a new specific state that has changed. These updates are handled by registering one or more callback functions in your app -using `Handlers <../api/handlers>`_. +using :doc:`Handlers <../api/handlers>`. Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback function will be called back by the framework and its body executed. @@ -18,17 +18,16 @@ function will be called back by the framework and its body executed. Registering a Handler --------------------- -To explain how handlers work let's have a look at the most used one, the -:obj:`MessageHandler `, which will be in charge for handling :obj:`Message ` -updates coming from all around your chats. Every other handler shares the same setup logic; you should not have troubles -settings them up once you learn from this section. +To explain how handlers work let's have a look at the most used one, the :class:`~pyrogram.MessageHandler`, which will +be in charge for handling :class:`~pyrogram.Message` updates coming from all around your chats. Every other handler shares +the same setup logic; you should not have troubles settings them up once you learn from this section. Using add_handler() ------------------- -The :meth:`add_handler() ` method takes any handler instance that wraps around your defined -callback function and registers it in your Client. Here's a full example that prints out the content of a message as -soon as it arrives: +The :meth:`~pyrogram.Client.add_handler` method takes any handler instance that wraps around your defined callback +function and registers it in your Client. Here's a full example that prints out the content of a message as soon as it +arrives: .. code-block:: python @@ -55,24 +54,23 @@ call that function by passing the client instance and the new message instance a def my_function(client, message): print(message) -Second one: the :obj:`MessageHandler `. This object tells Pyrogram the function we defined -above must only handle updates that are in form of a :obj:`Message `: +Second one: the :class:`~pyrogram.MessageHandler`. This object tells Pyrogram the function we defined above must only +handle updates that are in form of a :class:`~pyrogram.Message`: .. code-block:: python my_handler = MessageHandler(my_function) -Third: the method :meth:`add_handler() `. This method is used to actually register the -handler and let Pyrogram know it needs to be taken into consideration when new updates arrive and the internal -dispatching phase begins. +Third: the method :meth:`~pyrogram.Client.add_handler`. This method is used to actually register the handler and let +Pyrogram know it needs to be taken into consideration when new updates arrive and the internal dispatching phase begins. .. code-block:: python app.add_handler(my_handler) -Last one, the :meth:`run() ` method. What this does is simply call -:meth:`start() ` and a special method :meth:`idle() ` that keeps your main -scripts alive until you press ``CTRL+C``; the client will be automatically stopped after that. +Last one, the :meth:`~pyrogram.Client.run` method. What this does is simply call :meth:`~pyrogram.Client.start` and a +special method :meth:`~pyrogram.Client.idle` that keeps your main scripts alive until you press ``CTRL+C``; the client +will be automatically stopped after that. .. code-block:: python @@ -82,7 +80,7 @@ Using Decorators ---------------- All of the above will become quite verbose, especially in case you have lots of handlers to register. A much nicer way -to do so is by decorating your callback function with the :meth:`on_message() ` decorator. +to do so is by decorating your callback function with the :meth:`~pyrogram.Client.on_message` decorator. .. code-block:: python @@ -108,5 +106,3 @@ to do so is by decorating your callback function with the :meth:`on_message()

` and facade +:doc:`types <../api/types>`, exists to provide a much easier interface to the undocumented and often confusing Telegram +API. In this section, you'll be shown the alternative way of communicating with Telegram using Pyrogram: the main "raw" Telegram API with its functions and types. @@ -11,7 +12,7 @@ Telegram Raw API ---------------- If you can't find a high-level method for your needs or if you want complete, low-level access to the whole -Telegram API, you have to use the raw :mod:`functions ` and :mod:`types `. +Telegram API, you have to use the raw :mod:`~pyrogram.api.functions` and :mod:`~pyrogram.api.types`. As already hinted, raw functions and types can be really confusing, mainly because people don't realize soon enough they accept *only* the right types and that all required parameters must be filled in. This section will therefore explain @@ -21,24 +22,25 @@ some pitfalls to take into consideration when working with the raw API. Every available high-level methods in Pyrogram is built on top of these raw functions. - Nothing stops you from using the raw functions only, but they are rather complex and `plenty of them`_ are already - re-implemented by providing a much simpler and cleaner interface which is very similar to the Bot API (yet much more - powerful). + Nothing stops you from using the raw functions only, but they are rather complex and + :doc:`plenty of them <../api/methods>` are already re-implemented by providing a much simpler and cleaner interface + which is very similar to the Bot API (yet much more powerful). If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_! Invoking Functions ^^^^^^^^^^^^^^^^^^ -Unlike the methods_ found in Pyrogram's API, which can be called in the usual simple way, functions to be invoked from -the raw Telegram API have a different way of usage and are more complex. +Unlike the :doc:`methods <../api/methods>` found in Pyrogram's API, which can be called in the usual simple way, +functions to be invoked from the raw Telegram API have a different way of usage and are more complex. -First of all, both `raw functions`_ and `raw types`_ live in their respective packages (and sub-packages): -``pyrogram.api.functions``, ``pyrogram.api.types``. They all exist as Python classes, meaning you need to create an -instance of each every time you need them and fill them in with the correct values using named arguments. +First of all, both :doc:`raw functions <../telegram/functions/index>` and :doc:`raw types <../telegram/types/index>` live in their +respective packages (and sub-packages): ``pyrogram.api.functions``, ``pyrogram.api.types``. They all exist as Python +classes, meaning you need to create an instance of each every time you need them and fill them in with the correct +values using named arguments. -Next, to actually invoke the raw function you have to use the :meth:`send() ` method provided by -the Client class and pass the function object you created. +Next, to actually invoke the raw function you have to use the :meth:`~pyrogram.Client.send` method provided by the +Client class and pass the function object you created. Here's some examples: @@ -101,12 +103,12 @@ sending messages with IDs only thanks to cached access hashes. There are three different InputPeer types, one for each kind of Telegram entity. Whenever an InputPeer is needed you must pass one of these: - - :obj:`InputPeerUser <../telegram/types/InputPeerUser>` - Users - - :obj:`InputPeerChat <../telegram/types/InputPeerChat>` - Basic Chats - - :obj:`InputPeerChannel <../telegram/types/InputPeerChannel>` - Either Channels or Supergroups + - :class:`~pyrogram.api.types.InputPeerUser` - Users + - :class:`~pyrogram.api.types.InputPeerChat` - Basic Chats + - :class:`~pyrogram.api.types.InputPeerChannel` - Either Channels or Supergroups But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides -:meth:`resolve_peer() ` as a convenience utility method that returns the correct InputPeer +:meth:`~pyrogram.Client.resolve_peer` as a convenience utility method that returns the correct InputPeer by accepting a peer ID only. Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and @@ -125,9 +127,4 @@ For example, given the ID *123456789*, here's how Pyrogram can tell entities apa So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an high-level method. -.. _methods: ../api/methods -.. _types: ../api/types -.. _plenty of them: ../api/methods -.. _raw functions: ../telegram/functions -.. _raw types: ../telegram/types .. _Community: https://t.me/Pyrogram \ No newline at end of file diff --git a/docs/source/topics/auto-auth.rst b/docs/source/topics/auto-auth.rst index b5f3a94a..abeaf1fb 100644 --- a/docs/source/topics/auto-auth.rst +++ b/docs/source/topics/auto-auth.rst @@ -3,7 +3,7 @@ Auto Authorization Manually writing phone number, phone code and password on the terminal every time you want to login can be tedious. Pyrogram is able to automate both **Log In** and **Sign Up** processes, all you need to do is pass the relevant -parameters when creating a new :class:`Client `. +parameters when creating a new :class:`~pyrogram.Client`. .. note:: If you omit any of the optional parameter required for the authorization, Pyrogram will ask you to manually write it. For instance, if you don't want to set a ``last_name`` when creating a new account you diff --git a/docs/source/topics/bots-interaction.rst b/docs/source/topics/bots-interaction.rst index de7925a2..ad993050 100644 --- a/docs/source/topics/bots-interaction.rst +++ b/docs/source/topics/bots-interaction.rst @@ -7,8 +7,7 @@ Inline Bots ----------- - If a bot accepts inline queries, you can call it by using - :meth:`get_inline_bot_results() ` to get the list of its inline results - for a query: + :meth:`~pyrogram.Client.get_inline_bot_results` to get the list of its inline results for a query: .. code-block:: python @@ -24,7 +23,7 @@ Inline Bots results list. - After you retrieved the bot results, you can use - :meth:`send_inline_bot_result() ` to send a chosen result to any chat: + :meth:`~pyrogram.Client.send_inline_bot_result` to send a chosen result to any chat: .. code-block:: python diff --git a/docs/source/topics/filters.rst b/docs/source/topics/filters.rst index cb2e2a4c..7ff02ffc 100644 --- a/docs/source/topics/filters.rst +++ b/docs/source/topics/filters.rst @@ -4,7 +4,7 @@ Using Filters So far we've seen how to register a callback function that executes every time a specific update comes from the server, but there's much more than that to come. -Here we'll discuss about :class:`Filters `. Filters enable a fine-grain control over what kind of +Here we'll discuss about :class:`~pyrogram.Filters`. Filters enable a fine-grain control over what kind of updates are allowed or not to be passed in your callback functions, based on their inner details. Single Filters @@ -12,7 +12,7 @@ Single Filters Let's start right away with a simple example: -- This example will show you how to **only** handle messages containing an :obj:`Audio ` object and +- This example will show you how to **only** handle messages containing an :class:`~pyrogram.Audio` object and ignore any other message. Filters are passed as the first argument of the decorator: .. code-block:: python @@ -69,7 +69,7 @@ Here are some examples: Advanced Filters ---------------- -Some filters, like :meth:`command() ` or :meth:`regex() ` +Some filters, like :meth:`~pyrogram.Filters.command` or :meth:`~pyrogram.Filters.regex` can also accept arguments: - Message is either a */start* or */help* **command**. @@ -109,18 +109,18 @@ More handlers using different filters can also live together. Custom Filters -------------- -Pyrogram already provides lots of built-in :class:`Filters ` to work with, but in case you can't find +Pyrogram already provides lots of built-in :class:`~pyrogram.Filters` to work with, but in case you can't find a specific one for your needs or want to build a custom filter by yourself (to be used in a different kind of handler, -for example) you can use :meth:`Filters.create() `. +for example) you can use :meth:`~pyrogram.Filters.create`. .. note:: - At the moment, the built-in filters are intended to be used with the :obj:`MessageHandler ` - only. + + At the moment, the built-in filters are intended to be used with the :class:`~pyrogram.MessageHandler` only. An example to demonstrate how custom filters work is to show how to create and use one for the -:obj:`CallbackQueryHandler `. Note that callback queries updates are only received by -bots; create and `authorize your bot <../start/Setup.html#bot-authorization>`_, then send a message with an inline -keyboard to yourself. This allows you to test your filter by pressing the inline button: +:class:`~pyrogram.CallbackQueryHandler`. Note that callback queries updates are only received by bots; create and +:doc:`authorize your bot <../start/auth>`, then send a message with an inline keyboard to yourself. This allows you to +test your filter by pressing the inline button: .. code-block:: python @@ -137,7 +137,7 @@ keyboard to yourself. This allows you to test your filter by pressing the inline Basic Filters ^^^^^^^^^^^^^ -For this basic filter we will be using only the first two parameters of :meth:`Filters.create() `. +For this basic filter we will be using only the first two parameters of :meth:`~pyrogram.Filters.create`. The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries containing "Pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data @@ -175,7 +175,7 @@ Filters with Arguments ^^^^^^^^^^^^^^^^^^^^^^ A much cooler filter would be one that accepts "Pyrogram" or any other data as argument at usage time. -A dynamic filter like this will make use of the third parameter of :meth:`Filters.create() `. +A dynamic filter like this will make use of the third parameter of :meth:`~pyrogram.Filters.create`. This is how a dynamic custom filter looks like: diff --git a/docs/source/topics/more-on-updates.rst b/docs/source/topics/more-on-updates.rst index cb319ee1..c3737b38 100644 --- a/docs/source/topics/more-on-updates.rst +++ b/docs/source/topics/more-on-updates.rst @@ -1,7 +1,8 @@ More on Updates =============== -Here we'll show some advanced usages when working with `update handlers`_ and `filters`_. +Here we'll show some advanced usages when working with :doc:`update handlers <../start/updates>` and +:doc:`filters `. Handler Groups -------------- @@ -44,7 +45,7 @@ Or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``- def just_text(client, message): print("Just Text") -With :meth:`add_handler() ` (without decorators) the same can be achieved with: +With :meth:`~pyrogram.Client.add_handler` (without decorators) the same can be achieved with: .. code-block:: python @@ -217,6 +218,3 @@ The output of both (equivalent) examples will be: 0 1 2 - -.. _`update handlers`: ../start/updates -.. _`filters`: filters \ No newline at end of file diff --git a/docs/source/topics/serialize.rst b/docs/source/topics/serialize.rst index 32208199..a238f8dc 100644 --- a/docs/source/topics/serialize.rst +++ b/docs/source/topics/serialize.rst @@ -9,7 +9,8 @@ For Humans - str(obj) --------------------- If you want a nicely formatted, human readable JSON representation of any object in the API -- namely, any object from -`Pyrogram types`_, `raw functions`_ and `raw types`_ -- you can use use ``str(obj)``. +:doc:`Pyrogram types <../api/types>`, :doc:`raw functions <../telegram/functions/index>` and +:doc:`raw types <../telegram/types/index>` -- you can use use ``str(obj)``. .. code-block:: python @@ -25,10 +26,6 @@ If you want a nicely formatted, human readable JSON representation of any object When using ``print()`` you don't actually need to use ``str()`` on the object because it is called automatically, we have done that above just to show you how to explicitly convert a Pyrogram object to JSON. -.. _Pyrogram types: ../api/types -.. _raw functions: ../telegram/functions -.. _raw types: ../telegram/types - For Machines - repr(obj) ------------------------ diff --git a/docs/source/topics/session-settings.rst b/docs/source/topics/session-settings.rst index 91e3f050..dd777bda 100644 --- a/docs/source/topics/session-settings.rst +++ b/docs/source/topics/session-settings.rst @@ -5,7 +5,7 @@ As you may probably know, Telegram allows users (and bots) having more than one in the system at the same time. Briefly explaining, sessions are simply new logins in your account. They can be reviewed in the settings of an official -app (or by invoking `GetAuthorizations <../telegram/functions/account/GetAuthorizations.html>`_ with Pyrogram). They +app (or by invoking :class:`~pyrogram.api.functions.account.GetAuthorizations` with Pyrogram). They store some useful information such as the client who's using them and from which country and IP address. .. figure:: https://i.imgur.com/YaqtMLO.png diff --git a/docs/source/topics/smart-plugins.rst b/docs/source/topics/smart-plugins.rst index 9f1592d1..8e59b971 100644 --- a/docs/source/topics/smart-plugins.rst +++ b/docs/source/topics/smart-plugins.rst @@ -65,8 +65,8 @@ after importing your modules, like this: app.run() This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to -manually ``import``, manually :meth:`add_handler() ` and manually instantiate each -:obj:`MessageHandler ` object because **you can't use those cool decorators** for your +manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each +:class:`~pyrogram.MessageHandler` object because **you can't use those cool decorators** for your functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically. Using Smart Plugins @@ -80,7 +80,7 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight .. note:: - This is the same example application `as shown above <#introduction>`_, written using the Smart Plugin system. + This is the same example application as shown above, written using the Smart Plugin system. .. code-block:: text :emphasize-lines: 2, 3 @@ -156,7 +156,7 @@ found inside each module will be, instead, loaded in the order they are defined, .. note:: Remember: there can be at most one handler, within a group, dealing with a specific update. Plugins with overlapping - filters included a second time will not work. Learn more at `More on Updates `_. + filters included a second time will not work. Learn more at :doc:`More on Updates `. This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude`` @@ -288,9 +288,8 @@ also organized in subfolders: Load/Unload Plugins at Runtime ------------------------------ -In the `previous section <#specifying-the-plugins-to-include>`_ we've explained how to specify which plugins to load and -which to ignore before your Client starts. Here we'll show, instead, how to unload and load again a previously -registered plugin at runtime. +In the previous section we've explained how to specify which plugins to load and which to ignore before your Client +starts. Here we'll show, instead, how to unload and load again a previously registered plugin at runtime. Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram updates ) will be modified in such a way that, when you reference them later on, they will be actually pointing to a tuple of @@ -318,7 +317,7 @@ Unloading ^^^^^^^^^ In order to unload a plugin, or any other handler, all you need to do is obtain a reference to it by importing the -relevant module and call :meth:`remove_handler() ` Client's method with your function +relevant module and call :meth:`~pyrogram.Client.remove_handler` Client's method with your function name preceded by the star ``*`` operator as argument. Example: - ``main.py`` @@ -343,7 +342,7 @@ Loading ^^^^^^^ Similarly to the unloading process, in order to load again a previously unloaded plugin you do the same, but this time -using :meth:`add_handler() ` instead. Example: +using :meth:`~pyrogram.Client.add_handler` instead. Example: - ``main.py`` diff --git a/docs/source/topics/text-formatting.rst b/docs/source/topics/text-formatting.rst index 8f2292d0..bc74d562 100644 --- a/docs/source/topics/text-formatting.rst +++ b/docs/source/topics/text-formatting.rst @@ -12,7 +12,7 @@ Markdown Style -------------- To use this mode, pass "markdown" in the *parse_mode* field when using -:obj:`send_message() `. Use the following syntax in your message: +:meth:`~pyrogram.Client.send_message`. Use the following syntax in your message: .. code-block:: text @@ -34,7 +34,7 @@ To use this mode, pass "markdown" in the *parse_mode* field when using HTML Style ---------- -To use this mode, pass "html" in the *parse_mode* field when using :obj:`send_message() `. +To use this mode, pass "html" in the *parse_mode* field when using :meth:`~pyrogram.Client.send_message`. The following tags are currently supported: .. code-block:: text diff --git a/pyrogram/client/methods/chats/set_chat_photo.py b/pyrogram/client/methods/chats/set_chat_photo.py index 4a2f6cf1..79cceb7e 100644 --- a/pyrogram/client/methods/chats/set_chat_photo.py +++ b/pyrogram/client/methods/chats/set_chat_photo.py @@ -51,7 +51,7 @@ class SetChatPhoto(BaseClient): Raises: RPCError: In case of a Telegram RPC error. - ``ValueError`` if a chat_id belongs to user. + ValueError: if a chat_id belongs to user. """ peer = self.resolve_peer(chat_id) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 09cb9ca3..f8d161c2 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -110,7 +110,7 @@ class Message(PyrogramType, Update): 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. - media (``bool`` *optional*): + media (``bool``, *optional*): The message is a media message. A media message has one and only one of these fields set: audio, document, photo, sticker, video, animation, voice, video_note, contact, location, venue. From 4eaa891836914d3ad1012b74eef1d9f2f7fb972a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 28 May 2019 19:50:21 +0200 Subject: [PATCH 089/202] Update API schema to Layer 100 --- compiler/api/source/main_api.tl | 127 +++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 43 deletions(-) diff --git a/compiler/api/source/main_api.tl b/compiler/api/source/main_api.tl index 61c9faf6..43b02e80 100644 --- a/compiler/api/source/main_api.tl +++ b/compiler/api/source/main_api.tl @@ -22,10 +22,13 @@ inputPeerSelf#7da07ec9 = InputPeer; inputPeerChat#179be863 chat_id:int = InputPeer; inputPeerUser#7b8e7de6 user_id:int access_hash:long = InputPeer; inputPeerChannel#20adaef8 channel_id:int access_hash:long = InputPeer; +inputPeerUserFromMessage#17bae2e6 peer:InputPeer msg_id:int user_id:int = InputPeer; +inputPeerChannelFromMessage#9c95f7bb peer:InputPeer msg_id:int channel_id:int = InputPeer; inputUserEmpty#b98886cf = InputUser; inputUserSelf#f7c1b13f = InputUser; inputUser#d8292816 user_id:int access_hash:long = InputUser; +inputUserFromMessage#2d117597 peer:InputPeer msg_id:int user_id:int = InputUser; inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact; @@ -60,9 +63,12 @@ inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto; inputFileLocation#dfdaabe1 volume_id:long local_id:int secret:long file_reference:bytes = InputFileLocation; inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation; -inputDocumentFileLocation#196683d9 id:long access_hash:long file_reference:bytes = InputFileLocation; +inputDocumentFileLocation#bad07584 id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation; inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation; inputTakeoutFileLocation#29be5899 = InputFileLocation; +inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation; +inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation; +inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation; peerUser#9db1bc6d user_id:int = Peer; peerChat#bad0e5bb chat_id:int = Peer; @@ -79,14 +85,11 @@ storage.fileMov#4b09ebbc = storage.FileType; storage.fileMp4#b3cea0e4 = storage.FileType; storage.fileWebp#1081464c = storage.FileType; -fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation; -fileLocation#91d11eb dc_id:int volume_id:long local_id:int secret:long file_reference:bytes = FileLocation; - userEmpty#200250ba id:int = User; -user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User; +user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User; userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto; -userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto; +userProfilePhoto#ecd75d8c photo_id:long photo_small:FileLocation photo_big:FileLocation dc_id:int = UserProfilePhoto; userStatusEmpty#9d05049 = UserStatus; userStatusOnline#edb93949 expires:int = UserStatus; @@ -98,11 +101,11 @@ userStatusLastMonth#77ebc742 = UserStatus; chatEmpty#9ba2d800 id:int = Chat; chat#3bda1bde flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chatForbidden#7328bdb id:int title:string = Chat; -channel#4df30834 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat; +channel#4df30834 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat; channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat; -chatFull#22a235da flags:# can_set_username:flags.7?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int = ChatFull; -channelFull#1c87a71a flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull; +chatFull#1b7c9db3 flags:# can_set_username:flags.7?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int = ChatFull; +channelFull#9882e516 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.13?int pts:int = ChatFull; chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant; chatParticipantCreator#da13538a user_id:int = ChatParticipant; @@ -112,11 +115,11 @@ chatParticipantsForbidden#fc900c2b flags:# chat_id:int self_participant:flags.0? chatParticipants#3f460fed chat_id:int participants:Vector version:int = ChatParticipants; chatPhotoEmpty#37c1011c = ChatPhoto; -chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto; +chatPhoto#475cdbd5 photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto; messageEmpty#83e5de54 id:int = Message; -message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message; -messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message; +message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message; +messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message; messageMediaEmpty#3ded6320 = MessageMedia; messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia; @@ -147,7 +150,7 @@ messageActionHistoryClear#9fbab604 = MessageAction; messageActionGameScore#92a72876 game_id:long score:int = MessageAction; messageActionPaymentSentMe#8f31b327 flags:# currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction; messageActionPaymentSent#40699cd0 currency:string total_amount:long = MessageAction; -messageActionPhoneCall#80e11a7f flags:# call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction; +messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction; messageActionScreenshotTaken#4792929b = MessageAction; messageActionCustomAction#fae69f56 message:string = MessageAction; messageActionBotAllowed#abe9affe domain:string = MessageAction; @@ -155,10 +158,11 @@ messageActionSecureValuesSentMe#1b287353 values:Vector credentials: messageActionSecureValuesSent#d95c6154 types:Vector = MessageAction; messageActionContactSignUp#f3f25f76 = MessageAction; -dialog#e4def5db flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog; +dialog#2c171f72 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog; +dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; photoEmpty#2331b22d id:long = Photo; -photo#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector = Photo; +photo#d07504a5 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector dc_id:int = Photo; photoSizeEmpty#e17e23c type:string = PhotoSize; photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize; @@ -196,7 +200,7 @@ inputReportReasonChildAbuse#adf44ee3 = ReportReason; inputReportReasonOther#e1746d0a text:string = ReportReason; inputReportReasonCopyright#9b89f93a = ReportReason; -userFull#8ea4a881 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int = UserFull; +userFull#745559cc flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int = UserFull; contact#f911c994 user_id:int mutual:Bool = Contact; @@ -221,7 +225,7 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector

messages:Vector< messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs; messages.messages#8c718e87 messages:Vector chats:Vector users:Vector = messages.Messages; -messages.messagesSlice#a6c47aaa flags:# inexact:flags.1?true count:int messages:Vector chats:Vector users:Vector = messages.Messages; +messages.messagesSlice#c8edce1e flags:# inexact:flags.1?true count:int next_rate:flags.0?int messages:Vector chats:Vector users:Vector = messages.Messages; messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector chats:Vector users:Vector = messages.Messages; messages.messagesNotModified#74535f21 count:int = messages.Messages; @@ -271,14 +275,14 @@ updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector = Update; updatePrivacy#ee3b272a key:PrivacyKey rules:Vector = Update; updateUserPhone#12b9417b user_id:int phone:string = Update; -updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update; +updateReadHistoryInbox#9c974fdf flags:# folder_id:flags.0?int peer:Peer max_id:int still_unread_count:int pts:int pts_count:int = Update; updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update; updateWebPage#7f891213 webpage:WebPage pts:int pts_count:int = Update; updateReadMessagesContents#68c13933 messages:Vector pts:int pts_count:int = Update; updateChannelTooLong#eb0467fb flags:# channel_id:int pts:flags.0?int = Update; updateChannel#b6d45656 channel_id:int = Update; updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update; -updateReadChannelInbox#4214f37f channel_id:int max_id:int = Update; +updateReadChannelInbox#330b5424 flags:# folder_id:flags.0?int channel_id:int max_id:int still_unread_count:int pts:int = Update; updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector pts:int pts_count:int = Update; updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update; updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update; @@ -300,8 +304,8 @@ updateRecentStickers#9a422c20 = Update; updateConfig#a229dd06 = Update; updatePtsChanged#3354678f = Update; updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update; -updateDialogPinned#19d27f3c flags:# pinned:flags.0?true peer:DialogPeer = Update; -updatePinnedDialogs#ea4cb65b flags:# order:flags.0?Vector = Update; +updateDialogPinned#6e6fe51c flags:# pinned:flags.0?true folder_id:flags.1?int peer:DialogPeer = Update; +updatePinnedDialogs#fa0f3ca2 flags:# folder_id:flags.1?int order:flags.0?Vector = Update; updateBotWebhookJSON#8317c0c3 data:DataJSON = Update; updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Update; updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update; @@ -318,6 +322,7 @@ updateUserPinnedMessage#4c43da18 user_id:int id:int = Update; updateChatPinnedMessage#e10db349 chat_id:int id:int version:int = Update; updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update; updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update; +updateFolderPeers#19360dc0 folder_peers:Vector pts:int pts_count:int = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -344,7 +349,7 @@ upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption; -config#e6ca25f6 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config; +config#330b4067 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config; nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc; @@ -413,6 +418,7 @@ inputPrivacyKeyPhoneCall#fabadc5f = InputPrivacyKey; inputPrivacyKeyPhoneP2P#db9e70d2 = InputPrivacyKey; inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey; inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey; +inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey; privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey; privacyKeyChatInvite#500e6dfa = PrivacyKey; @@ -420,6 +426,7 @@ privacyKeyPhoneCall#3d662b7b = PrivacyKey; privacyKeyPhoneP2P#39491cc8 = PrivacyKey; privacyKeyForwards#69ec56a3 = PrivacyKey; privacyKeyProfilePhoto#96151fed = PrivacyKey; +privacyKeyPhoneNumber#d19ae46d = PrivacyKey; inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule; inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule; @@ -427,6 +434,8 @@ inputPrivacyValueAllowUsers#131cc67f users:Vector = InputPrivacyRule; inputPrivacyValueDisallowContacts#ba52007 = InputPrivacyRule; inputPrivacyValueDisallowAll#d66b66c9 = InputPrivacyRule; inputPrivacyValueDisallowUsers#90110467 users:Vector = InputPrivacyRule; +inputPrivacyValueAllowChatParticipants#4c81c1ba chats:Vector = InputPrivacyRule; +inputPrivacyValueDisallowChatParticipants#d82363af chats:Vector = InputPrivacyRule; privacyValueAllowContacts#fffe1bac = PrivacyRule; privacyValueAllowAll#65427b82 = PrivacyRule; @@ -434,8 +443,10 @@ privacyValueAllowUsers#4d5bbe0c users:Vector = PrivacyRule; privacyValueDisallowContacts#f888fa1a = PrivacyRule; privacyValueDisallowAll#8b73e763 = PrivacyRule; privacyValueDisallowUsers#c7f49b7 users:Vector = PrivacyRule; +privacyValueAllowChatParticipants#18be796b chats:Vector = PrivacyRule; +privacyValueDisallowChatParticipants#acae0690 chats:Vector = PrivacyRule; -account.privacyRules#554abb6f rules:Vector users:Vector = account.PrivacyRules; +account.privacyRules#50a04e45 rules:Vector chats:Vector users:Vector = account.PrivacyRules; accountDaysTTL#b8d0afdf days:int = AccountDaysTTL; @@ -459,7 +470,6 @@ messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMess contactLinkUnknown#5f4f9247 = ContactLink; contactLinkNone#feedd3ad = ContactLink; -contactLinkHasPhone#268f3f59 = ContactLink; contactLinkContact#d502c2d0 = ContactLink; webPageEmpty#eb1477e8 id:long = WebPage; @@ -485,13 +495,13 @@ chatInviteEmpty#69df3769 = ExportedChatInvite; chatInviteExported#fc2e05bc link:string = ExportedChatInvite; chatInviteAlready#5a686d7c chat:Chat = ChatInvite; -chatInvite#db74f558 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:ChatPhoto participants_count:int participants:flags.4?Vector = ChatInvite; +chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector = ChatInvite; inputStickerSetEmpty#ffb62b95 = InputStickerSet; inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet; inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet; -stickerSet#6a90bcb7 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize count:int hash:int = StickerSet; +stickerSet#eeb46f27 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize thumb_dc_id:flags.4?int count:int hash:int = StickerSet; messages.stickerSet#b60a24a6 set:StickerSet packs:Vector documents:Vector = messages.StickerSet; @@ -507,6 +517,8 @@ keyboardButtonRequestGeoLocation#fc796b3f text:string = KeyboardButton; keyboardButtonSwitchInline#568a748 flags:# same_peer:flags.0?true text:string query:string = KeyboardButton; keyboardButtonGame#50f41ccf text:string = KeyboardButton; keyboardButtonBuy#afd93fbb text:string = KeyboardButton; +keyboardButtonUrlAuth#10b78d29 flags:# text:string fwd_text:flags.0?string url:string button_id:int = KeyboardButton; +inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true text:string fwd_text:flags.1?string url:string bot:InputUser = KeyboardButton; keyboardButtonRow#77608b83 buttons:Vector = KeyboardButtonRow; @@ -533,13 +545,14 @@ messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity; inputChannelEmpty#ee8c1e86 = InputChannel; inputChannel#afeb712e channel_id:int access_hash:long = InputChannel; +inputChannelFromMessage#2a286531 peer:InputPeer msg_id:int channel_id:int = InputChannel; contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector users:Vector = contacts.ResolvedPeer; messageRange#ae30253 min_id:int max_id:int = MessageRange; updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int = updates.ChannelDifference; -updates.channelDifferenceTooLong#6a9d7b35 flags:# final:flags.0?true pts:int timeout:flags.1?int top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int messages:Vector chats:Vector users:Vector = updates.ChannelDifference; +updates.channelDifferenceTooLong#a4bcc6fe flags:# final:flags.0?true timeout:flags.1?int dialog:Dialog messages:Vector chats:Vector users:Vector = updates.ChannelDifference; updates.channelDifference#2064674e flags:# final:flags.0?true pts:int timeout:flags.1?int new_messages:Vector other_updates:Vector chats:Vector users:Vector = updates.ChannelDifference; channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter; @@ -628,6 +641,8 @@ topPeerCategoryCorrespondents#637b7ed = TopPeerCategory; topPeerCategoryGroups#bd17a14a = TopPeerCategory; topPeerCategoryChannels#161d9628 = TopPeerCategory; topPeerCategoryPhoneCalls#1e76a78c = TopPeerCategory; +topPeerCategoryForwardUsers#a8406ca9 = TopPeerCategory; +topPeerCategoryForwardChats#fbeec0f0 = TopPeerCategory; topPeerCategoryPeers#fb834291 category:TopPeerCategory count:int peers:Vector = TopPeerCategoryPeers; @@ -767,11 +782,11 @@ inputStickerSetItem#ffa0a496 flags:# document:InputDocument emoji:string mask_co inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall; phoneCallEmpty#5366c915 id:long = PhoneCall; -phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall; -phoneCallRequested#83761ce4 id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall; -phoneCallAccepted#6d003d3f id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall; -phoneCall#e6f9ddf3 flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector start_date:int = PhoneCall; -phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall; +phoneCallWaiting#1b8f4ad1 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall; +phoneCallRequested#87eabb53 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall; +phoneCallAccepted#997c454a flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall; +phoneCall#8742ae7f flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector start_date:int = PhoneCall; +phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.5?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall; phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection; @@ -797,7 +812,7 @@ langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:fl channelAdminLogEventActionChangeTitle#e6dfb825 prev_value:string new_value:string = ChannelAdminLogEventAction; channelAdminLogEventActionChangeAbout#55188a2e prev_value:string new_value:string = ChannelAdminLogEventAction; channelAdminLogEventActionChangeUsername#6a4afc38 prev_value:string new_value:string = ChannelAdminLogEventAction; -channelAdminLogEventActionChangePhoto#b82f55c3 prev_photo:ChatPhoto new_photo:ChatPhoto = ChannelAdminLogEventAction; +channelAdminLogEventActionChangePhoto#434bd2af prev_photo:Photo new_photo:Photo = ChannelAdminLogEventAction; channelAdminLogEventActionToggleInvites#1b7907ae new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionToggleSignatures#26ae0971 new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionUpdatePinned#e9e82c18 message:Message = ChannelAdminLogEventAction; @@ -812,6 +827,7 @@ channelAdminLogEventActionChangeStickerSet#b1c3caa7 prev_stickerset:InputSticker channelAdminLogEventActionTogglePreHistoryHidden#5f5c95f1 new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionDefaultBannedRights#2df5fc0a prev_banned_rights:ChatBannedRights new_banned_rights:ChatBannedRights = ChannelAdminLogEventAction; channelAdminLogEventActionStopPoll#8f079643 message:Message = ChannelAdminLogEventAction; +channelAdminLogEventActionChangeLinkedChat#a26f881b prev_value:int new_value:int = ChannelAdminLogEventAction; channelAdminLogEvent#3b5a3e40 id:long date:int user_id:int action:ChannelAdminLogEventAction = ChannelAdminLogEvent; @@ -843,8 +859,10 @@ inputMessageReplyTo#bad88395 id:int = InputMessage; inputMessagePinned#86872538 = InputMessage; inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer; +inputDialogPeerFolder#64600527 folder_id:int = InputDialogPeer; dialogPeer#e56dbf05 peer:Peer = DialogPeer; +dialogPeerFolder#514519e2 folder_id:int = DialogPeer; messages.foundStickerSetsNotModified#d54b65d = messages.FoundStickerSets; messages.foundStickerSets#5108d648 hash:int sets:Vector = messages.FoundStickerSets; @@ -1000,6 +1018,22 @@ emojiKeywordsDifference#5cc761bd lang_code:string from_version:int version:int k emojiURL#a575739d url:string = EmojiURL; +emojiLanguage#b3fb5361 lang_code:string = EmojiLanguage; + +fileLocationToBeDeprecated#bc7fc6cd volume_id:long local_id:int = FileLocation; + +folder#ff544e65 flags:# autofill_new_broadcasts:flags.0?true autofill_public_groups:flags.1?true autofill_new_correspondents:flags.2?true id:int title:string photo:flags.3?ChatPhoto = Folder; + +inputFolderPeer#fbd2c296 peer:InputPeer folder_id:int = InputFolderPeer; + +folderPeer#e9baa668 peer:Peer folder_id:int = FolderPeer; + +messages.searchCounter#e844ebff flags:# inexact:flags.1?true filter:MessagesFilter count:int = messages.SearchCounter; + +urlAuthResultRequest#92d33a0e flags:# request_write_access:flags.0?true bot:User domain:string = UrlAuthResult; +urlAuthResultAccepted#8f8c0e4e url:string = UrlAuthResult; +urlAuthResultDefault#a9d6db1f = UrlAuthResult; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1098,14 +1132,14 @@ contacts.unblock#e54100bd id:InputUser = Bool; contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked; contacts.search#11f812d8 q:string limit:int = contacts.Found; contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer; -contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers; +contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers; contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool; contacts.resetSaved#879537f1 = Bool; contacts.getSaved#82f1e39f = Vector; contacts.toggleTopPeers#8514bdda enabled:Bool = Bool; messages.getMessages#63c66506 id:Vector = messages.Messages; -messages.getDialogs#b098aee6 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs; +messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs; messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages; messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages; messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages; @@ -1152,7 +1186,7 @@ messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_par messages.getMessagesViews#c4c8a55d peer:InputPeer id:Vector increment:Bool = Vector; messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool; messages.migrateChat#15a3b8e3 chat_id:int = Updates; -messages.searchGlobal#9e3cacb0 q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; +messages.searchGlobal#f79c611 q:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector = Bool; messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document; messages.searchGifs#bf9a776b q:string offset:int = messages.FoundGifs; @@ -1185,8 +1219,8 @@ messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = message messages.getAllChats#eba80ff0 except_ids:Vector = messages.Chats; messages.getWebPage#32ca8f91 url:string hash:int = WebPage; messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool; -messages.reorderPinnedDialogs#5b51d63f flags:# force:flags.0?true order:Vector = Bool; -messages.getPinnedDialogs#e254d64e = messages.PeerDialogs; +messages.reorderPinnedDialogs#3b1adf37 flags:# force:flags.0?true folder_id:int order:Vector = Bool; +messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs; messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector = Bool; messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool; messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia; @@ -1212,7 +1246,11 @@ messages.editChatAbout#def60797 peer:InputPeer about:string = Bool; messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates; messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference; messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference; +messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector = Vector; messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL; +messages.getSearchCounters#732eef00 peer:InputPeer filters:Vector = Vector; +messages.requestUrlAuth#e33f5613 peer:InputPeer msg_id:int button_id:int = UrlAuthResult; +messages.acceptUrlAuth#f729ea98 flags:# write_allowed:flags.0?true peer:InputPeer msg_id:int button_id:int = UrlAuthResult; updates.getState#edd4882a = updates.State; updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference; @@ -1281,6 +1319,9 @@ channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector = Bool channels.deleteHistory#af369d42 channel:InputChannel max_id:int = Bool; channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates; channels.getLeftChannels#8341ecc0 offset:int = messages.Chats; +channels.getGroupsForDiscussion#f5dad378 = messages.Chats; +channels.getBroadcastsForDiscussion#1a87f304 = messages.Chats; +channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel = Bool; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; @@ -1298,11 +1339,11 @@ stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = mes stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet; phone.getCallConfig#55451fa9 = DataJSON; -phone.requestCall#5b95b3d4 user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; +phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall; phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall; phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool; -phone.discardCall#78d413a6 peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates; +phone.discardCall#b2cbc1c0 flags:# video:flags.0?true peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates; phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates; phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool; @@ -1312,7 +1353,7 @@ langpack.getDifference#cd984aa5 lang_pack:string lang_code:string from_version:i langpack.getLanguages#42c6978f lang_pack:string = Vector; langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage; -// LAYER 97 +folders.editPeerFolders#6847d0ab folder_peers:Vector = Updates; +folders.deleteFolder#1c295881 folder_id:int = Updates; -// Ports -channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite; \ No newline at end of file +// LAYER 100 \ No newline at end of file From c2424029b57e50a3587476900ee842b97feec947 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:37:50 +0200 Subject: [PATCH 090/202] Fix dialogs after L100 update --- pyrogram/client/client.py | 4 ++-- pyrogram/client/methods/chats/get_dialogs.py | 2 +- pyrogram/client/methods/chats/get_dialogs_count.py | 2 +- pyrogram/client/methods/chats/iter_dialogs.py | 2 +- pyrogram/client/types/user_and_chats/dialog.py | 2 +- pyrogram/client/types/user_and_chats/dialogs.py | 12 ++++++++++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 8c1e3001..0d1cde19 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -313,7 +313,7 @@ class Client(Methods, BaseClient): self.get_initial_dialogs() self.get_contacts() else: - self.send(functions.messages.GetPinnedDialogs()) + self.send(functions.messages.GetPinnedDialogs(folder_id=0)) self.get_initial_dialogs_chunk() else: self.send(functions.updates.GetState()) @@ -1325,7 +1325,7 @@ class Client(Methods, BaseClient): return r def get_initial_dialogs(self): - self.send(functions.messages.GetPinnedDialogs()) + self.send(functions.messages.GetPinnedDialogs(folder_id=0)) dialogs = self.get_initial_dialogs_chunk() offset_date = utils.get_offset_date(dialogs) diff --git a/pyrogram/client/methods/chats/get_dialogs.py b/pyrogram/client/methods/chats/get_dialogs.py index 605ee782..948a7642 100644 --- a/pyrogram/client/methods/chats/get_dialogs.py +++ b/pyrogram/client/methods/chats/get_dialogs.py @@ -62,7 +62,7 @@ class GetDialogs(BaseClient): while True: try: if pinned_only: - r = self.send(functions.messages.GetPinnedDialogs()) + r = self.send(functions.messages.GetPinnedDialogs(folder_id=0)) else: r = self.send( functions.messages.GetDialogs( diff --git a/pyrogram/client/methods/chats/get_dialogs_count.py b/pyrogram/client/methods/chats/get_dialogs_count.py index b9b0970a..c804709d 100644 --- a/pyrogram/client/methods/chats/get_dialogs_count.py +++ b/pyrogram/client/methods/chats/get_dialogs_count.py @@ -36,7 +36,7 @@ class GetDialogsCount(BaseClient): """ if pinned_only: - return len(self.send(functions.messages.GetPinnedDialogs()).dialogs) + return len(self.send(functions.messages.GetPinnedDialogs(folder_id=0)).dialogs) else: r = self.send( functions.messages.GetDialogs( diff --git a/pyrogram/client/methods/chats/iter_dialogs.py b/pyrogram/client/methods/chats/iter_dialogs.py index 1209a5df..976a49df 100644 --- a/pyrogram/client/methods/chats/iter_dialogs.py +++ b/pyrogram/client/methods/chats/iter_dialogs.py @@ -26,7 +26,7 @@ class IterDialogs(BaseClient): def iter_dialogs( self, offset_date: int = 0, - limit: int = 0 + limit: int = None ) -> Generator["pyrogram.Dialog", None, None]: """Iterate through a user's dialogs sequentially. diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index fc691ab6..4b900012 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -69,7 +69,7 @@ class Dialog(PyrogramType): self.is_pinned = is_pinned @staticmethod - def _parse(client, dialog, messages, users, chats) -> "Dialog": + def _parse(client, dialog: types.Dialog, messages, users, chats) -> "Dialog": chat_id = dialog.peer if isinstance(chat_id, types.PeerUser): diff --git a/pyrogram/client/types/user_and_chats/dialogs.py b/pyrogram/client/types/user_and_chats/dialogs.py index 0d6a0935..862fcf22 100644 --- a/pyrogram/client/types/user_and_chats/dialogs.py +++ b/pyrogram/client/types/user_and_chats/dialogs.py @@ -51,7 +51,7 @@ class Dialogs(PyrogramType): self.dialogs = dialogs @staticmethod - def _parse(client, dialogs) -> "Dialogs": + def _parse(client, dialogs: types.messages.Dialogs) -> "Dialogs": users = {i.id: i for i in dialogs.users} chats = {i.id: i for i in dialogs.chats} @@ -72,8 +72,16 @@ class Dialogs(PyrogramType): messages[chat_id] = Message._parse(client, message, users, chats) + parsed_dialogs = [] + + for dialog in dialogs.dialogs: + if not isinstance(dialog, types.Dialog): + continue + + parsed_dialogs.append(Dialog._parse(client, dialog, messages, users, chats)) + return Dialogs( total_count=getattr(dialogs, "count", len(dialogs.dialogs)), - dialogs=[Dialog._parse(client, dialog, messages, users, chats) for dialog in dialogs.dialogs], + dialogs=parsed_dialogs, client=client ) From 1390797f5853bb64a3e8f79ae673f932d1a272f1 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:41:04 +0200 Subject: [PATCH 091/202] Rename delete_user_profile_photos to just delete_photos. It's implied an user can only delete own photos. --- .../users/{delete_user_profile_photos.py => delete_photos.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename pyrogram/client/methods/users/{delete_user_profile_photos.py => delete_photos.py} (96%) diff --git a/pyrogram/client/methods/users/delete_user_profile_photos.py b/pyrogram/client/methods/users/delete_photos.py similarity index 96% rename from pyrogram/client/methods/users/delete_user_profile_photos.py rename to pyrogram/client/methods/users/delete_photos.py index 305fd554..30b3b533 100644 --- a/pyrogram/client/methods/users/delete_user_profile_photos.py +++ b/pyrogram/client/methods/users/delete_photos.py @@ -24,8 +24,8 @@ from pyrogram.api import functions, types from ...ext import BaseClient -class DeleteUserProfilePhotos(BaseClient): - def delete_user_profile_photos( +class DeletePhotos(BaseClient): + def delete_photos( self, id: Union[str, List[str]] ) -> bool: From 83cd82838642425d1bd2137f9a5ead7280d28c1c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:41:59 +0200 Subject: [PATCH 092/202] Rename get_user_profile_photos_count to get_user_photos_count --- ..._user_profile_photos_count.py => get_user_photos_count.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename pyrogram/client/methods/users/{get_user_profile_photos_count.py => get_user_photos_count.py} (93%) diff --git a/pyrogram/client/methods/users/get_user_profile_photos_count.py b/pyrogram/client/methods/users/get_user_photos_count.py similarity index 93% rename from pyrogram/client/methods/users/get_user_profile_photos_count.py rename to pyrogram/client/methods/users/get_user_photos_count.py index 7870d003..3bbaf55b 100644 --- a/pyrogram/client/methods/users/get_user_profile_photos_count.py +++ b/pyrogram/client/methods/users/get_user_photos_count.py @@ -22,8 +22,8 @@ from pyrogram.api import functions, types from ...ext import BaseClient -class GetUserProfilePhotosCount(BaseClient): - def get_user_profile_photos_count(self, user_id: Union[int, str]) -> int: +class GetUserPhotosCount(BaseClient): + def get_user_photos_count(self, user_id: Union[int, str]) -> int: """Get the total count of profile pictures for a user. Parameters: From 86a4f63d37f267c5a9ba250df3a95bcbe9dc508a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:42:55 +0200 Subject: [PATCH 093/202] Rename set_user_profile_photo to set_photo Users can only set a photo for themselves. --- .../methods/users/{set_user_profile_photo.py => set_photo.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename pyrogram/client/methods/users/{set_user_profile_photo.py => set_photo.py} (95%) diff --git a/pyrogram/client/methods/users/set_user_profile_photo.py b/pyrogram/client/methods/users/set_photo.py similarity index 95% rename from pyrogram/client/methods/users/set_user_profile_photo.py rename to pyrogram/client/methods/users/set_photo.py index bc056466..cd7f955d 100644 --- a/pyrogram/client/methods/users/set_user_profile_photo.py +++ b/pyrogram/client/methods/users/set_photo.py @@ -20,8 +20,8 @@ from pyrogram.api import functions from ...ext import BaseClient -class SetUserProfilePhoto(BaseClient): - def set_user_profile_photo( +class SetPhoto(BaseClient): + def set_photo( self, photo: str ) -> bool: From 09d012b696555e9530fd47a2c29e8b5dabe605c4 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:43:33 +0200 Subject: [PATCH 094/202] Rename get_user_profile_photos to get_user_photos --- .../{get_user_profile_photos.py => get_user_photos.py} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename pyrogram/client/methods/users/{get_user_profile_photos.py => get_user_photos.py} (88%) diff --git a/pyrogram/client/methods/users/get_user_profile_photos.py b/pyrogram/client/methods/users/get_user_photos.py similarity index 88% rename from pyrogram/client/methods/users/get_user_profile_photos.py rename to pyrogram/client/methods/users/get_user_photos.py index ab58dbec..e134a502 100644 --- a/pyrogram/client/methods/users/get_user_profile_photos.py +++ b/pyrogram/client/methods/users/get_user_photos.py @@ -23,13 +23,13 @@ from pyrogram.api import functions from ...ext import BaseClient -class GetUserProfilePhotos(BaseClient): - def get_user_profile_photos( +class GetUserPhotos(BaseClient): + def get_user_photos( self, user_id: Union[int, str], offset: int = 0, limit: int = 100 - ) -> "pyrogram.UserProfilePhotos": + ) -> "pyrogram.Photos": """Get a list of profile pictures for a user. Parameters: @@ -47,12 +47,12 @@ class GetUserProfilePhotos(BaseClient): Values between 1—100 are accepted. Defaults to 100. Returns: - :obj:`UserProfilePhotos`: On success, an object containing a list of the profile photos is returned. + :obj:`Photos`: On success, an object containing a list of the profile photos is returned. Raises: RPCError: In case of a Telegram RPC error. """ - return pyrogram.UserProfilePhotos._parse( + return pyrogram.Photos._parse( self, self.send( functions.photos.GetUserPhotos( From 38de4299c511046b866abd0b32d2db5c9575a16c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:43:48 +0200 Subject: [PATCH 095/202] Add get_user_dc method --- pyrogram/client/methods/users/__init__.py | 16 ++++++++-------- pyrogram/client/methods/users/get_user_dc.py | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pyrogram/client/methods/users/__init__.py b/pyrogram/client/methods/users/__init__.py index a33a0f0c..bbc2df23 100644 --- a/pyrogram/client/methods/users/__init__.py +++ b/pyrogram/client/methods/users/__init__.py @@ -16,24 +16,24 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .delete_user_profile_photos import DeleteUserProfilePhotos +from .delete_photos import DeletePhotos from .get_me import GetMe from .get_user_dc import GetUserDC -from .get_user_profile_photos import GetUserProfilePhotos -from .get_user_profile_photos_count import GetUserProfilePhotosCount +from .get_user_photos import GetUserPhotos +from .get_user_photos_count import GetUserPhotosCount from .get_users import GetUsers -from .set_user_profile_photo import SetUserProfilePhoto +from .set_photo import SetPhoto from .update_username import UpdateUsername class Users( - GetUserProfilePhotos, - SetUserProfilePhoto, - DeleteUserProfilePhotos, + GetUserPhotos, + SetPhoto, + DeletePhotos, GetUsers, GetMe, UpdateUsername, - GetUserProfilePhotosCount, + GetUserPhotosCount, GetUserDC ): pass diff --git a/pyrogram/client/methods/users/get_user_dc.py b/pyrogram/client/methods/users/get_user_dc.py index 27631e95..49596c11 100644 --- a/pyrogram/client/methods/users/get_user_dc.py +++ b/pyrogram/client/methods/users/get_user_dc.py @@ -46,7 +46,7 @@ class GetUserDC(BaseClient): r = r[0] if r.photo: - if isinstance(r.photo.photo_small, types.FileLocation): - return r.photo.photo_small.dc_id + if isinstance(r.photo, types.UserProfilePhoto): + return r.photo.dc_id return None From 41d5a13b5f99ea65c5a36959f78bc8cd2c511712 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:44:57 +0200 Subject: [PATCH 096/202] Extend Chat and User types with new fields is_verified, is_restricted, is_scam and is_support (user only) --- pyrogram/client/types/user_and_chats/chat.py | 44 ++++++++++++++++---- pyrogram/client/types/user_and_chats/user.py | 33 +++++++++++++-- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index e45814ea..10cc10a7 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -35,6 +35,16 @@ class Chat(PyrogramType): type (``str``): Type of chat, can be either "private", "bot", "group", "supergroup" or "channel". + is_verified (``bool``, *optional*): + True, if this chat has been verified by Telegram. Supergroups and channels only. + + is_restricted (``bool``, *optional*): + True, if this chat has been restricted. Supergroups and channels only. + See *restriction_reason* for details. + + is_scam (``bool``, *optional*): + True, if this chat has been flagged for scam. Supergroups and channels only. + title (``str``, *optional*): Title, for supergroups, channels and basic group chats. @@ -75,15 +85,16 @@ class Chat(PyrogramType): restriction_reason (``str``, *optional*): The reason why this chat might be unavailable to some users. + This field is available only in case *is_restricted* is True. permissions (:obj:`ChatPermissions ` *optional*): Information about the chat default permissions, for groups and supergroups. """ __slots__ = [ - "id", "type", "title", "username", "first_name", "last_name", "photo", "description", "invite_link", - "pinned_message", "sticker_set_name", "can_set_sticker_set", "members_count", "restriction_reason", - "permissions" + "id", "type", "is_verified", "is_restricted", "is_scam", "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__( @@ -92,6 +103,9 @@ class Chat(PyrogramType): client: "pyrogram.BaseClient" = None, id: int, type: str, + is_verified: bool = None, + is_restricted: bool = None, + is_scam: bool = None, title: str = None, username: str = None, first_name: str = None, @@ -110,6 +124,9 @@ class Chat(PyrogramType): self.id = id self.type = type + self.is_verified = is_verified + self.is_restricted = is_restricted + self.is_scam = is_scam self.title = title self.username = username self.first_name = first_name @@ -126,36 +143,45 @@ class Chat(PyrogramType): @staticmethod def _parse_user_chat(client, user: types.User) -> "Chat": + peer_id = user.id + return Chat( - id=user.id, + id=peer_id, type="bot" if user.bot else "private", username=user.username, first_name=user.first_name, last_name=user.last_name, - photo=ChatPhoto._parse(client, user.photo), + photo=ChatPhoto._parse(client, user.photo, peer_id), restriction_reason=user.restriction_reason, client=client ) @staticmethod def _parse_chat_chat(client, chat: types.Chat) -> "Chat": + peer_id = -chat.id + return Chat( - id=-chat.id, + id=peer_id, type="group", title=chat.title, - photo=ChatPhoto._parse(client, getattr(chat, "photo", None)), + photo=ChatPhoto._parse(client, getattr(chat, "photo", None), peer_id), permissions=ChatPermissions._parse(getattr(chat, "default_banned_rights", None)), client=client ) @staticmethod def _parse_channel_chat(client, channel: types.Channel) -> "Chat": + peer_id = int("-100" + str(channel.id)) + return Chat( - id=int("-100" + str(channel.id)), + id=peer_id, type="supergroup" if channel.megagroup else "channel", + is_verified=getattr(channel, "verified", None), + is_restricted=getattr(channel, "restricted", None), + is_scam=getattr(channel, "scam", None), title=channel.title, username=getattr(channel, "username", None), - photo=ChatPhoto._parse(client, getattr(channel, "photo", None)), + photo=ChatPhoto._parse(client, getattr(channel, "photo", None), peer_id), restriction_reason=getattr(channel, "restriction_reason", None), permissions=ChatPermissions._parse(getattr(channel, "default_banned_rights", None)), client=client diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 455b4a4d..ae631df1 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -45,6 +45,19 @@ class User(PyrogramType): is_bot (``bool``): True, if this user is a bot. + is_verified (``bool``): + True, if this user has been verified by Telegram. + + is_restricted (``bool``): + True, if this user has been restricted. Bots only. + See *restriction_reason* for details. + + is_support (``bool``): + True, if this user is part of the Telegram support team. + + is_scam (``bool``): + True, if this user has been flagged for scam. + first_name (``str``): User's or bot's first name. @@ -68,11 +81,13 @@ class User(PyrogramType): restriction_reason (``str``, *optional*): The reason why this bot might be unavailable to some users. + This field is available only in case *is_restricted* is True. """ __slots__ = [ - "id", "is_self", "is_contact", "is_mutual_contact", "is_deleted", "is_bot", "first_name", "last_name", "status", - "username", "language_code", "phone_number", "photo", "restriction_reason" + "id", "is_self", "is_contact", "is_mutual_contact", "is_deleted", "is_bot", "is_verified", "is_restricted", + "is_support", "is_scam", "first_name", "last_name", "status", "username", "language_code", "phone_number", + "photo", "restriction_reason" ] def __init__( @@ -85,6 +100,10 @@ class User(PyrogramType): is_mutual_contact: bool, is_deleted: bool, is_bot: bool, + is_verified: bool, + is_restricted: bool, + is_support: bool, + is_scam: bool, first_name: str, last_name: str = None, status: UserStatus = None, @@ -102,6 +121,10 @@ class User(PyrogramType): self.is_mutual_contact = is_mutual_contact self.is_deleted = is_deleted self.is_bot = is_bot + self.is_verified = is_verified + self.is_restricted = is_restricted + self.is_support = is_support + self.is_scam = is_scam self.first_name = first_name self.last_name = last_name self.status = status @@ -123,13 +146,17 @@ class User(PyrogramType): is_mutual_contact=user.mutual_contact, is_deleted=user.deleted, is_bot=user.bot, + is_verified=user.verified, + is_restricted=user.restricted, + is_support=user.support, + is_scam=user.scam, first_name=user.first_name, last_name=user.last_name, status=UserStatus._parse(client, user.status, user.id, user.bot), username=user.username, language_code=user.lang_code, phone_number=user.phone, - photo=ChatPhoto._parse(client, user.photo), + photo=ChatPhoto._parse(client, user.photo, user.id), restriction_reason=user.restriction_reason, client=client ) From 807dcb67be8914ca2907dd9e4a382032faf605d9 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:46:21 +0200 Subject: [PATCH 097/202] Hide phone numbers and show human-friendly date formats when printing --- pyrogram/client/types/pyrogram_type.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/types/pyrogram_type.py b/pyrogram/client/types/pyrogram_type.py index ed50efbc..9a04c636 100644 --- a/pyrogram/client/types/pyrogram_type.py +++ b/pyrogram/client/types/pyrogram_type.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from collections import OrderedDict +from datetime import datetime from json import dumps import pyrogram @@ -46,9 +47,15 @@ class PyrogramType: try: return OrderedDict( [("_", "pyrogram." + obj.__class__.__name__)] - + [(attr, getattr(obj, attr)) - for attr in obj.__slots__ - if getattr(obj, attr) is not None] + + [ + (attr, "*" * len(getattr(obj, attr))) + if attr == "phone_number" + else (attr, str(datetime.fromtimestamp(getattr(obj, attr)))) + if attr.endswith("date") + else (attr, getattr(obj, attr)) + for attr in obj.__slots__ + if getattr(obj, attr) is not None + ] ) except AttributeError: return repr(obj) From aaa569a08dca9c075779c1230577fc0a69643866 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:47:14 +0200 Subject: [PATCH 098/202] Revamp Thumbnail type (ex PhotoSize) --- .../{photo_size.py => thumbnail.py} | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) rename pyrogram/client/types/messages_and_media/{photo_size.py => thumbnail.py} (53%) diff --git a/pyrogram/client/types/messages_and_media/photo_size.py b/pyrogram/client/types/messages_and_media/thumbnail.py similarity index 53% rename from pyrogram/client/types/messages_and_media/photo_size.py rename to pyrogram/client/types/messages_and_media/thumbnail.py index 9f64ae6a..0ff15e66 100644 --- a/pyrogram/client/types/messages_and_media/photo_size.py +++ b/pyrogram/client/types/messages_and_media/thumbnail.py @@ -17,15 +17,16 @@ # along with Pyrogram. If not, see . from struct import pack -from typing import List, Union +from typing import Union, List import pyrogram from pyrogram.api import types from pyrogram.client.ext.utils import encode +from .stripped_thumbnail import StrippedThumbnail from ..pyrogram_type import PyrogramType -class PhotoSize(PyrogramType): +class Thumbnail(PyrogramType): """One size of a photo or a file/sticker thumbnail. Parameters: @@ -61,30 +62,44 @@ class PhotoSize(PyrogramType): self.file_size = file_size @staticmethod - def _parse(client, thumbs: List) -> Union["PhotoSize", None]: - if not thumbs: + def _parse( + client, + media: Union[types.Photo, types.Document] + ) -> Union[List[Union[StrippedThumbnail, "Thumbnail"]], None]: + if isinstance(media, types.Photo): + raw_thumbnails = media.sizes[:-1] + media_type = 0 + elif isinstance(media, types.Document): + raw_thumbnails = media.thumbs + media_type = 14 + + if not raw_thumbnails: + return None + else: return None - photo_size = thumbs[-1] + thumbnails = [] - if not isinstance(photo_size, (types.PhotoSize, types.PhotoCachedSize, types.PhotoStrippedSize)): - return None - - loc = photo_size.location - - if not isinstance(loc, types.FileLocation): - return None - - return PhotoSize( - file_id=encode( - pack( - " Date: Wed, 29 May 2019 09:47:43 +0200 Subject: [PATCH 099/202] Add StrippedThumbnail type Still a WIP --- .../messages_and_media/stripped_thumbnail.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 pyrogram/client/types/messages_and_media/stripped_thumbnail.py diff --git a/pyrogram/client/types/messages_and_media/stripped_thumbnail.py b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py new file mode 100644 index 00000000..31638fc2 --- /dev/null +++ b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py @@ -0,0 +1,49 @@ +# 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 . + +import pyrogram +from pyrogram.api import types +from ..pyrogram_type import PyrogramType + + +class StrippedThumbnail(PyrogramType): + """A stripped thumbnail + + Parameters: + data (``bytes``): + Thumbnail data + """ + + __slots__ = ["data"] + + def __init__( + self, + *, + client: "pyrogram.BaseClient" = None, + data: bytes, + ): + super().__init__(client) + + self.data = data + + @staticmethod + def _parse(client, stripped_thumbnail: types.PhotoStrippedSize) -> "StrippedThumbnail": + return StrippedThumbnail( + data=stripped_thumbnail.bytes, + client=client + ) From fda456cd1ee31c84a66e0bfbd06f29809571f75e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:49:13 +0200 Subject: [PATCH 100/202] Rename UserProfilePhotos to just Photos for brevity and elegance --- .../{user_profile_photos.py => photos.py} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename pyrogram/client/types/messages_and_media/{user_profile_photos.py => photos.py} (92%) diff --git a/pyrogram/client/types/messages_and_media/user_profile_photos.py b/pyrogram/client/types/messages_and_media/photos.py similarity index 92% rename from pyrogram/client/types/messages_and_media/user_profile_photos.py rename to pyrogram/client/types/messages_and_media/photos.py index 628831d5..1d5b193e 100644 --- a/pyrogram/client/types/messages_and_media/user_profile_photos.py +++ b/pyrogram/client/types/messages_and_media/photos.py @@ -23,7 +23,7 @@ from .photo import Photo from ..pyrogram_type import PyrogramType -class UserProfilePhotos(PyrogramType): +class Photos(PyrogramType): """Contains a user's profile pictures. Parameters: @@ -49,8 +49,8 @@ class UserProfilePhotos(PyrogramType): self.photos = photos @staticmethod - def _parse(client, photos) -> "UserProfilePhotos": - return UserProfilePhotos( + def _parse(client, photos) -> "Photos": + return Photos( total_count=getattr(photos, "count", len(photos.photos)), photos=[Photo._parse(client, photo) for photo in photos.photos], client=client From b217bf37845c5a4b92a2f45613697dd0f5a0ddb3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 09:49:50 +0200 Subject: [PATCH 101/202] Refactor ChatPhoto to accommodate L100 changes --- .../client/types/user_and_chats/chat_photo.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat_photo.py b/pyrogram/client/types/user_and_chats/chat_photo.py index 08e43138..1885eff2 100644 --- a/pyrogram/client/types/user_and_chats/chat_photo.py +++ b/pyrogram/client/types/user_and_chats/chat_photo.py @@ -50,31 +50,24 @@ class ChatPhoto(PyrogramType): self.big_file_id = big_file_id @staticmethod - def _parse(client, chat_photo: types.UserProfilePhoto or types.ChatPhoto): + def _parse(client, chat_photo: types.UserProfilePhoto or types.ChatPhoto, peer_id: int): if not isinstance(chat_photo, (types.UserProfilePhoto, types.ChatPhoto)): return None - if not isinstance(chat_photo.photo_small, types.FileLocation): - return None - - if not isinstance(chat_photo.photo_big, types.FileLocation): - return None - - photo_id = getattr(chat_photo, "photo_id", 0) loc_small = chat_photo.photo_small loc_big = chat_photo.photo_big return ChatPhoto( small_file_id=encode( pack( - " Date: Wed, 29 May 2019 09:50:41 +0200 Subject: [PATCH 102/202] Update all media types' thumbnails They are now a List of Thumbnail objects --- .../types/messages_and_media/__init__.py | 7 +- .../types/messages_and_media/animation.py | 27 +++--- .../client/types/messages_and_media/audio.py | 29 ++++--- .../types/messages_and_media/document.py | 21 ++--- .../client/types/messages_and_media/photo.py | 82 ++++++++----------- .../types/messages_and_media/sticker.py | 21 ++--- .../client/types/messages_and_media/video.py | 29 ++++--- .../types/messages_and_media/video_note.py | 17 ++-- 8 files changed, 122 insertions(+), 111 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/__init__.py b/pyrogram/client/types/messages_and_media/__init__.py index ae4386d0..d312611b 100644 --- a/pyrogram/client/types/messages_and_media/__init__.py +++ b/pyrogram/client/types/messages_and_media/__init__.py @@ -26,11 +26,12 @@ from .message import Message from .message_entity import MessageEntity from .messages import Messages from .photo import Photo -from .photo_size import PhotoSize from .poll import Poll from .poll_option import PollOption from .sticker import Sticker -from .user_profile_photos import UserProfilePhotos +from .stripped_thumbnail import StrippedThumbnail +from .thumbnail import Thumbnail +from .photos import Photos from .venue import Venue from .video import Video from .video_note import VideoNote @@ -38,5 +39,5 @@ from .voice import Voice __all__ = [ "Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Messages", "Photo", - "PhotoSize", "Poll", "PollOption", "Sticker", "UserProfilePhotos", "Venue", "Video", "VideoNote", "Voice" + "Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Photos", "Venue", "Video", "VideoNote", "Voice" ] diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index cd6e03ab..d729c3ac 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -17,10 +17,11 @@ # along with Pyrogram. If not, see . from struct import pack +from typing import List import pyrogram from pyrogram.api import types -from .photo_size import PhotoSize +from .thumbnail import Thumbnail from ..pyrogram_type import PyrogramType from ...ext.utils import encode @@ -41,9 +42,6 @@ class Animation(PyrogramType): duration (``int``): Duration of the animation in seconds as defined by sender. - thumb (:obj:`PhotoSize `, *optional*): - Animation thumbnail. - file_name (``str``, *optional*): Animation file name. @@ -55,9 +53,12 @@ class Animation(PyrogramType): date (``int``, *optional*): Date the animation was sent in Unix time. + + thumbnails (List of :obj:`Thumbnail`, *optional*): + Animation thumbnails. """ - __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date", "width", "height", "duration"] + __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "duration", "thumbnails"] def __init__( self, @@ -67,16 +68,15 @@ class Animation(PyrogramType): width: int, height: int, duration: int, - thumb: PhotoSize = None, file_name: str = None, mime_type: str = None, file_size: int = None, - date: int = None + date: int = None, + thumbnails: List[Thumbnail] = None, ): super().__init__(client) self.file_id = file_id - self.thumb = thumb self.file_name = file_name self.mime_type = mime_type self.file_size = file_size @@ -84,10 +84,15 @@ class Animation(PyrogramType): self.width = width self.height = height self.duration = duration + self.thumbnails = thumbnails @staticmethod - def _parse(client, animation: types.Document, video_attributes: types.DocumentAttributeVideo, - file_name: str) -> "Animation": + def _parse( + client, + animation: types.Document, + video_attributes: types.DocumentAttributeVideo, + file_name: str + ) -> "Animation": return Animation( file_id=encode( pack( @@ -101,10 +106,10 @@ class Animation(PyrogramType): width=getattr(video_attributes, "w", 0), height=getattr(video_attributes, "h", 0), duration=getattr(video_attributes, "duration", 0), - thumb=PhotoSize._parse(client, animation.thumbs), mime_type=animation.mime_type, file_size=animation.size, file_name=file_name, date=animation.date, + thumbnails=Thumbnail._parse(client, animation), client=client ) diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index 76181a22..ccea2f3c 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -17,10 +17,11 @@ # along with Pyrogram. If not, see . from struct import pack +from typing import List import pyrogram from pyrogram.api import types -from .photo_size import PhotoSize +from .thumbnail import Thumbnail from ..pyrogram_type import PyrogramType from ...ext.utils import encode @@ -35,9 +36,6 @@ class Audio(PyrogramType): duration (``int``): Duration of the audio in seconds as defined by sender. - thumb (:obj:`PhotoSize`, *optional*): - Thumbnail of the music file album cover. - file_name (``str``, *optional*): Audio file name. @@ -55,9 +53,14 @@ class Audio(PyrogramType): title (``str``, *optional*): Title of the audio as defined by sender or by audio tags. + + thumbnails (List of :obj:`Thumbnail`, *optional*): + Thumbnails of the music file album cover. """ - __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date", "duration", "performer", "title"] + __slots__ = [ + "file_id", "file_name", "mime_type", "file_size", "date", "duration", "performer", "title", "thumbnails" + ] def __init__( self, @@ -65,18 +68,17 @@ class Audio(PyrogramType): client: "pyrogram.BaseClient" = None, file_id: str, duration: int, - thumb: PhotoSize = None, file_name: str = None, mime_type: str = None, file_size: int = None, date: int = None, performer: str = None, - title: str = None + title: str = None, + thumbnails: List[Thumbnail] = None, ): super().__init__(client) self.file_id = file_id - self.thumb = thumb self.file_name = file_name self.mime_type = mime_type self.file_size = file_size @@ -84,10 +86,15 @@ class Audio(PyrogramType): self.duration = duration self.performer = performer self.title = title + self.thumbnails = thumbnails @staticmethod - def _parse(client, audio: types.Document, audio_attributes: types.DocumentAttributeAudio, - file_name: str) -> "Audio": + def _parse( + client, + audio: types.Document, + audio_attributes: types.DocumentAttributeAudio, + file_name: str + ) -> "Audio": return Audio( file_id=encode( pack( @@ -103,8 +110,8 @@ class Audio(PyrogramType): title=audio_attributes.title, mime_type=audio.mime_type, file_size=audio.size, - thumb=PhotoSize._parse(client, audio.thumbs), file_name=file_name, date=audio.date, + thumbnails=Thumbnail._parse(client, audio), client=client ) diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index 394d5e14..654516e8 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -17,10 +17,11 @@ # along with Pyrogram. If not, see . from struct import pack +from typing import List import pyrogram from pyrogram.api import types -from .photo_size import PhotoSize +from .thumbnail import Thumbnail from ..pyrogram_type import PyrogramType from ...ext.utils import encode @@ -32,9 +33,6 @@ class Document(PyrogramType): file_id (``str``): Unique file identifier. - thumb (:obj:`PhotoSize`, *optional*): - Document thumbnail as defined by sender. - file_name (``str``, *optional*): Original filename as defined by sender. @@ -46,29 +44,32 @@ class Document(PyrogramType): date (``int``, *optional*): Date the document was sent in Unix time. + + thumbnails (List of :obj:`Thumbnail`, *optional*): + Document thumbnails as defined by sender. """ - __slots__ = ["file_id", "thumb", "file_name", "mime_type", "file_size", "date"] + __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "thumbnails"] def __init__( self, *, client: "pyrogram.BaseClient" = None, file_id: str, - thumb: PhotoSize = None, file_name: str = None, mime_type: str = None, file_size: int = None, - date: int = None + date: int = None, + thumbnails: List[Thumbnail] = None, ): super().__init__(client) self.file_id = file_id - self.thumb = thumb self.file_name = file_name self.mime_type = mime_type self.file_size = file_size - self.date = date + self.date = date, + self.thumbnails = thumbnails @staticmethod def _parse(client, document: types.Document, file_name: str) -> "Document": @@ -82,10 +83,10 @@ class Document(PyrogramType): document.access_hash ) ), - thumb=PhotoSize._parse(client, document.thumbs), file_name=file_name, mime_type=document.mime_type, file_size=document.size, date=document.date, + thumbnails=Thumbnail._parse(client, document), client=client ) diff --git a/pyrogram/client/types/messages_and_media/photo.py b/pyrogram/client/types/messages_and_media/photo.py index 8d60d59a..ca42c3eb 100644 --- a/pyrogram/client/types/messages_and_media/photo.py +++ b/pyrogram/client/types/messages_and_media/photo.py @@ -16,13 +16,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from base64 import b64encode from struct import pack from typing import List import pyrogram from pyrogram.api import types -from .photo_size import PhotoSize +from .thumbnail import Thumbnail from ..pyrogram_type import PyrogramType from ...ext.utils import encode @@ -31,74 +30,65 @@ class Photo(PyrogramType): """A Photo. Parameters: - id (``str``): + file_id (``str``): Unique identifier for this photo. + width (``int``): + Photo width. + + height (``int``): + Photo height. + + file_size (``int``): + File size. + date (``int``): Date the photo was sent in Unix time. - sizes (List of :obj:`PhotoSize`): + thumbnails (List of :obj:`Thumbnail`): Available sizes of this photo. """ - __slots__ = ["id", "date", "sizes"] + __slots__ = ["file_id", "width", "height", "file_size", "date", "thumbnails"] def __init__( self, *, client: "pyrogram.BaseClient" = None, - id: str, + file_id: str, + width: int, + height: int, + file_size: int, date: int, - sizes: List[PhotoSize] + thumbnails: List[Thumbnail] ): super().__init__(client) - self.id = id + self.file_id = file_id + self.width = width + self.height = height + self.file_size = file_size self.date = date - self.sizes = sizes + self.thumbnails = thumbnails @staticmethod - def _parse(client, photo: types.Photo): + def _parse(client, photo: types.Photo) -> "Photo": if isinstance(photo, types.Photo): - raw_sizes = photo.sizes - sizes = [] - - for raw_size in raw_sizes: - if isinstance(raw_size, (types.PhotoSize, types.PhotoCachedSize)): - if isinstance(raw_size, types.PhotoSize): - file_size = raw_size.size - elif isinstance(raw_size, types.PhotoCachedSize): - file_size = len(raw_size.bytes) - else: - file_size = 0 - - loc = raw_size.location - - if isinstance(loc, types.FileLocation): - size = PhotoSize( - file_id=encode( - pack( - ". from struct import pack +from typing import List import pyrogram from pyrogram.api import types -from .photo_size import PhotoSize +from .thumbnail import Thumbnail from ..pyrogram_type import PyrogramType from ...ext.utils import encode @@ -41,9 +42,6 @@ class Video(PyrogramType): duration (``int``): Duration of the video in seconds as defined by sender. - thumb (:obj:`PhotoSize`, *optional*): - Video thumbnail. - file_name (``str``, *optional*): Video file name. @@ -58,11 +56,14 @@ class Video(PyrogramType): date (``int``, *optional*): Date the video was sent in Unix time. + + thumbnails (List of :obj:`Thumbnail`, *optional*): + Video thumbnails. """ __slots__ = [ - "file_id", "width", "height", "duration", "thumb", "file_name", "mime_type", "supports_streaming", "file_size", - "date" + "file_id", "width", "height", "duration", "file_name", "mime_type", "supports_streaming", "file_size", "date", + "thumbnails" ] def __init__( @@ -73,12 +74,12 @@ class Video(PyrogramType): width: int, height: int, duration: int, - thumb: PhotoSize = None, file_name: str = None, mime_type: str = None, supports_streaming: bool = None, file_size: int = None, - date: int = None + date: int = None, + thumbnails: List[Thumbnail] = None ): super().__init__(client) @@ -86,16 +87,20 @@ class Video(PyrogramType): self.width = width self.height = height self.duration = duration - self.thumb = thumb self.file_name = file_name self.mime_type = mime_type self.supports_streaming = supports_streaming self.file_size = file_size self.date = date + self.thumbnails = thumbnails @staticmethod - def _parse(client, video: types.Document, video_attributes: types.DocumentAttributeVideo, - file_name: str) -> "Video": + def _parse( + client, + video: types.Document, + video_attributes: types.DocumentAttributeVideo, + file_name: str + ) -> "Video": return Video( file_id=encode( pack( @@ -109,11 +114,11 @@ class Video(PyrogramType): width=video_attributes.w, height=video_attributes.h, duration=video_attributes.duration, - thumb=PhotoSize._parse(client, video.thumbs), file_name=file_name, mime_type=video.mime_type, supports_streaming=video_attributes.supports_streaming, file_size=video.size, date=video.date, + thumbnails=Thumbnail._parse(client, video), client=client ) diff --git a/pyrogram/client/types/messages_and_media/video_note.py b/pyrogram/client/types/messages_and_media/video_note.py index 133ccae0..34f5972f 100644 --- a/pyrogram/client/types/messages_and_media/video_note.py +++ b/pyrogram/client/types/messages_and_media/video_note.py @@ -17,10 +17,11 @@ # along with Pyrogram. If not, see . from struct import pack +from typing import List import pyrogram from pyrogram.api import types -from .photo_size import PhotoSize +from .thumbnail import Thumbnail from ..pyrogram_type import PyrogramType from ...ext.utils import encode @@ -38,9 +39,6 @@ class VideoNote(PyrogramType): duration (``int``): Duration of the video in seconds as defined by sender. - thumb (:obj:`PhotoSize`, *optional*): - Video thumbnail. - mime_type (``str``, *optional*): MIME type of the file as defined by sender. @@ -49,9 +47,12 @@ class VideoNote(PyrogramType): date (``int``, *optional*): Date the video note was sent in Unix time. + + thumbnails (List of :obj:`Thumbnail`, *optional*): + Video thumbnails. """ - __slots__ = ["file_id", "thumb", "mime_type", "file_size", "date", "length", "duration"] + __slots__ = ["file_id", "mime_type", "file_size", "date", "length", "duration", "thumbnails"] def __init__( self, @@ -60,7 +61,7 @@ class VideoNote(PyrogramType): file_id: str, length: int, duration: int, - thumb: PhotoSize = None, + thumbnails: List[Thumbnail] = None, mime_type: str = None, file_size: int = None, date: int = None @@ -68,12 +69,12 @@ class VideoNote(PyrogramType): super().__init__(client) self.file_id = file_id - self.thumb = thumb self.mime_type = mime_type self.file_size = file_size self.date = date self.length = length self.duration = duration + self.thumbnails = thumbnails @staticmethod def _parse(client, video_note: types.Document, video_attributes: types.DocumentAttributeVideo) -> "VideoNote": @@ -89,9 +90,9 @@ class VideoNote(PyrogramType): ), length=video_attributes.w, duration=video_attributes.duration, - thumb=PhotoSize._parse(client, video_note.thumbs), file_size=video_note.size, mime_type=video_note.mime_type, date=video_note.date, + thumbnails=Thumbnail._parse(client, video_note), client=client ) From 55599e33c67d7a67eb1a3a227d05975df25fdb35 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 10:40:37 +0200 Subject: [PATCH 103/202] Rework download_media to accommodate L100 changes --- pyrogram/client/client.py | 152 +++++++++--------- pyrogram/client/ext/base_client.py | 10 +- .../client/methods/messages/download_media.py | 131 +++++++++------ 3 files changed, 166 insertions(+), 127 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 0d1cde19..468413b0 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -17,7 +17,6 @@ # along with Pyrogram. If not, see . import base64 -import binascii import json import logging import math @@ -25,7 +24,6 @@ import mimetypes import os import re import shutil -import struct import tempfile import threading import time @@ -49,7 +47,7 @@ from pyrogram.errors import ( PhoneNumberUnoccupied, PhoneCodeInvalid, PhoneCodeHashEmpty, PhoneCodeExpired, PhoneCodeEmpty, SessionPasswordNeeded, PasswordHashInvalid, FloodWait, PeerIdInvalid, FirstnameInvalid, PhoneNumberBanned, - VolumeLocNotFound, UserMigrate, FileIdInvalid, ChannelPrivate, PhoneNumberOccupied, + VolumeLocNotFound, UserMigrate, ChannelPrivate, PhoneNumberOccupied, PasswordRecoveryNa, PasswordEmpty ) from pyrogram.session import Auth, Session @@ -829,85 +827,59 @@ class Client(Methods, BaseClient): log.debug("{} started".format(name)) while True: - media = self.download_queue.get() + packet = self.download_queue.get() - if media is None: + if packet is None: break temp_file_path = "" final_file_path = "" try: - media, file_name, done, progress, progress_args, path = media - - file_id = media.file_id - size = media.file_size + data, file_name, done, progress, progress_args, path = packet + data = data # type: BaseClient.FileData directory, file_name = os.path.split(file_name) directory = directory or "downloads" - try: - decoded = utils.decode(file_id) - fmt = " 24 else " 24: - volume_id = unpacked[4] - secret = unpacked[5] - local_id = unpacked[6] + if not data.file_name: + guessed_extension = self.guess_extension(data.mime_type) - media_type_str = Client.MEDIA_TYPE_ID.get(media_type, None) - - if media_type_str is None: - raise FileIdInvalid("Unknown media type: {}".format(unpacked[0])) - - file_name = file_name or getattr(media, "file_name", None) - - if not file_name: - guessed_extension = self.guess_extension(media.mime_type) - - if media_type in (0, 1, 2): + if data.media_type in (0, 1, 2, 14): extension = ".jpg" - elif media_type == 3: + elif data.media_type == 3: extension = guessed_extension or ".ogg" - elif media_type in (4, 10, 13): + elif data.media_type in (4, 10, 13): extension = guessed_extension or ".mp4" - elif media_type == 5: + elif data.media_type == 5: extension = guessed_extension or ".zip" - elif media_type == 8: + elif data.media_type == 8: extension = guessed_extension or ".webp" - elif media_type == 9: + elif data.media_type == 9: extension = guessed_extension or ".mp3" else: continue file_name = "{}_{}_{}{}".format( media_type_str, - datetime.fromtimestamp( - getattr(media, "date", None) or time.time() - ).strftime("%Y-%m-%d_%H-%M-%S"), + datetime.fromtimestamp(data.date or time.time()).strftime("%Y-%m-%d_%H-%M-%S"), self.rnd_id(), extension ) temp_file_path = self.get_file( - dc_id=dc_id, - id=id, - access_hash=access_hash, - volume_id=volume_id, - local_id=local_id, - secret=secret, - size=size, + media_type=data.media_type, + dc_id=data.dc_id, + file_id=data.file_id, + access_hash=data.access_hash, + thumb_size=data.thumb_size, + peer_id=data.peer_id, + volume_id=data.volume_id, + local_id=data.local_id, + file_size=data.file_size, + is_big=data.is_big, progress=progress, progress_args=progress_args ) @@ -1549,16 +1521,21 @@ class Client(Methods, BaseClient): finally: session.stop() - def get_file(self, - dc_id: int, - id: int = None, - access_hash: int = None, - volume_id: int = None, - local_id: int = None, - secret: int = None, - size: int = None, - progress: callable = None, - progress_args: tuple = ()) -> str: + def get_file( + self, + media_type: int, + dc_id: int, + file_id: int, + access_hash: int, + thumb_size: str, + peer_id: int, + volume_id: int, + local_id: int, + file_size: int, + is_big: bool, + progress: callable, + progress_args: tuple = () + ) -> str: with self.media_sessions_lock: session = self.media_sessions.get(dc_id, None) @@ -1599,18 +1576,33 @@ class Client(Methods, BaseClient): self.media_sessions[dc_id] = session - if volume_id: # Photos are accessed by volume_id, local_id, secret - location = types.InputFileLocation( + if media_type == 1: + location = types.InputPeerPhotoFileLocation( + peer=self.resolve_peer(peer_id), volume_id=volume_id, local_id=local_id, - secret=secret, - file_reference=b"" + big=is_big or None ) - else: # Any other file can be more easily accessed by id and access_hash - location = types.InputDocumentFileLocation( - id=id, + elif media_type in (0, 2): + location = types.InputPhotoFileLocation( + id=file_id, access_hash=access_hash, - file_reference=b"" + file_reference=b"", + thumb_size=thumb_size + ) + elif media_type == 14: + location = types.InputDocumentFileLocation( + id=file_id, + access_hash=access_hash, + file_reference=b"", + thumb_size=thumb_size + ) + else: + location = types.InputDocumentFileLocation( + id=file_id, + access_hash=access_hash, + file_reference=b"", + thumb_size="" ) limit = 1024 * 1024 @@ -1641,7 +1633,14 @@ class Client(Methods, BaseClient): offset += limit if progress: - progress(self, min(offset, size) if size != 0 else offset, size, *progress_args) + progress( + self, + min(offset, file_size) + if file_size != 0 + else offset, + file_size, + *progress_args + ) r = session.send( functions.upload.GetFile( @@ -1723,7 +1722,14 @@ class Client(Methods, BaseClient): offset += limit if progress: - progress(self, min(offset, size) if size != 0 else offset, size, *progress_args) + progress( + self, + min(offset, file_size) + if file_size != 0 + else offset, + file_size, + *progress_args + ) if len(chunk) < limit: break diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index a3816bdf..3397c8d3 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -19,6 +19,7 @@ import os import platform import re +from collections import namedtuple from queue import Queue from threading import Lock @@ -56,7 +57,7 @@ class BaseClient: CONFIG_FILE = "./config.ini" MEDIA_TYPE_ID = { - 0: "thumbnail", + 0: "photo_thumbnail", 1: "chat_photo", 2: "photo", 3: "voice", @@ -65,7 +66,8 @@ class BaseClient: 8: "sticker", 9: "audio", 10: "animation", - 13: "video_note" + 13: "video_note", + 14: "document_thumbnail" } mime_types_to_extensions = {} @@ -82,6 +84,10 @@ class BaseClient: mime_types_to_extensions[mime_type] = " ".join(extensions) + fields = ("media_type", "dc_id", "file_id", "access_hash", "thumb_size", "peer_id", "volume_id", "local_id", + "is_big", "file_size", "mime_type", "file_name", "date") + FileData = namedtuple("FileData", fields, defaults=(None,) * len(fields)) + def __init__(self): self.is_bot = None self.dc_id = None diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index c21a95bf..bba5afd5 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -16,11 +16,14 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +import binascii +import struct from threading import Event from typing import Union import pyrogram -from pyrogram.client.ext import BaseClient +from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FileIdInvalid class DownloadMedia(BaseClient): @@ -81,67 +84,91 @@ class DownloadMedia(BaseClient): ``ValueError`` if the message doesn't contain any downloadable media """ error_message = "This message doesn't contain any downloadable media" + available_media = ("audio", "document", "photo", "sticker", "animation", "video", "voice", "video_note") + + file_size = None + mime_type = None + date = None if isinstance(message, pyrogram.Message): - if message.photo: - media = pyrogram.Document( - file_id=message.photo.sizes[-1].file_id, - file_size=message.photo.sizes[-1].file_size, - mime_type="", - date=message.photo.date, - client=self - ) - elif message.audio: - media = message.audio - elif message.document: - media = message.document - elif message.video: - media = message.video - elif message.voice: - media = message.voice - elif message.video_note: - media = message.video_note - elif message.sticker: - media = message.sticker - elif message.animation: - media = message.animation + for kind in available_media: + media = getattr(message, kind, None) + + if media is not None: + break else: raise ValueError(error_message) - elif isinstance(message, ( - pyrogram.Photo, - pyrogram.PhotoSize, - pyrogram.Audio, - pyrogram.Document, - pyrogram.Video, - pyrogram.Voice, - pyrogram.VideoNote, - pyrogram.Sticker, - pyrogram.Animation - )): - if isinstance(message, pyrogram.Photo): - media = pyrogram.Document( - file_id=message.sizes[-1].file_id, - file_size=message.sizes[-1].file_size, - mime_type="", - date=message.date, - client=self + else: + media = message + + if isinstance(media, str): + file_id_str = media + else: + file_id_str = media.file_id + file_name = getattr(media, "file_name", "") + file_size = getattr(media, "file_size", None) + mime_type = getattr(media, "mime_type", None) + date = getattr(media, "date", None) + + data = self.FileData( + file_name=file_name, + file_size=file_size, + mime_type=mime_type, + date=date + ) + + def get_existing_attributes() -> dict: + return dict(filter(lambda x: x[1] is not None, data._asdict().items())) + + try: + decoded = utils.decode(file_id_str) + media_type = decoded[0] + + if media_type == 1: + unpacked = struct.unpack(" Date: Wed, 29 May 2019 10:40:48 +0200 Subject: [PATCH 104/202] Update docs --- docs/source/api/methods.rst | 18 +++++++++--------- docs/source/api/types.rst | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index 7614918e..760c332b 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -107,14 +107,14 @@ Users ^^^^^ .. hlist:: - :columns: 2 + :columns: 3 - :meth:`~Client.get_me` - :meth:`~Client.get_users` - - :meth:`~Client.get_user_profile_photos` - - :meth:`~Client.get_user_profile_photos_count` - - :meth:`~Client.set_user_profile_photo` - - :meth:`~Client.delete_user_profile_photos` + - :meth:`~Client.get_user_photos` + - :meth:`~Client.get_user_photos_count` + - :meth:`~Client.set_photo` + - :meth:`~Client.delete_photos` - :meth:`~Client.update_username` - :meth:`~Client.get_user_dc` @@ -232,10 +232,10 @@ Details .. Users .. automethod:: Client.get_me() .. automethod:: Client.get_users() -.. automethod:: Client.get_user_profile_photos() -.. automethod:: Client.get_user_profile_photos_count() -.. automethod:: Client.set_user_profile_photo() -.. automethod:: Client.delete_user_profile_photos() +.. automethod:: Client.get_user_photos() +.. automethod:: Client.get_user_photos_count() +.. automethod:: Client.set_photo() +.. automethod:: Client.delete_photos() .. automethod:: Client.update_username() .. automethod:: Client.get_user_dc() diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index d264eaa2..15f81ae7 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -45,8 +45,8 @@ Messages & Media - :class:`Messages` - :class:`MessageEntity` - :class:`Photo` - - :class:`PhotoSize` - - :class:`UserProfilePhotos` + - :class:`Photos` + - :class:`Thumbnail` - :class:`Audio` - :class:`Document` - :class:`Animation` @@ -133,8 +133,8 @@ Details .. autoclass:: Messages() .. autoclass:: MessageEntity() .. autoclass:: Photo() -.. autoclass:: PhotoSize() -.. autoclass:: UserProfilePhotos() +.. autoclass:: Photos() +.. autoclass:: Thumbnail() .. autoclass:: Audio() .. autoclass:: Document() .. autoclass:: Animation() From 16dbd8d8db248308592b0f940af6b5f2a1e7a18d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 10:41:04 +0200 Subject: [PATCH 105/202] Update development version --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index cbba2fbf..f87b2b0d 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -24,7 +24,7 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]: # Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one. sys.modules["typing"] = typing -__version__ = "0.13.0" +__version__ = "0.14.0-develop" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __copyright__ = "Copyright (C) 2017-2019 Dan " From 08d120be7477ba097e64f61e70440f01f9f4e677 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 29 May 2019 13:11:48 +0200 Subject: [PATCH 106/202] Add the LAYER attribute to each constructor --- compiler/api/compiler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 21348336..64e88c9d 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -333,6 +333,7 @@ def start(): docstring_args = "No parameters required." docstring_args = "Attributes:\n ID: ``{}``\n\n ".format(c.id) + docstring_args + docstring_args = "Attributes:\n LAYER: ``{}``\n\n ".format(layer) + docstring_args if c.section == "functions": docstring_args += "\n\n Returns:\n " + get_docstring_arg_type(c.return_type) From 376909f3565cfc3ea2f556873eb38c806747d207 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 30 May 2019 14:56:59 +0200 Subject: [PATCH 107/202] Add get_input_media_from_file_id utility method For internal usage --- pyrogram/client/ext/utils.py | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 981752fa..e1959309 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -16,8 +16,11 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +import struct from base64 import b64decode, b64encode +from typing import Union +from . import BaseClient from ...api import types @@ -82,3 +85,53 @@ def get_offset_date(dialogs): return m.date else: return 0 + + +def get_input_media_from_file_id( + file_id_str: str, + expected_media_type: int = None +) -> Union[types.InputMediaPhoto, types.InputMediaDocument]: + try: + decoded = decode(file_id_str) + except Exception: + raise ValueError("Failed to decode file_id: {}".format(file_id_str)) + else: + media_type = decoded[0] + + if expected_media_type is not None: + if media_type != expected_media_type: + media_type_str = BaseClient.MEDIA_TYPE_ID.get(media_type, None) + expected_media_type_str = BaseClient.MEDIA_TYPE_ID.get(expected_media_type, None) + + raise ValueError( + 'Expected: "{}", got "{}" file_id instead'.format(expected_media_type_str, media_type_str) + ) + + if media_type in (0, 1, 14): + raise ValueError("This file_id can only be used for download: {}".format(file_id_str)) + + if media_type == 2: + unpacked = struct.unpack(" Date: Thu, 30 May 2019 14:57:52 +0200 Subject: [PATCH 108/202] Update send_* methods (for file_ids) --- .../methods/messages/edit_message_media.py | 118 +----------------- .../client/methods/messages/send_animation.py | 27 +--- .../client/methods/messages/send_audio.py | 27 +--- .../methods/messages/send_cached_media.py | 34 +---- .../methods/messages/send_chat_action.py | 2 +- .../client/methods/messages/send_document.py | 27 +--- .../methods/messages/send_media_group.py | 50 +------- .../client/methods/messages/send_photo.py | 28 +---- .../client/methods/messages/send_sticker.py | 27 +--- .../client/methods/messages/send_video.py | 27 +--- .../methods/messages/send_video_note.py | 27 +--- .../client/methods/messages/send_voice.py | 27 +--- 12 files changed, 26 insertions(+), 395 deletions(-) diff --git a/pyrogram/client/methods/messages/edit_message_media.py b/pyrogram/client/methods/messages/edit_message_media.py index b15daa9b..3793c693 100644 --- a/pyrogram/client/methods/messages/edit_message_media.py +++ b/pyrogram/client/methods/messages/edit_message_media.py @@ -16,14 +16,11 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid from pyrogram.client.ext import BaseClient, utils from pyrogram.client.types import ( InputMediaPhoto, InputMediaVideo, InputMediaAudio, @@ -94,28 +91,7 @@ class EditMessageMedia(BaseClient): url=media.media ) else: - try: - decoded = utils.decode(media.media) - fmt = " 24 else " 24 else " 24 else " 24 else " 24 else ". -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendAnimation(BaseClient): @@ -153,28 +151,7 @@ class SendAnimation(BaseClient): url=animation ) else: - try: - decoded = utils.decode(animation) - fmt = " 24 else ". -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendAudio(BaseClient): @@ -153,28 +151,7 @@ class SendAudio(BaseClient): url=audio ) else: - try: - decoded = utils.decode(audio) - fmt = " 24 else ". -import binascii -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid from pyrogram.client.ext import BaseClient, utils @@ -84,39 +81,10 @@ class SendCachedMedia(BaseClient): """ style = self.html if parse_mode.lower() == "html" else self.markdown - try: - decoded = utils.decode(file_id) - fmt = " 24 else ". +import json from typing import Union from pyrogram.api import functions, types from pyrogram.client.ext import BaseClient -import json class ChatAction: diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index df202fd7..ff523303 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -16,15 +16,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendDocument(BaseClient): @@ -134,28 +132,7 @@ class SendDocument(BaseClient): url=document ) else: - try: - decoded = utils.decode(document) - fmt = " 24 else ". -import binascii import logging import os -import struct import time from typing import Union, List import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FloodWait from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FloodWait log = logging.getLogger(__name__) @@ -96,28 +94,7 @@ class SendMediaGroup(BaseClient): ) ) else: - try: - decoded = utils.decode(i.media) - fmt = " 24 else " 24 else ". -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendPhoto(BaseClient): @@ -129,29 +127,7 @@ class SendPhoto(BaseClient): ttl_seconds=ttl_seconds ) else: - try: - decoded = utils.decode(photo) - fmt = " 24 else ". -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendSticker(BaseClient): @@ -114,28 +112,7 @@ class SendSticker(BaseClient): url=sticker ) else: - try: - decoded = utils.decode(sticker) - fmt = " 24 else ". -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendVideo(BaseClient): @@ -156,28 +154,7 @@ class SendVideo(BaseClient): url=video ) else: - try: - decoded = utils.decode(video) - fmt = " 24 else ". -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendVideoNote(BaseClient): @@ -133,28 +131,7 @@ class SendVideoNote(BaseClient): ] ) else: - try: - decoded = utils.decode(video_note) - fmt = " 24 else ". -import binascii import os -import struct from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.errors import FileIdInvalid, FilePartMissing from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing class SendVoice(BaseClient): @@ -132,28 +130,7 @@ class SendVoice(BaseClient): url=voice ) else: - try: - decoded = utils.decode(voice) - fmt = " 24 else " Date: Thu, 30 May 2019 15:23:43 +0200 Subject: [PATCH 109/202] Refactor docstrings --- pyrogram/client/client.py | 8 +++---- pyrogram/client/filters/filters.py | 8 +++---- .../client/handlers/callback_query_handler.py | 4 ++-- .../handlers/deleted_messages_handler.py | 4 ++-- .../client/handlers/disconnect_handler.py | 4 ++-- .../client/handlers/inline_query_handler.py | 4 ++-- pyrogram/client/handlers/message_handler.py | 5 ++--- pyrogram/client/handlers/poll_handler.py | 10 ++++----- .../client/handlers/raw_update_handler.py | 6 +++--- .../client/handlers/user_status_handler.py | 4 ++-- .../methods/chats/export_chat_invite_link.py | 4 ++-- .../client/methods/chats/get_chat_members.py | 2 +- pyrogram/client/methods/chats/get_dialogs.py | 2 +- .../client/methods/chats/iter_chat_members.py | 2 +- pyrogram/client/methods/chats/iter_dialogs.py | 5 +++-- .../client/methods/chats/set_chat_photo.py | 2 +- .../methods/chats/update_chat_username.py | 2 +- .../methods/decorators/on_callback_query.py | 2 +- .../methods/decorators/on_deleted_messages.py | 2 +- .../methods/decorators/on_disconnect.py | 2 +- .../methods/decorators/on_inline_query.py | 2 +- .../client/methods/decorators/on_message.py | 2 +- pyrogram/client/methods/decorators/on_poll.py | 4 ++-- .../methods/decorators/on_raw_update.py | 2 +- .../methods/decorators/on_user_status.py | 2 +- .../client/methods/messages/download_media.py | 2 +- .../client/methods/messages/get_history.py | 2 +- .../client/methods/messages/iter_history.py | 5 +++-- .../client/methods/messages/send_animation.py | 2 +- .../client/methods/messages/send_audio.py | 2 +- .../client/methods/messages/send_document.py | 2 +- .../client/methods/messages/send_photo.py | 2 +- .../client/methods/messages/send_sticker.py | 2 +- .../client/methods/messages/send_video.py | 2 +- .../methods/messages/send_video_note.py | 2 +- .../client/methods/messages/send_voice.py | 2 +- .../client/methods/users/update_username.py | 2 +- .../client/types/inline_mode/inline_query.py | 4 ++-- .../inline_query_result_article.py | 4 ++-- .../todo/inline_query_result_audio.py | 4 ++-- .../inline_query_result_cached_document.py | 4 ++-- .../todo/inline_query_result_cached_gif.py | 4 ++-- .../inline_query_result_cached_sticker.py | 4 ++-- .../todo/inline_query_result_cached_voice.py | 4 ++-- .../todo/inline_query_result_document.py | 4 ++-- .../todo/inline_query_result_game.py | 2 +- .../todo/inline_query_result_photo.py | 4 ++-- .../todo/inline_query_result_venue.py | 4 ++-- .../todo/inline_query_result_video.py | 4 ++-- .../todo/inline_query_result_voice.py | 4 ++-- .../types/input_media/input_phone_contact.py | 2 +- .../types/messages_and_media/message.py | 21 +++++++++---------- .../types/messages_and_media/messages.py | 2 +- pyrogram/client/types/user_and_chats/chat.py | 14 ++++++------- 54 files changed, 105 insertions(+), 105 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 468413b0..e93e3ff8 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -434,9 +434,9 @@ class Client(Methods, BaseClient): def run(self): """Start the Client and automatically idle the main script. - This is a convenience method that literally just calls :meth:`start` and :meth:`idle`. It makes running a client - less verbose, but is not suitable in case you want to run more than one client in a single main script, - since :meth:`idle` will block. + This is a convenience method that literally just calls :meth:`~Client.start` and :meth:`~Client.idle`. It makes + running a client less verbose, but is not suitable in case you want to run more than one client in a single main + script, since :meth:`~Client.idle` will block. Raises: RPCError: In case of a Telegram RPC error. @@ -472,7 +472,7 @@ class Client(Methods, BaseClient): """Remove a previously-registered update handler. Make sure to provide the right group that the handler was added in. You can use - the return value of the :meth:`add_handler` method, a tuple of (handler, group), and + the return value of the :meth:`~Client.add_handler` method, a tuple of (handler, group), and pass it directly. Parameters: diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 169193a0..9c80d870 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -42,7 +42,7 @@ def create(name: str, func: callable, **kwargs) -> type: **kwargs (``any``, *optional*): Any keyword argument you would like to pass. Useful for custom filters that accept parameters (e.g.: - :meth:`Filters.command`, :meth:`Filters.regex`). + :meth:`~Filters.command`, :meth:`~Filters.regex`). """ # TODO: unpack kwargs using **kwargs into the dict itself. For Python 3.5+ only d = {"__call__": func} @@ -56,7 +56,7 @@ class Filters: The Filters listed here are intended to be used with the :obj:`MessageHandler` only. At the moment, if you want to filter updates coming from different `Handlers `_ you have to create - your own filters with :meth:`Filters.create` and use them in the same way. + your own filters with :meth:`~Filters.create` and use them in the same way. """ create = create @@ -219,7 +219,7 @@ class Filters: The command or list of commands as string the filter should look for. Examples: "start", ["start", "help", "settings"]. When a message text containing a command arrives, the command itself and its arguments will be stored in the *command* - field of the :class:`Message`. + field of the :obj:`Message`. prefix (``str`` | ``list``, *optional*): A prefix or a list of prefixes as string the filter should look for. @@ -263,7 +263,7 @@ class Filters: pattern (``str``): The RegEx pattern as string, it will be applied to the text of a message. When a pattern matches, all the `Match Objects `_ - are stored in the *matches* field of the :class:`Message` itself. + are stored in the *matches* field of the :obj:`Message` itself. flags (``int``, *optional*): RegEx flags. diff --git a/pyrogram/client/handlers/callback_query_handler.py b/pyrogram/client/handlers/callback_query_handler.py index feb46cb0..9e17296b 100644 --- a/pyrogram/client/handlers/callback_query_handler.py +++ b/pyrogram/client/handlers/callback_query_handler.py @@ -21,10 +21,10 @@ from .handler import Handler class CallbackQueryHandler(Handler): """The CallbackQuery handler class. Used to handle callback queries coming from inline buttons. - It is intended to be used with :meth:`add_handler() ` + It is intended to be used with :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_callback_query() ` decorator. + :meth:`~Client.on_callback_query` decorator. Parameters: callback (``callable``): diff --git a/pyrogram/client/handlers/deleted_messages_handler.py b/pyrogram/client/handlers/deleted_messages_handler.py index f37caaed..b6651fba 100644 --- a/pyrogram/client/handlers/deleted_messages_handler.py +++ b/pyrogram/client/handlers/deleted_messages_handler.py @@ -22,10 +22,10 @@ from .handler import Handler class DeletedMessagesHandler(Handler): """The deleted Messages handler class. Used to handle deleted messages coming from any chat (private, group, channel). It is intended to be used with - :meth:`add_handler() ` + :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_deleted_messages() ` decorator. + :meth:`~Client.on_deleted_messages` decorator. Parameters: callback (``callable``): diff --git a/pyrogram/client/handlers/disconnect_handler.py b/pyrogram/client/handlers/disconnect_handler.py index b9e6350a..1b4801b2 100644 --- a/pyrogram/client/handlers/disconnect_handler.py +++ b/pyrogram/client/handlers/disconnect_handler.py @@ -21,10 +21,10 @@ from .handler import Handler class DisconnectHandler(Handler): """The Disconnect handler class. Used to handle disconnections. It is intended to be used with - :meth:`add_handler() ` + :meth:~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_disconnect() ` decorator. + :meth:`~Client.on_disconnect` decorator. Parameters: callback (``callable``): diff --git a/pyrogram/client/handlers/inline_query_handler.py b/pyrogram/client/handlers/inline_query_handler.py index 98a25652..dbd86df7 100644 --- a/pyrogram/client/handlers/inline_query_handler.py +++ b/pyrogram/client/handlers/inline_query_handler.py @@ -21,10 +21,10 @@ from .handler import Handler class InlineQueryHandler(Handler): """The InlineQuery handler class. Used to handle inline queries. - It is intended to be used with :meth:`add_handler() ` + It is intended to be used with :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_inline_query() ` decorator. + :meth:`~Client.on_inline_query` decorator. Parameters: callback (``callable``): diff --git a/pyrogram/client/handlers/message_handler.py b/pyrogram/client/handlers/message_handler.py index 10fff479..ea091ca4 100644 --- a/pyrogram/client/handlers/message_handler.py +++ b/pyrogram/client/handlers/message_handler.py @@ -21,11 +21,10 @@ from .handler import Handler class MessageHandler(Handler): """The Message handler class. Used to handle text, media and service messages coming from - any chat (private, group, channel). It is intended to be used with - :meth:`add_handler() ` + any chat (private, group, channel). It is intended to be used with :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_message() ` decorator. + :meth:`~Client.on_message` decorator. Parameters: callback (``callable``): diff --git a/pyrogram/client/handlers/poll_handler.py b/pyrogram/client/handlers/poll_handler.py index 9e97f2ac..d46fb5be 100644 --- a/pyrogram/client/handlers/poll_handler.py +++ b/pyrogram/client/handlers/poll_handler.py @@ -22,25 +22,25 @@ from .handler import Handler class PollHandler(Handler): """The Poll handler class. Used to handle polls updates. - It is intended to be used with :meth:`add_handler() ` + It is intended to be used with :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_poll() ` decorator. + :meth:`~Client.on_poll` decorator. Parameters: callback (``callable``): Pass a function that will be called when a new poll update arrives. It takes *(client, poll)* as positional arguments (look at the section below for a detailed description). - filters (:obj:`Filters `): + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of polls to be passed in your callback function. Other parameters: - client (:obj:`Client `): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the poll handler. - poll (:obj:`Poll `): + poll (:obj:`Poll`): The received poll. """ diff --git a/pyrogram/client/handlers/raw_update_handler.py b/pyrogram/client/handlers/raw_update_handler.py index f54d59b6..485c6339 100644 --- a/pyrogram/client/handlers/raw_update_handler.py +++ b/pyrogram/client/handlers/raw_update_handler.py @@ -21,10 +21,10 @@ from .handler import Handler class RawUpdateHandler(Handler): """The Raw Update handler class. Used to handle raw updates. It is intended to be used with - :meth:`add_handler() ` + :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_raw_update() ` decorator. + :meth:`~Client.on_raw_update` decorator. Parameters: callback (``callable``): @@ -33,7 +33,7 @@ class RawUpdateHandler(Handler): a detailed description). Other Parameters: - client (:class:`Client`): + client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the update handler. update (``Update``): diff --git a/pyrogram/client/handlers/user_status_handler.py b/pyrogram/client/handlers/user_status_handler.py index 1250cb19..9b39aab6 100644 --- a/pyrogram/client/handlers/user_status_handler.py +++ b/pyrogram/client/handlers/user_status_handler.py @@ -21,10 +21,10 @@ from .handler import Handler class UserStatusHandler(Handler): """The UserStatus handler class. Used to handle user status updates (user going online or offline). - It is intended to be used with :meth:`add_handler() ` + It is intended to be used with :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the - :meth:`on_user_status() ` decorator. + :meth:`~Client.on_user_status` decorator. Parameters: callback (``callable``): diff --git a/pyrogram/client/methods/chats/export_chat_invite_link.py b/pyrogram/client/methods/chats/export_chat_invite_link.py index a223a000..26263d53 100644 --- a/pyrogram/client/methods/chats/export_chat_invite_link.py +++ b/pyrogram/client/methods/chats/export_chat_invite_link.py @@ -35,8 +35,8 @@ class ExportChatInviteLink(BaseClient): Each administrator in a chat generates their own invite links. Bots can't use invite links generated by other administrators. If you want your bot to work with invite links, it will need to generate its own link - using this method – after this the link will become available to the bot via the :meth:`get_chat` method. - If your bot needs to generate a new invite link replacing its previous one, use this method again. + using this method – after this the link will become available to the bot via the :meth:`~Client.get_chat` + method. If your bot needs to generate a new invite link replacing its previous one, use this method again. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/chats/get_chat_members.py b/pyrogram/client/methods/chats/get_chat_members.py index 10f76dcf..1c966f36 100644 --- a/pyrogram/client/methods/chats/get_chat_members.py +++ b/pyrogram/client/methods/chats/get_chat_members.py @@ -51,7 +51,7 @@ class GetChatMembers(BaseClient): You can get up to 200 chat members at once. A chat can be either a basic group, a supergroup or a channel. You must be admin to retrieve the members list of a channel (also known as "subscribers"). - For a more convenient way of getting chat members see :meth:`iter_chat_members`. + For a more convenient way of getting chat members see :meth:`~Client.iter_chat_members`. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/chats/get_dialogs.py b/pyrogram/client/methods/chats/get_dialogs.py index 948a7642..8d5baa15 100644 --- a/pyrogram/client/methods/chats/get_dialogs.py +++ b/pyrogram/client/methods/chats/get_dialogs.py @@ -37,7 +37,7 @@ class GetDialogs(BaseClient): """Get a chunk of the user's dialogs. You can get up to 100 dialogs at once. - For a more convenient way of getting a user's dialogs see :meth:`iter_dialogs`. + For a more convenient way of getting a user's dialogs see :meth:`~Client.iter_dialogs`. Parameters: offset_date (``int``): diff --git a/pyrogram/client/methods/chats/iter_chat_members.py b/pyrogram/client/methods/chats/iter_chat_members.py index 330eed7b..961f6d98 100644 --- a/pyrogram/client/methods/chats/iter_chat_members.py +++ b/pyrogram/client/methods/chats/iter_chat_members.py @@ -47,7 +47,7 @@ class IterChatMembers(BaseClient): ) -> Generator["pyrogram.ChatMember", None, None]: """Iterate through the members of a chat sequentially. - This convenience method does the same as repeatedly calling :meth:`get_chat_members` in a loop, thus saving you + This convenience method does the same as repeatedly calling :meth:`~Client.get_chat_members` in a loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting the whole members list of a chat with a single call. diff --git a/pyrogram/client/methods/chats/iter_dialogs.py b/pyrogram/client/methods/chats/iter_dialogs.py index 976a49df..e7fb7330 100644 --- a/pyrogram/client/methods/chats/iter_dialogs.py +++ b/pyrogram/client/methods/chats/iter_dialogs.py @@ -30,8 +30,9 @@ class IterDialogs(BaseClient): ) -> Generator["pyrogram.Dialog", None, None]: """Iterate through a user's dialogs sequentially. - This convenience method does the same as repeatedly calling :meth:`get_dialogs` in a loop, thus saving you from - the hassle of setting up boilerplate code. It is useful for getting the whole dialogs list with a single call. + This convenience method does the same as repeatedly calling :meth:`~Client.get_dialogs` in a loop, thus saving + you from the hassle of setting up boilerplate code. It is useful for getting the whole dialogs list with a + single call. Parameters: offset_date (``int``): diff --git a/pyrogram/client/methods/chats/set_chat_photo.py b/pyrogram/client/methods/chats/set_chat_photo.py index 79cceb7e..2baa29fe 100644 --- a/pyrogram/client/methods/chats/set_chat_photo.py +++ b/pyrogram/client/methods/chats/set_chat_photo.py @@ -44,7 +44,7 @@ class SetChatPhoto(BaseClient): Unique identifier (int) or username (str) of the target chat. photo (``str``): - New chat photo. You can pass a :class:`Photo` id or a file path to upload a new photo. + New chat photo. You can pass a :obj:`Photo` id or a file path to upload a new photo. Returns: ``bool``: True on success. diff --git a/pyrogram/client/methods/chats/update_chat_username.py b/pyrogram/client/methods/chats/update_chat_username.py index de5015ea..d06cda61 100644 --- a/pyrogram/client/methods/chats/update_chat_username.py +++ b/pyrogram/client/methods/chats/update_chat_username.py @@ -30,7 +30,7 @@ class UpdateChatUsername(BaseClient): ) -> bool: """Update a channel or a supergroup username. - To update your own username (for users only, not bots) you can use :meth:`update_username`. + To update your own username (for users only, not bots) you can use :meth:`~Client.update_username`. Parameters: chat_id (``int`` | ``str``) diff --git a/pyrogram/client/methods/decorators/on_callback_query.py b/pyrogram/client/methods/decorators/on_callback_query.py index b76655fb..5057f59f 100644 --- a/pyrogram/client/methods/decorators/on_callback_query.py +++ b/pyrogram/client/methods/decorators/on_callback_query.py @@ -32,7 +32,7 @@ class OnCallbackQuery(BaseClient): ) -> callable: """Decorator for handling callback queries. - This does the same thing as :meth:`add_handler` using the :class:`CallbackQueryHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`CallbackQueryHandler`. Parameters: filters (:obj:`Filters`): diff --git a/pyrogram/client/methods/decorators/on_deleted_messages.py b/pyrogram/client/methods/decorators/on_deleted_messages.py index 7637e6eb..53457b55 100644 --- a/pyrogram/client/methods/decorators/on_deleted_messages.py +++ b/pyrogram/client/methods/decorators/on_deleted_messages.py @@ -32,7 +32,7 @@ class OnDeletedMessages(BaseClient): ) -> callable: """Decorator for handling deleted messages. - This does the same thing as :meth:`add_handler` using the :class:`DeletedMessagesHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`DeletedMessagesHandler`. Parameters: filters (:obj:`Filters`): diff --git a/pyrogram/client/methods/decorators/on_disconnect.py b/pyrogram/client/methods/decorators/on_disconnect.py index 9305808e..b195ac54 100644 --- a/pyrogram/client/methods/decorators/on_disconnect.py +++ b/pyrogram/client/methods/decorators/on_disconnect.py @@ -25,7 +25,7 @@ class OnDisconnect(BaseClient): def on_disconnect(self=None) -> callable: """Decorator for handling disconnections. - This does the same thing as :meth:`add_handler` using the :class:`DisconnectHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`DisconnectHandler`. """ def decorator(func: callable) -> Handler: diff --git a/pyrogram/client/methods/decorators/on_inline_query.py b/pyrogram/client/methods/decorators/on_inline_query.py index 58837398..ee7175eb 100644 --- a/pyrogram/client/methods/decorators/on_inline_query.py +++ b/pyrogram/client/methods/decorators/on_inline_query.py @@ -32,7 +32,7 @@ class OnInlineQuery(BaseClient): ) -> callable: """Decorator for handling inline queries. - This does the same thing as :meth:`add_handler` using the :class:`InlineQueryHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`InlineQueryHandler`. Parameters: filters (:obj:`Filters `): diff --git a/pyrogram/client/methods/decorators/on_message.py b/pyrogram/client/methods/decorators/on_message.py index f590fd12..0f5c836c 100644 --- a/pyrogram/client/methods/decorators/on_message.py +++ b/pyrogram/client/methods/decorators/on_message.py @@ -32,7 +32,7 @@ class OnMessage(BaseClient): ) -> callable: """Decorator for handling messages. - This does the same thing as :meth:`add_handler` using the :class:`MessageHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`MessageHandler`. Parameters: filters (:obj:`Filters`): diff --git a/pyrogram/client/methods/decorators/on_poll.py b/pyrogram/client/methods/decorators/on_poll.py index de1c1d3d..7442858d 100644 --- a/pyrogram/client/methods/decorators/on_poll.py +++ b/pyrogram/client/methods/decorators/on_poll.py @@ -32,10 +32,10 @@ class OnPoll(BaseClient): ) -> callable: """Decorator for handling poll updates. - This does the same thing as :meth:`add_handler` using the :class:`PollHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`PollHandler`. Parameters: - filters (:obj:`Filters `): + filters (:obj:`Filters`): Pass one or more filters to allow only a subset of polls to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_raw_update.py b/pyrogram/client/methods/decorators/on_raw_update.py index 53a0f4cf..e03402ca 100644 --- a/pyrogram/client/methods/decorators/on_raw_update.py +++ b/pyrogram/client/methods/decorators/on_raw_update.py @@ -30,7 +30,7 @@ class OnRawUpdate(BaseClient): ) -> callable: """Decorator for handling raw updates. - This does the same thing as :meth:`add_handler` using the :class:`RawUpdateHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`RawUpdateHandler`. Parameters: group (``int``, *optional*): diff --git a/pyrogram/client/methods/decorators/on_user_status.py b/pyrogram/client/methods/decorators/on_user_status.py index e7db7b74..bcdcf024 100644 --- a/pyrogram/client/methods/decorators/on_user_status.py +++ b/pyrogram/client/methods/decorators/on_user_status.py @@ -31,7 +31,7 @@ class OnUserStatus(BaseClient): group: int = 0 ) -> callable: """Decorator for handling user status updates. - This does the same thing as :meth:`add_handler` using the :class:`UserStatusHandler`. + This does the same thing as :meth:`~Client.add_handler` using the :obj:`UserStatusHandler`. Parameters: filters (:obj:`Filters`): diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index bba5afd5..88c9c2d9 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -77,7 +77,7 @@ class DownloadMedia(BaseClient): Returns: ``str`` | ``None``: On success, the absolute path of the downloaded file is returned, otherwise, in case - the download failed or was deliberately stopped with :meth:`stop_transmission`, None is returned. + the download failed or was deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/get_history.py b/pyrogram/client/methods/messages/get_history.py index 3933e729..c0810474 100644 --- a/pyrogram/client/methods/messages/get_history.py +++ b/pyrogram/client/methods/messages/get_history.py @@ -41,7 +41,7 @@ class GetHistory(BaseClient): """Retrieve a chunk of the history of a chat. You can get up to 100 messages at once. - For a more convenient way of getting a chat history see :meth:`iter_history`. + For a more convenient way of getting a chat history see :meth:`~Client.iter_history`. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/iter_history.py b/pyrogram/client/methods/messages/iter_history.py index 218dd7f5..57da3da5 100644 --- a/pyrogram/client/methods/messages/iter_history.py +++ b/pyrogram/client/methods/messages/iter_history.py @@ -34,8 +34,9 @@ class IterHistory(BaseClient): ) -> Generator["pyrogram.Message", None, None]: """Iterate through a chat history sequentially. - This convenience method does the same as repeatedly calling :meth:`get_history` in a loop, thus saving you from - the hassle of setting up boilerplate code. It is useful for getting the whole chat history with a single call. + This convenience method does the same as repeatedly calling :meth:`~Client.get_history` in a loop, thus saving + you from the hassle of setting up boilerplate code. It is useful for getting the whole chat history with a + single call. Parameters: chat_id (``int`` | ``str``): diff --git a/pyrogram/client/methods/messages/send_animation.py b/pyrogram/client/methods/messages/send_animation.py index 458e3b5f..8a4ec7bd 100644 --- a/pyrogram/client/methods/messages/send_animation.py +++ b/pyrogram/client/methods/messages/send_animation.py @@ -119,7 +119,7 @@ class SendAnimation(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent animation message is returned, otherwise, in case the upload - is deliberately stopped with :meth:`stop_transmission`, None is returned. + is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_audio.py b/pyrogram/client/methods/messages/send_audio.py index 1c8f7ec5..7b218a66 100644 --- a/pyrogram/client/methods/messages/send_audio.py +++ b/pyrogram/client/methods/messages/send_audio.py @@ -121,7 +121,7 @@ class SendAudio(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent audio message is returned, otherwise, in case the upload - is deliberately stopped with :meth:`stop_transmission`, None is returned. + is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_document.py b/pyrogram/client/methods/messages/send_document.py index ff523303..da012b2c 100644 --- a/pyrogram/client/methods/messages/send_document.py +++ b/pyrogram/client/methods/messages/send_document.py @@ -107,7 +107,7 @@ class SendDocument(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent document message is returned, otherwise, in case the upload - is deliberately stopped with :meth:`stop_transmission`, None is returned. + is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_photo.py b/pyrogram/client/methods/messages/send_photo.py index 5e7cb35d..c1fd33d8 100644 --- a/pyrogram/client/methods/messages/send_photo.py +++ b/pyrogram/client/methods/messages/send_photo.py @@ -106,7 +106,7 @@ class SendPhoto(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent photo message is returned, otherwise, in case the upload - is deliberately stopped with :meth:`stop_transmission`, None is returned. + is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_sticker.py b/pyrogram/client/methods/messages/send_sticker.py index 6a3d2b4b..4f7a99ff 100644 --- a/pyrogram/client/methods/messages/send_sticker.py +++ b/pyrogram/client/methods/messages/send_sticker.py @@ -91,7 +91,7 @@ class SendSticker(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent sticker message is returned, otherwise, in case the upload - is deliberately stopped with :meth:`stop_transmission`, None is returned. + is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. """ diff --git a/pyrogram/client/methods/messages/send_video.py b/pyrogram/client/methods/messages/send_video.py index dc9229e8..4e1201fc 100644 --- a/pyrogram/client/methods/messages/send_video.py +++ b/pyrogram/client/methods/messages/send_video.py @@ -123,7 +123,7 @@ class SendVideo(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent video message is returned, otherwise, in case the upload - is deliberately stopped with :meth:`stop_transmission`, None is returned. + is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_video_note.py b/pyrogram/client/methods/messages/send_video_note.py index 9372dd9a..7bb8803b 100644 --- a/pyrogram/client/methods/messages/send_video_note.py +++ b/pyrogram/client/methods/messages/send_video_note.py @@ -106,7 +106,7 @@ class SendVideoNote(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent video note message is returned, otherwise, in case the - pload is deliberately stopped with :meth:`stop_transmission`, None is returned. + pload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/messages/send_voice.py b/pyrogram/client/methods/messages/send_voice.py index 759a5421..9dace1e0 100644 --- a/pyrogram/client/methods/messages/send_voice.py +++ b/pyrogram/client/methods/messages/send_voice.py @@ -104,7 +104,7 @@ class SendVoice(BaseClient): Returns: :obj:`Message` | ``None``: On success, the sent voice message is returned, otherwise, in case the upload - is deliberately stopped with :meth:`stop_transmission`, None is returned. + is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/methods/users/update_username.py b/pyrogram/client/methods/users/update_username.py index 65b86174..002dbf75 100644 --- a/pyrogram/client/methods/users/update_username.py +++ b/pyrogram/client/methods/users/update_username.py @@ -31,7 +31,7 @@ class UpdateUsername(BaseClient): This method only works for users, not bots. Bot usernames must be changed via Bot Support or by recreating them from scratch using BotFather. To update a channel or supergroup username you can use - :meth:`update_chat_username`. + :meth:`~Client.update_chat_username`. Parameters: username (``str`` | ``None``): diff --git a/pyrogram/client/types/inline_mode/inline_query.py b/pyrogram/client/types/inline_mode/inline_query.py index 4d1c9a16..1985a0c0 100644 --- a/pyrogram/client/types/inline_mode/inline_query.py +++ b/pyrogram/client/types/inline_mode/inline_query.py @@ -92,7 +92,7 @@ class InlineQuery(PyrogramType, Update): switch_pm_text: str = "", switch_pm_parameter: str = "" ): - """Bound method *answer* of :obj:`InlineQuery `. + """Bound method *answer* of :obj:`InlineQuery`. Use this method as a shortcut for: @@ -109,7 +109,7 @@ class InlineQuery(PyrogramType, Update): inline_query.answer([...]) Parameters: - results (List of :obj:`InlineQueryResult `): + results (List of :obj:`InlineQueryResult`): A list of results for the inline query. cache_time (``int``, *optional*): 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 8543eb4c..ad0be9e4 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result_article.py +++ b/pyrogram/client/types/inline_mode/inline_query_result_article.py @@ -34,10 +34,10 @@ class InlineQueryResultArticle(InlineQueryResult): title (``str``): Title for the result. - input_message_content (:obj:`InputMessageContent `): + input_message_content (:obj:`InputMessageContent`): Content of the message to be sent. - reply_markup (:obj:`InlineKeyboardMarkup `, *optional*): + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): Inline keyboard attached to the message. url (``str``, *optional*): diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py index 0ef30b20..6ca0478a 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py @@ -50,10 +50,10 @@ class InlineQueryResultAudio(PyrogramType): audio_duration (``int`` ``32-bit``, optional): Audio duration in seconds. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the audio. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py index e2873638..ad6cb9af 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py @@ -47,10 +47,10 @@ class InlineQueryResultCachedDocument(PyrogramType): parse_mode (``str``, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the file. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py index 8b523dbd..1c836f20 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py @@ -44,10 +44,10 @@ class InlineQueryResultCachedGif(PyrogramType): parse_mode (``str``, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the GIF animation. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py index 06944deb..4711cd72 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py @@ -35,10 +35,10 @@ class InlineQueryResultCachedSticker(PyrogramType): sticker_file_id (``str``): A valid file identifier of the sticker. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the sticker. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py index 3f8bb6a3..3091cf65 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py @@ -44,10 +44,10 @@ class InlineQueryResultCachedVoice(PyrogramType): parse_mode (``str``, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the voice message. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py index 148ec01d..a95dd2e9 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py @@ -50,10 +50,10 @@ class InlineQueryResultDocument(PyrogramType): description (``str``, optional): Short description of the result. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the file. thumb_url (``str``, optional): diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py index faebacea..98654463 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py @@ -35,7 +35,7 @@ class InlineQueryResultGame(PyrogramType): game_short_name (``str``): Short name of the game. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py index 3412b3f4..db6b9090 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py @@ -54,10 +54,10 @@ class InlineQueryResultPhoto(PyrogramType): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. - reply_markup (:obj:`InlineKeyboardMarkup `, *optional*): + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, *optional*): + input_message_content (:obj:`InputMessageContent`, *optional*): Content of the message to be sent instead of the photo. """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py index 1dee9509..51ee8ae7 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py @@ -50,10 +50,10 @@ class InlineQueryResultVenue(PyrogramType): foursquare_type (``str``, optional): Foursquare type of the venue, if known. (For example, "arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".). - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the venue. thumb_url (``str``, optional): diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py index 22d810e1..c8e27f79 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py @@ -62,10 +62,10 @@ class InlineQueryResultVideo(PyrogramType): description (``str``, optional): Short description of the result. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the video. This field is required if InlineQueryResultVideo is used to send an HTML-page as a result (e.g., a YouTube video). """ diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py index 73d7fb1d..23cc741f 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py @@ -47,10 +47,10 @@ class InlineQueryResultVoice(PyrogramType): voice_duration (``int`` ``32-bit``, optional): Recording duration in seconds. - reply_markup (:obj:`InlineKeyboardMarkup `, optional): + reply_markup (:obj:`InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. - input_message_content (:obj:`InputMessageContent `, optional): + input_message_content (:obj:`InputMessageContent`, optional): Content of the message to be sent instead of the voice recording. """ diff --git a/pyrogram/client/types/input_media/input_phone_contact.py b/pyrogram/client/types/input_media/input_phone_contact.py index 0b6353b7..c1627516 100644 --- a/pyrogram/client/types/input_media/input_phone_contact.py +++ b/pyrogram/client/types/input_media/input_phone_contact.py @@ -23,7 +23,7 @@ from ..pyrogram_type import PyrogramType class InputPhoneContact(PyrogramType): """A Phone Contact to be added in your Telegram address book. - It is intended to be used with :meth:`add_contacts() ` + It is intended to be used with :meth:`~Client.add_contacts() ` Parameters: phone (``str``): diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index f8d161c2..c3a12f3e 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -834,7 +834,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -968,7 +968,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -1294,7 +1294,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -1686,7 +1686,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -1864,7 +1864,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -2094,7 +2094,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -2216,7 +2216,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -2332,7 +2332,7 @@ class Message(PyrogramType, Update): Returns: On success, the sent :obj:`Message` is returned. - In case the upload is deliberately stopped with :meth:`stop_transmission`, None is returned instead. + In case the upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned instead. Raises: RPCError: In case of a Telegram RPC error. @@ -2778,9 +2778,8 @@ class Message(PyrogramType, Update): Timeout in seconds. Returns: - - The result of :meth:`request_callback_answer() ` in case of - inline callback button clicks. - - The result of :meth:`reply() ` in case of normal button clicks. + - The result of :meth:`~Client.request_callback_answer` in case of inline callback button clicks. + - The result of :meth:`~Message.reply()` in case of normal button clicks. - A string in case the inline button is a URL, a *switch_inline_query* or a *switch_inline_query_current_chat* button. diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py index 379830be..f94f1951 100644 --- a/pyrogram/client/types/messages_and_media/messages.py +++ b/pyrogram/client/types/messages_and_media/messages.py @@ -146,7 +146,7 @@ class Messages(PyrogramType, Update): Defaults to False. Returns: - On success, a :class:`Messages` containing forwarded messages is returned. + On success, a :obj:`Messages` containing forwarded messages is returned. Raises: RPCError: In case of a Telegram RPC error. diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 10cc10a7..e260d8cd 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -57,28 +57,28 @@ class Chat(PyrogramType): last_name (``str``, *optional*): Last name of the other party in a private chat, for private chats. - photo (:obj:`ChatPhoto `, *optional*): + photo (:obj:`ChatPhoto`, *optional*): Chat photo. Suitable for downloads only. description (``str``, *optional*): Bio, for private chats and bots or description for groups, supergroups and channels. - Returned only in :meth:`get_chat() `. + Returned only in :meth:`~Client.get_chat`. invite_link (``str``, *optional*): Chat invite link, for groups, supergroups and channels. - Returned only in :meth:`get_chat() `. + Returned only in :meth:`~Client.get_chat`. pinned_message (:obj:`Message`, *optional*): Pinned message, for groups, supergroups channels and own chat. - Returned only in :meth:`get_chat() `. + Returned only in :meth:`~Client.get_chat`. sticker_set_name (``str``, *optional*): For supergroups, name of group sticker set. - Returned only in :meth:`get_chat() `. + Returned only in :meth:`~Client.get_chat`. can_set_sticker_set (``bool``, *optional*): True, if the group sticker set can be changed by you. - Returned only in :meth:`get_chat() `. + Returned only in :meth:`~Client.get_chat`. members_count (``int``, *optional*): Chat members count, for groups, supergroups and channels only. @@ -87,7 +87,7 @@ class Chat(PyrogramType): The reason why this chat might be unavailable to some users. This field is available only in case *is_restricted* is True. - permissions (:obj:`ChatPermissions ` *optional*): + permissions (:obj:`ChatPermissions` *optional*): Information about the chat default permissions, for groups and supergroups. """ From 4ca87682af04206b53a6067ee152821234e85148 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 31 May 2019 00:16:31 +0200 Subject: [PATCH 110/202] Fix Document.date attribute being a tuple Thanks Python... --- pyrogram/client/types/messages_and_media/document.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index 654516e8..a8838531 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -68,7 +68,7 @@ class Document(PyrogramType): self.file_name = file_name self.mime_type = mime_type self.file_size = file_size - self.date = date, + self.date = date self.thumbnails = thumbnails @staticmethod From cb3addab1e60256fa6fa49093e5c9e78f9da629a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 31 May 2019 00:18:43 +0200 Subject: [PATCH 111/202] Add iter_profile_photos method --- .../methods/users/iter_profile_photos.py | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 pyrogram/client/methods/users/iter_profile_photos.py diff --git a/pyrogram/client/methods/users/iter_profile_photos.py b/pyrogram/client/methods/users/iter_profile_photos.py new file mode 100644 index 00000000..1773634e --- /dev/null +++ b/pyrogram/client/methods/users/iter_profile_photos.py @@ -0,0 +1,79 @@ +# 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 typing import Union, Generator + +import pyrogram +from ...ext import BaseClient + + +class IterProfilePhotos(BaseClient): + def iter_profile_photos( + self, + chat_id: Union[int, str], + offset: int = 0, + limit: int = 0, + ) -> Generator["pyrogram.Photo", None, None]: + """Iterate through a chat or a user profile photos sequentially. + + This convenience method does the same as repeatedly calling :meth:`~Client.get_profile_photos` in a loop, thus + saving you from the hassle of setting up boilerplate code. It is useful for getting all the profile photos with + a single call. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For your personal cloud (Saved Messages) you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + limit (``int``, *optional*): + Limits the number of profile photos to be retrieved. + By default, no limit is applied and all profile photos are returned. + + offset (``int``, *optional*): + Sequential number of the first profile photo to be returned. + + Returns: + ``Generator``: A generator yielding :obj:`Photo` objects. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + current = 0 + total = limit or (1 << 31) + limit = min(100, total) + + while True: + photos = self.get_profile_photos( + chat_id=chat_id, + offset=offset, + limit=limit + ).photos + + if not photos: + return + + offset += len(photos) + + for photo in photos: + yield photo + + current += 1 + + if current >= total: + return From 06ad65e3a035f9bb0a721cc79086bdedd380cc90 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 31 May 2019 00:19:18 +0200 Subject: [PATCH 112/202] Improve codegen scripts --- compiler/api/compiler.py | 4 ++-- compiler/docs/compiler.py | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 64e88c9d..6566bc8e 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -67,7 +67,7 @@ def get_docstring_arg_type(t: str, is_list: bool = False, is_pyrogram_type: bool n = len(t) - 1 t = (("e" if is_list else "E") + "ither " if n else "") + ", ".join( - ":obj:`{1} <{0}.{1}>`".format( + ":obj:`~{}.{}`".format( "pyrogram.types" if is_pyrogram_type else "pyrogram.api.types", i.replace("pyrogram.", "") ) @@ -88,7 +88,7 @@ def get_references(t: str): n = len(t) - 1 t = ", ".join( - ":obj:`{0} `".format(i) + ":obj:`~pyrogram.api.functions.{}`".format(i) for i in t ) diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 2c67e66c..b167fa57 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -18,6 +18,7 @@ import ast import os +import re import shutil HOME = "compiler/docs" @@ -29,8 +30,10 @@ TYPES_PATH = "pyrogram/api/types" FUNCTIONS_BASE = "functions" TYPES_BASE = "types" -shutil.rmtree(TYPES_BASE, ignore_errors=True) -shutil.rmtree(FUNCTIONS_BASE, ignore_errors=True) + +def snek(s: str): + s = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", s) + return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s).lower() def generate(source_path, base): @@ -50,9 +53,11 @@ def generate(source_path, base): for node in ast.walk(p): if isinstance(node, ast.ClassDef): name = node.name + break + else: + continue - # name = "".join([str(j.title()) for j in os.path.splitext(i)[0].split("_")]) - full_path = os.path.basename(path) + "/" + name + ".rst" + full_path = os.path.basename(path) + "/" + snek(name).replace("_", "-") + ".rst" if level: full_path = base + "/" + full_path @@ -65,7 +70,7 @@ def generate(source_path, base): title=name, title_markup="=" * len(name), full_class_path="pyrogram.api.{}".format( - os.path.splitext(full_path)[0].replace("/", ".") + ".".join(full_path.split("/")[:-1]) + "." + name ) ) ) @@ -82,7 +87,7 @@ def generate(source_path, base): entities = [] for i in v: - entities.append(i) + entities.append(snek(i).replace("_", "-")) if k != base: inner_path = base + "/" + k + "/index" + ".rst" @@ -98,6 +103,7 @@ def generate(source_path, base): with open(DESTINATION + "/" + inner_path, "w", encoding="utf-8") as f: if k == base: f.write(":tocdepth: 1\n\n") + k = "Raw " + k f.write( toctree.format( @@ -115,6 +121,8 @@ def start(): global page_template global toctree + shutil.rmtree(DESTINATION, ignore_errors=True) + with open(HOME + "/template/page.txt", encoding="utf-8") as f: page_template = f.read() From a98455886036c61899665e6033d87b98c72882c4 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 31 May 2019 00:20:09 +0200 Subject: [PATCH 113/202] Rename methods dealing with profile pictures --- docs/source/api/methods.rst | 18 +++--- pyrogram/client/ext/base_client.py | 3 + pyrogram/client/methods/users/__init__.py | 20 ++++--- ...ete_photos.py => delete_profile_photos.py} | 4 +- ...t_user_photos.py => get_profile_photos.py} | 57 ++++++++++++++----- ...s_count.py => get_profile_photos_count.py} | 21 ++----- .../{set_photo.py => set_profile_photo.py} | 4 +- 7 files changed, 74 insertions(+), 53 deletions(-) rename pyrogram/client/methods/users/{delete_photos.py => delete_profile_photos.py} (96%) rename pyrogram/client/methods/users/{get_user_photos.py => get_profile_photos.py} (55%) rename pyrogram/client/methods/users/{get_user_photos_count.py => get_profile_photos_count.py} (72%) rename pyrogram/client/methods/users/{set_photo.py => set_profile_photo.py} (96%) diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index 760c332b..2d3d8f23 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -111,10 +111,11 @@ Users - :meth:`~Client.get_me` - :meth:`~Client.get_users` - - :meth:`~Client.get_user_photos` - - :meth:`~Client.get_user_photos_count` - - :meth:`~Client.set_photo` - - :meth:`~Client.delete_photos` + - :meth:`~Client.get_profile_photos` + - :meth:`~Client.get_profile_photos_count` + - :meth:`~Client.iter_profile_photos` + - :meth:`~Client.set_profile_photo` + - :meth:`~Client.delete_profile_photos` - :meth:`~Client.update_username` - :meth:`~Client.get_user_dc` @@ -232,10 +233,11 @@ Details .. Users .. automethod:: Client.get_me() .. automethod:: Client.get_users() -.. automethod:: Client.get_user_photos() -.. automethod:: Client.get_user_photos_count() -.. automethod:: Client.set_photo() -.. automethod:: Client.delete_photos() +.. automethod:: Client.get_profile_photos() +.. automethod:: Client.get_profile_photos_count() +.. automethod:: Client.iter_profile_photos() +.. automethod:: Client.set_profile_photo() +.. automethod:: Client.delete_profile_photos() .. automethod:: Client.update_username() .. automethod:: Client.get_user_dc() diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index 3397c8d3..b193ceee 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -159,3 +159,6 @@ class BaseClient: def guess_extension(self, *args, **kwargs): pass + + def get_profile_photos(self, *args, **kwargs): + pass diff --git a/pyrogram/client/methods/users/__init__.py b/pyrogram/client/methods/users/__init__.py index bbc2df23..20b50ce9 100644 --- a/pyrogram/client/methods/users/__init__.py +++ b/pyrogram/client/methods/users/__init__.py @@ -16,24 +16,26 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .delete_photos import DeletePhotos +from .delete_profile_photos import DeleteProfilePhotos from .get_me import GetMe +from .get_profile_photos import GetProfilePhotos +from .get_profile_photos_count import GetProfilePhotosCount from .get_user_dc import GetUserDC -from .get_user_photos import GetUserPhotos -from .get_user_photos_count import GetUserPhotosCount from .get_users import GetUsers -from .set_photo import SetPhoto +from .iter_profile_photos import IterProfilePhotos +from .set_profile_photo import SetProfilePhoto from .update_username import UpdateUsername class Users( - GetUserPhotos, - SetPhoto, - DeletePhotos, + GetProfilePhotos, + SetProfilePhoto, + DeleteProfilePhotos, GetUsers, GetMe, UpdateUsername, - GetUserPhotosCount, - GetUserDC + GetProfilePhotosCount, + GetUserDC, + IterProfilePhotos ): pass diff --git a/pyrogram/client/methods/users/delete_photos.py b/pyrogram/client/methods/users/delete_profile_photos.py similarity index 96% rename from pyrogram/client/methods/users/delete_photos.py rename to pyrogram/client/methods/users/delete_profile_photos.py index 30b3b533..1b46382c 100644 --- a/pyrogram/client/methods/users/delete_photos.py +++ b/pyrogram/client/methods/users/delete_profile_photos.py @@ -24,8 +24,8 @@ from pyrogram.api import functions, types from ...ext import BaseClient -class DeletePhotos(BaseClient): - def delete_photos( +class DeleteProfilePhotos(BaseClient): + def delete_profile_photos( self, id: Union[str, List[str]] ) -> bool: diff --git a/pyrogram/client/methods/users/get_user_photos.py b/pyrogram/client/methods/users/get_profile_photos.py similarity index 55% rename from pyrogram/client/methods/users/get_user_photos.py rename to pyrogram/client/methods/users/get_profile_photos.py index e134a502..d45bd5b6 100644 --- a/pyrogram/client/methods/users/get_user_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -19,21 +19,21 @@ from typing import Union import pyrogram -from pyrogram.api import functions +from pyrogram.api import functions, types from ...ext import BaseClient -class GetUserPhotos(BaseClient): - def get_user_photos( +class GetProfilePhotos(BaseClient): + def get_profile_photos( self, - user_id: Union[int, str], + chat_id: Union[int, str], offset: int = 0, limit: int = 100 ) -> "pyrogram.Photos": - """Get a list of profile pictures for a user. + """Get a list of profile pictures for a user or a chat. Parameters: - user_id (``int`` | ``str``): + chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). @@ -52,14 +52,41 @@ class GetUserPhotos(BaseClient): Raises: RPCError: In case of a Telegram RPC error. """ - return pyrogram.Photos._parse( - self, - self.send( - functions.photos.GetUserPhotos( - user_id=self.resolve_peer(user_id), - offset=offset, - max_id=0, - limit=limit + peer_id = self.resolve_peer(chat_id) + + if isinstance(peer_id, types.InputPeerUser): + return pyrogram.Photos._parse( + self, + self.send( + functions.photos.GetUserPhotos( + user_id=peer_id, + offset=offset, + max_id=0, + limit=limit + ) ) ) - ) + else: + new_chat_photos = pyrogram.Messages._parse( + self, + self.send( + functions.messages.Search( + peer=peer_id, + q="", + filter=types.InputMessagesFilterChatPhotos(), + min_date=0, + max_date=0, + offset_id=0, + add_offset=offset, + limit=limit, + max_id=0, + min_id=0, + hash=0 + ) + ) + ) + + return pyrogram.Photos( + total_count=new_chat_photos.total_count, + photos=[m.new_chat_photo for m in new_chat_photos.messages][:limit] + ) diff --git a/pyrogram/client/methods/users/get_user_photos_count.py b/pyrogram/client/methods/users/get_profile_photos_count.py similarity index 72% rename from pyrogram/client/methods/users/get_user_photos_count.py rename to pyrogram/client/methods/users/get_profile_photos_count.py index 3bbaf55b..a65e0ada 100644 --- a/pyrogram/client/methods/users/get_user_photos_count.py +++ b/pyrogram/client/methods/users/get_profile_photos_count.py @@ -18,16 +18,15 @@ from typing import Union -from pyrogram.api import functions, types from ...ext import BaseClient -class GetUserPhotosCount(BaseClient): - def get_user_photos_count(self, user_id: Union[int, str]) -> int: +class GetProfilePhotosCount(BaseClient): + def get_profile_photos_count(self, chat_id: Union[int, str]) -> int: """Get the total count of profile pictures for a user. Parameters: - user_id (``int`` | ``str``): + chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). @@ -39,16 +38,4 @@ class GetUserPhotosCount(BaseClient): RPCError: In case of a Telegram RPC error. """ - r = self.send( - functions.photos.GetUserPhotos( - user_id=self.resolve_peer(user_id), - offset=0, - max_id=0, - limit=1 - ) - ) - - if isinstance(r, types.photos.Photos): - return len(r.photos) - else: - return r.count + return self.get_profile_photos(chat_id, limit=1).total_count diff --git a/pyrogram/client/methods/users/set_photo.py b/pyrogram/client/methods/users/set_profile_photo.py similarity index 96% rename from pyrogram/client/methods/users/set_photo.py rename to pyrogram/client/methods/users/set_profile_photo.py index cd7f955d..a713fd34 100644 --- a/pyrogram/client/methods/users/set_photo.py +++ b/pyrogram/client/methods/users/set_profile_photo.py @@ -20,8 +20,8 @@ from pyrogram.api import functions from ...ext import BaseClient -class SetPhoto(BaseClient): - def set_photo( +class SetProfilePhoto(BaseClient): + def set_profile_photo( self, photo: str ) -> bool: From 364d3ec1450af42fc4148b53a90d50b1d39b482b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 31 May 2019 01:09:03 +0200 Subject: [PATCH 114/202] Revert: Improve codegen scripts --- compiler/api/compiler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 6566bc8e..64e88c9d 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -67,7 +67,7 @@ def get_docstring_arg_type(t: str, is_list: bool = False, is_pyrogram_type: bool n = len(t) - 1 t = (("e" if is_list else "E") + "ither " if n else "") + ", ".join( - ":obj:`~{}.{}`".format( + ":obj:`{1} <{0}.{1}>`".format( "pyrogram.types" if is_pyrogram_type else "pyrogram.api.types", i.replace("pyrogram.", "") ) @@ -88,7 +88,7 @@ def get_references(t: str): n = len(t) - 1 t = ", ".join( - ":obj:`~pyrogram.api.functions.{}`".format(i) + ":obj:`{0} `".format(i) for i in t ) From 2df9f53e5435a871219273866e4050f9639101de Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 31 May 2019 13:18:19 +0200 Subject: [PATCH 115/202] Add a FAQ about expiring sms codes --- docs/source/faq.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 7d7e9032..33e7282f 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -155,6 +155,15 @@ things: 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)``. +My verification code expires immediately! +----------------------------------------- + +That is because you likely shared it across any of your Telegram chats. Yes, that's right: the server keeps scanning the +messages you send and if an active verification code is found it will immediately expire, automatically. + +The reason behind this is to protect unaware users from giving their account access to any potential scammer, but if you +legitimately want to share your account(s) verification codes, consider scrambling them, e.g. ``12345`` → ``1-2-3-4-5``. + My account has been deactivated/limited! ---------------------------------------- From 48a5da8958f55763f7cd07bb5c7f38e112ac9f9d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 31 May 2019 16:36:20 +0200 Subject: [PATCH 116/202] Let FutureSalt(s) attributes be plain integer instead of datetime values --- pyrogram/api/core/future_salt.py | 7 +++---- pyrogram/api/core/future_salts.py | 5 ++--- pyrogram/session/session.py | 3 ++- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pyrogram/api/core/future_salt.py b/pyrogram/api/core/future_salt.py index 4ee8197b..c4ccea3d 100644 --- a/pyrogram/api/core/future_salt.py +++ b/pyrogram/api/core/future_salt.py @@ -16,7 +16,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from datetime import datetime from io import BytesIO from .object import Object @@ -30,15 +29,15 @@ class FutureSalt(Object): QUALNAME = "FutureSalt" - def __init__(self, valid_since: int or datetime, valid_until: int or datetime, salt: int): + def __init__(self, valid_since: int, valid_until: int, salt: int): self.valid_since = valid_since self.valid_until = valid_until self.salt = salt @staticmethod def read(b: BytesIO, *args) -> "FutureSalt": - valid_since = datetime.fromtimestamp(Int.read(b)) - valid_until = datetime.fromtimestamp(Int.read(b)) + valid_since = Int.read(b) + valid_until = Int.read(b) salt = Long.read(b) return FutureSalt(valid_since, valid_until, salt) diff --git a/pyrogram/api/core/future_salts.py b/pyrogram/api/core/future_salts.py index cf6a9902..91ee7b51 100644 --- a/pyrogram/api/core/future_salts.py +++ b/pyrogram/api/core/future_salts.py @@ -16,7 +16,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from datetime import datetime from io import BytesIO from . import FutureSalt @@ -31,7 +30,7 @@ class FutureSalts(Object): QUALNAME = "FutureSalts" - def __init__(self, req_msg_id: int, now: int or datetime, salts: list): + def __init__(self, req_msg_id: int, now: int, salts: list): self.req_msg_id = req_msg_id self.now = now self.salts = salts @@ -39,7 +38,7 @@ class FutureSalts(Object): @staticmethod def read(b: BytesIO, *args) -> "FutureSalts": req_msg_id = Long.read(b) - now = datetime.fromtimestamp(Int.read(b)) + now = Int.read(b) count = Int.read(b) salts = [FutureSalt.read(b) for _ in range(count)] diff --git a/pyrogram/session/session.py b/pyrogram/session/session.py index 66207037..e4260be4 100644 --- a/pyrogram/session/session.py +++ b/pyrogram/session/session.py @@ -350,7 +350,8 @@ class Session: # Seconds to wait until middle-overlap, which is # 15 minutes before/after the current/next salt end/start time - dt = (self.current_salt.valid_until - now).total_seconds() - 900 + valid_until = datetime.fromtimestamp(self.current_salt.valid_until) + dt = (valid_until - now).total_seconds() - 900 log.debug("Current salt: {} | Next salt in {:.0f}m {:.0f}s ({})".format( self.current_salt.salt, From 341c41e7efecc6f7bd6efc3b49ff7353a89ce927 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 13:10:06 +0200 Subject: [PATCH 117/202] Add MESSAGE_EDIT_TIME_EXPIRED error --- compiler/error/source/400_BAD_REQUEST.tsv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index cbea977a..fa6ff67e 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -98,4 +98,5 @@ RESULTS_TOO_MUCH The result contains too many items RESULT_ID_DUPLICATE The result contains items with duplicated identifiers ACCESS_TOKEN_INVALID The bot access token is invalid INVITE_HASH_EXPIRED The chat invite link is no longer valid -USER_BANNED_IN_CHANNEL You are limited, check @SpamBot for details \ No newline at end of file +USER_BANNED_IN_CHANNEL You are limited, check @SpamBot for details +MESSAGE_EDIT_TIME_EXPIRED You can no longer edit this message \ No newline at end of file From e7f6e9ec66901151e9cda6182b71179eb067acea Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 13:15:41 +0200 Subject: [PATCH 118/202] Cast is_bot value to bool --- pyrogram/client/ext/syncer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/ext/syncer.py b/pyrogram/client/ext/syncer.py index 71dc3f35..c3921205 100644 --- a/pyrogram/client/ext/syncer.py +++ b/pyrogram/client/ext/syncer.py @@ -94,7 +94,7 @@ class Syncer: auth_key=auth_key, user_id=client.user_id, date=int(time.time()), - is_bot=client.is_bot, + is_bot=bool(client.is_bot), peers_by_id={ k: getattr(v, "access_hash", None) for k, v in client.peers_by_id.copy().items() From f6361cd20fa714ebdaed2c894dc40c0811ffbbc8 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 13:17:04 +0200 Subject: [PATCH 119/202] Allow bare lists from the MTProto API to be printed nicely --- pyrogram/api/core/__init__.py | 1 + pyrogram/api/core/list.py | 26 ++++++++++++++ pyrogram/api/core/object.py | 47 +++++++++++++------------- pyrogram/api/core/primitives/vector.py | 5 +-- 4 files changed, 53 insertions(+), 26 deletions(-) create mode 100644 pyrogram/api/core/list.py diff --git a/pyrogram/api/core/__init__.py b/pyrogram/api/core/__init__.py index daba6b7c..bf596446 100644 --- a/pyrogram/api/core/__init__.py +++ b/pyrogram/api/core/__init__.py @@ -19,6 +19,7 @@ from .future_salt import FutureSalt from .future_salts import FutureSalts from .gzip_packed import GzipPacked +from .list import List from .message import Message from .msg_container import MsgContainer from .object import Object diff --git a/pyrogram/api/core/list.py b/pyrogram/api/core/list.py new file mode 100644 index 00000000..1f55dc45 --- /dev/null +++ b/pyrogram/api/core/list.py @@ -0,0 +1,26 @@ +# 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 .object import Object + + +class List(list, Object): + __slots__ = [] + + def __repr__(self): + return "pyrogram.api.core.List([{}])".format(",".join(Object.__str__(i) for i in self)) diff --git a/pyrogram/api/core/object.py b/pyrogram/api/core/object.py index ace7a59a..9d1a4852 100644 --- a/pyrogram/api/core/object.py +++ b/pyrogram/api/core/object.py @@ -17,7 +17,6 @@ # along with Pyrogram. If not, see . from collections import OrderedDict -from datetime import datetime from io import BytesIO from json import dumps @@ -36,32 +35,22 @@ class Object: def write(self, *args) -> bytes: pass - def __eq__(self, other: "Object") -> bool: - for attr in self.__slots__: - try: - if getattr(self, attr) != getattr(other, attr): - return False - except AttributeError: - return False + @staticmethod + def default(obj: "Object"): + if isinstance(obj, bytes): + return repr(obj) - return True + return OrderedDict( + [("_", obj.QUALNAME)] + + [ + (attr, getattr(obj, attr)) + for attr in obj.__slots__ + if getattr(obj, attr) is not None + ] + ) def __str__(self) -> str: - def default(obj: Object): - try: - return OrderedDict( - [("_", obj.QUALNAME)] - + [(attr, getattr(obj, attr)) - for attr in obj.__slots__ - if getattr(obj, attr) is not None] - ) - except AttributeError: - if isinstance(obj, datetime): - return obj.strftime("%d-%b-%Y %H:%M:%S") - else: - return repr(obj) - - return dumps(self, indent=4, default=default, ensure_ascii=False) + return dumps(self, indent=4, default=Object.default, ensure_ascii=False) def __repr__(self) -> str: return "pyrogram.api.{}({})".format( @@ -73,6 +62,16 @@ class Object: ) ) + def __eq__(self, other: "Object") -> bool: + for attr in self.__slots__: + try: + if getattr(self, attr) != getattr(other, attr): + return False + except AttributeError: + return False + + return True + def __len__(self) -> int: return len(self.write()) diff --git a/pyrogram/api/core/primitives/vector.py b/pyrogram/api/core/primitives/vector.py index cd24ec35..720486f2 100644 --- a/pyrogram/api/core/primitives/vector.py +++ b/pyrogram/api/core/primitives/vector.py @@ -19,6 +19,7 @@ from io import BytesIO from . import Int +from ..list import List from ..object import Object @@ -37,11 +38,11 @@ class Vector(Object): @staticmethod def read(b: BytesIO, t: Object = None) -> list: - return [ + return List( t.read(b) if t else Vector._read(b) for _ in range(Int.read(b)) - ] + ) def __new__(cls, value: list, t: Object = None) -> bytes: return b"".join( From d243ebc2cdff4205334e5592d83abe80d4a1d277 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 13:18:48 +0200 Subject: [PATCH 120/202] Performance improvements --- pyrogram/client/client.py | 43 +++++++++++++----------------- pyrogram/client/ext/base_client.py | 1 - pyrogram/client/ext/dispatcher.py | 9 +++---- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index e93e3ff8..2ba6b8fa 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -765,7 +765,9 @@ class Client(Methods, BaseClient): types.Channel, types.ChannelForbidden ] ] - ): + ) -> bool: + is_min = False + for entity in entities: if isinstance(entity, types.User): user_id = entity.id @@ -773,6 +775,7 @@ class Client(Methods, BaseClient): access_hash = entity.access_hash if access_hash is None: + is_min = True continue username = entity.username @@ -808,6 +811,7 @@ class Client(Methods, BaseClient): access_hash = entity.access_hash if access_hash is None: + is_min = True continue username = getattr(entity, "username", None) @@ -822,6 +826,8 @@ class Client(Methods, BaseClient): if username is not None: self.peers_by_username[username.lower()] = input_peer + return is_min + def download_worker(self): name = threading.current_thread().name log.debug("{} started".format(name)) @@ -837,7 +843,6 @@ class Client(Methods, BaseClient): try: data, file_name, done, progress, progress_args, path = packet - data = data # type: BaseClient.FileData directory, file_name = os.path.split(file_name) directory = directory or "downloads" @@ -917,8 +922,10 @@ class Client(Methods, BaseClient): try: if isinstance(updates, (types.Update, types.UpdatesCombined)): - self.fetch_peers(updates.users) - self.fetch_peers(updates.chats) + is_min = self.fetch_peers(updates.users) or self.fetch_peers(updates.chats) + + users = {u.id: u for u in updates.users} + chats = {c.id: c for c in updates.chats} for update in updates.updates: channel_id = getattr( @@ -935,7 +942,7 @@ class Client(Methods, BaseClient): if isinstance(update, types.UpdateChannelTooLong): log.warning(update) - if isinstance(update, types.UpdateNewChannelMessage): + if isinstance(update, types.UpdateNewChannelMessage) and is_min: message = update.message if not isinstance(message, types.MessageEmpty): @@ -957,22 +964,10 @@ class Client(Methods, BaseClient): pass else: if not isinstance(diff, types.updates.ChannelDifferenceEmpty): - updates.users += diff.users - updates.chats += diff.chats + users.update({u.id: u for u in diff.users}) + chats.update({c.id: c for c in diff.chats}) - if channel_id and pts: - if channel_id not in self.channels_pts: - self.channels_pts[channel_id] = [] - - if pts in self.channels_pts[channel_id]: - continue - - self.channels_pts[channel_id].append(pts) - - if len(self.channels_pts[channel_id]) > 50: - self.channels_pts[channel_id] = self.channels_pts[channel_id][25:] - - self.dispatcher.updates_queue.put((update, updates.users, updates.chats)) + self.dispatcher.updates_queue.put((update, users, chats)) elif isinstance(updates, (types.UpdateShortMessage, types.UpdateShortChatMessage)): diff = self.send( functions.updates.GetDifference( @@ -989,13 +984,13 @@ class Client(Methods, BaseClient): pts=updates.pts, pts_count=updates.pts_count ), - diff.users, - diff.chats + {u.id: u for u in diff.users}, + {c.id: c for c in diff.chats} )) else: - self.dispatcher.updates_queue.put((diff.other_updates[0], [], [])) + self.dispatcher.updates_queue.put((diff.other_updates[0], {}, {})) elif isinstance(updates, types.UpdateShort): - self.dispatcher.updates_queue.put((updates.update, [], [])) + self.dispatcher.updates_queue.put((updates.update, {}, {})) elif isinstance(updates, types.UpdatesTooLong): log.warning(updates) except Exception as e: diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index b193ceee..9c0d661e 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -96,7 +96,6 @@ class BaseClient: self.date = None self.rnd_id = MsgId - self.channels_pts = {} self.peers_by_id = {} self.peers_by_username = {} diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 1004095b..2f1ec2b9 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -125,16 +125,13 @@ class Dispatcher: log.debug("{} started".format(name)) while True: - update = self.updates_queue.get() + packet = self.updates_queue.get() - if update is None: + if packet is None: break try: - users = {i.id: i for i in update[1]} - chats = {i.id: i for i in update[2]} - update = update[0] - + update, users, chats = packet parser = self.update_parsers.get(type(update), None) parsed_update, handler_type = ( From dc94da3895de3d9497c16bdfc706d11b57c19657 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 14:04:39 +0200 Subject: [PATCH 121/202] Add application/x-tgsticker mime type with .tgs as extension --- pyrogram/client/ext/mime.types | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/ext/mime.types b/pyrogram/client/ext/mime.types index 4db43cae..50ec065d 100644 --- a/pyrogram/client/ext/mime.types +++ b/pyrogram/client/ext/mime.types @@ -1852,4 +1852,7 @@ video/x-ms-wvx wvx video/x-msvideo avi video/x-sgi-movie movie video/x-smv smv -x-conference/x-cooltalk ice \ No newline at end of file +x-conference/x-cooltalk ice + +# Telegram animated stickers +application/x-tgsticker tgs \ No newline at end of file From 1f2be4f1cef6630831d99beb14c8eebcab9edb35 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 14:05:25 +0200 Subject: [PATCH 122/202] Add send_animated_sticker method --- pyrogram/client/methods/messages/__init__.py | 4 +- .../methods/messages/send_animated_sticker.py | 141 ++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 pyrogram/client/methods/messages/send_animated_sticker.py diff --git a/pyrogram/client/methods/messages/__init__.py b/pyrogram/client/methods/messages/__init__.py index e843aa7c..9ed6e33b 100644 --- a/pyrogram/client/methods/messages/__init__.py +++ b/pyrogram/client/methods/messages/__init__.py @@ -28,6 +28,7 @@ from .get_history_count import GetHistoryCount from .get_messages import GetMessages from .iter_history import IterHistory from .retract_vote import RetractVote +from .send_animated_sticker import SendAnimatedSticker from .send_animation import SendAnimation from .send_audio import SendAudio from .send_cached_media import SendCachedMedia @@ -78,6 +79,7 @@ class Messages( DownloadMedia, IterHistory, SendCachedMedia, - GetHistoryCount + GetHistoryCount, + SendAnimatedSticker ): pass diff --git a/pyrogram/client/methods/messages/send_animated_sticker.py b/pyrogram/client/methods/messages/send_animated_sticker.py new file mode 100644 index 00000000..789ca06d --- /dev/null +++ b/pyrogram/client/methods/messages/send_animated_sticker.py @@ -0,0 +1,141 @@ +# 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 . + +import os +from typing import Union + +import pyrogram +from pyrogram.api import functions, types +from pyrogram.client.ext import BaseClient, utils +from pyrogram.errors import FilePartMissing + + +class SendAnimatedSticker(BaseClient): + def send_animated_sticker( + self, + chat_id: Union[int, str], + animated_sticker: str, + disable_notification: bool = None, + reply_to_message_id: int = None, + reply_markup: Union[ + "pyrogram.InlineKeyboardMarkup", + "pyrogram.ReplyKeyboardMarkup", + "pyrogram.ReplyKeyboardRemove", + "pyrogram.ForceReply" + ] = None, + progress: callable = None, + progress_args: tuple = () + ) -> Union["pyrogram.Message", None]: + """Send .tgs animated stickers. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For your personal cloud (Saved Messages) you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + animated_sticker (``str``): + Animated sticker to send. + Pass a file_id as string to send a animated sticker that exists on the Telegram servers, + pass an HTTP URL as a string for Telegram to get a .webp animated sticker file from the Internet, or + pass a file path as string to upload a new animated sticker that exists on your local machine. + + disable_notification (``bool``, *optional*): + Sends the message silently. + Users will receive a notification with no sound. + + reply_to_message_id (``int``, *optional*): + If the message is a reply, ID of the original message. + + reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): + Additional interface options. An object for an inline keyboard, custom reply keyboard, + instructions to remove reply keyboard or to force a reply from the user. + + progress (``callable``, *optional*): + Pass a callback function to view the upload progress. + The function must take *(client, current, total, \*args)* as positional arguments (look at the section + below for a detailed description). + + progress_args (``tuple``, *optional*): + Extra custom arguments for the progress callback function. Useful, for example, if you want to pass + a chat_id and a message_id in order to edit a message with the updated progress. + + Other Parameters: + client (:obj:`Client`): + The Client itself, useful when you want to call other API methods inside the callback function. + + current (``int``): + The amount of bytes uploaded so far. + + total (``int``): + The size of the file. + + *args (``tuple``, *optional*): + Extra custom arguments as defined in the *progress_args* parameter. + You can either keep *\*args* or add every single extra argument in your function signature. + + Returns: + :obj:`Message` | ``None``: On success, the sent animated sticker message is returned, otherwise, in case the + upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned. + Raises: + RPCError: In case of a Telegram RPC error. + """ + file = None + + try: + if os.path.exists(animated_sticker): + file = self.save_file(animated_sticker, progress=progress, progress_args=progress_args) + media = types.InputMediaUploadedDocument( + mime_type=self.guess_mime_type(animated_sticker) or "application/x-tgsticker", + file=file, + attributes=[ + types.DocumentAttributeFilename(file_name=os.path.basename(animated_sticker)) + ] + ) + elif animated_sticker.startswith("http"): + media = types.InputMediaDocumentExternal( + url=animated_sticker + ) + else: + media = utils.get_input_media_from_file_id(animated_sticker, 8) + + while True: + try: + r = self.send( + functions.messages.SendMedia( + peer=self.resolve_peer(chat_id), + media=media, + silent=disable_notification or None, + reply_to_msg_id=reply_to_message_id, + random_id=self.rnd_id(), + reply_markup=reply_markup.write() if reply_markup else None, + message="" + ) + ) + except FilePartMissing as e: + self.save_file(animated_sticker, file_id=file.id, file_part=e.x) + else: + for i in r.updates: + if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): + return pyrogram.Message._parse( + self, i.message, + {i.id: i for i in r.users}, + {i.id: i for i in r.chats} + ) + except BaseClient.StopTransmission: + return None From acc0fab311d2b8af5d806d0bd9cc015b98daf065 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 14:07:45 +0200 Subject: [PATCH 123/202] Fix animated stickers media type. They are documents for now --- pyrogram/client/methods/messages/send_animated_sticker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/methods/messages/send_animated_sticker.py b/pyrogram/client/methods/messages/send_animated_sticker.py index 789ca06d..6fd0c647 100644 --- a/pyrogram/client/methods/messages/send_animated_sticker.py +++ b/pyrogram/client/methods/messages/send_animated_sticker.py @@ -112,7 +112,7 @@ class SendAnimatedSticker(BaseClient): url=animated_sticker ) else: - media = utils.get_input_media_from_file_id(animated_sticker, 8) + media = utils.get_input_media_from_file_id(animated_sticker, 5) while True: try: From 56f1a8ca9d124a092d8da6cf2f4c9d4de9321a48 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 15:25:42 +0200 Subject: [PATCH 124/202] Add send_animated_sticker to docs --- docs/source/api/methods.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index 2d3d8f23..b9fa180c 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -48,6 +48,7 @@ Messages - :meth:`~Client.send_audio` - :meth:`~Client.send_document` - :meth:`~Client.send_sticker` + - :meth:`~Client.send_animated_sticker` - :meth:`~Client.send_video` - :meth:`~Client.send_animation` - :meth:`~Client.send_voice` @@ -180,6 +181,7 @@ Details .. automethod:: Client.send_audio() .. automethod:: Client.send_document() .. automethod:: Client.send_sticker() +.. automethod:: Client.send_animated_sticker() .. automethod:: Client.send_video() .. automethod:: Client.send_animation() .. automethod:: Client.send_voice() From e9a2087fe094c40edea2601399ff78cfdfad0ba6 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 1 Jun 2019 15:36:53 +0200 Subject: [PATCH 125/202] Fix List not calling __repr__ --- pyrogram/api/core/list.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyrogram/api/core/list.py b/pyrogram/api/core/list.py index 1f55dc45..922ec64d 100644 --- a/pyrogram/api/core/list.py +++ b/pyrogram/api/core/list.py @@ -23,4 +23,6 @@ class List(list, Object): __slots__ = [] def __repr__(self): - return "pyrogram.api.core.List([{}])".format(",".join(Object.__str__(i) for i in self)) + return "pyrogram.api.core.List([{}])".format( + ",".join(Object.__repr__(i) for i in self) + ) From 0a96355c5dcda94a7ce982421ca0eeba66adf80d Mon Sep 17 00:00:00 2001 From: ColinShark Date: Sat, 1 Jun 2019 23:31:17 +0200 Subject: [PATCH 126/202] Add Filter for Callback_Query.data --- pyrogram/client/filters/filters.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 9c80d870..a3e39117 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -339,4 +339,19 @@ class Filters: and message.from_user.is_self and not message.outgoing))) + @staticmethod + def data(data: str or bytes = None): + """Filter callback queries for their data. + + Parameters: + data (``str`` | ``bytes``): + Pass the data you want to filter for. + Defaults to None (no data). + """ + + def f(_, cb): + return bool(cb.data and cb.data == _.d) + + return create("Data", f, d=data) + dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) From 2eba6e58f9f0eb983aedc25ea9b0c250bd52980a Mon Sep 17 00:00:00 2001 From: ColinShark Date: Sat, 1 Jun 2019 23:34:20 +0200 Subject: [PATCH 127/202] Remove Optionality for args --- pyrogram/client/filters/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index a3e39117..83e862e6 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -340,7 +340,7 @@ class Filters: and not message.outgoing))) @staticmethod - def data(data: str or bytes = None): + def data(data: str or bytes): """Filter callback queries for their data. Parameters: From 04aada818e4a6482128ff7448a6a8843b7adf0cc Mon Sep 17 00:00:00 2001 From: ColinShark Date: Sat, 1 Jun 2019 23:36:45 +0200 Subject: [PATCH 128/202] Less arbitrary name for Filter, Adapt Docstring --- pyrogram/client/filters/filters.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 83e862e6..c8b5b2f8 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -346,12 +346,11 @@ class Filters: Parameters: data (``str`` | ``bytes``): Pass the data you want to filter for. - Defaults to None (no data). """ def f(_, cb): return bool(cb.data and cb.data == _.d) - return create("Data", f, d=data) + return create("CallbackData", f, d=data) dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) From d3cb386a6f68eaa9ab94656c8826dd9b7c86d82b Mon Sep 17 00:00:00 2001 From: ColinShark Date: Sat, 1 Jun 2019 23:39:26 +0200 Subject: [PATCH 129/202] Appropiate naming --- pyrogram/client/filters/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index c8b5b2f8..1bcc858d 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -340,7 +340,7 @@ class Filters: and not message.outgoing))) @staticmethod - def data(data: str or bytes): + def callback_data(data: str or bytes): """Filter callback queries for their data. Parameters: From 12cc6fa4eb038af53621e14cf0b0565cc3b5db6f Mon Sep 17 00:00:00 2001 From: ColinShark Date: Sun, 2 Jun 2019 00:13:52 +0200 Subject: [PATCH 130/202] Removed Placeholder, break down comparison --- pyrogram/client/filters/filters.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 1bcc858d..12d5a69e 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -348,9 +348,9 @@ class Filters: Pass the data you want to filter for. """ - def f(_, cb): - return bool(cb.data and cb.data == _.d) + def f(flt, cb): + return cb.data == flt.data - return create("CallbackData", f, d=data) + return create("CallbackData", f, data=data) dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) From 5cb709ee75bdf16065a9f213c78f34b87ed41107 Mon Sep 17 00:00:00 2001 From: ColinShark Date: Sun, 2 Jun 2019 00:25:59 +0200 Subject: [PATCH 131/202] Make it one-line --- pyrogram/client/filters/filters.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 12d5a69e..1d962e85 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -348,9 +348,6 @@ class Filters: Pass the data you want to filter for. """ - def f(flt, cb): - return cb.data == flt.data - - return create("CallbackData", f, data=data) + return create("CallbackData", lambda flt, cb: cb.data == flt.data, data=data) dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) From cfec26d3db138aa620f1ffa203f6e44576cb6bad Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 2 Jun 2019 16:16:16 +0200 Subject: [PATCH 132/202] Add PyrogramList type --- pyrogram/client/types/pyrogram_list.py | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 pyrogram/client/types/pyrogram_list.py diff --git a/pyrogram/client/types/pyrogram_list.py b/pyrogram/client/types/pyrogram_list.py new file mode 100644 index 00000000..cb802e51 --- /dev/null +++ b/pyrogram/client/types/pyrogram_list.py @@ -0,0 +1,32 @@ +# 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 .pyrogram_type import PyrogramType + + +class PyrogramList(list): + __slots__ = [] + + def __str__(self): + # noinspection PyCallByClass + return PyrogramType.__str__(self) + + def __repr__(self): + return "pyrogram.client.types.pyrogram_list.PyrogramList([{}])".format( + ",".join(PyrogramType.__repr__(i) for i in self) + ) From 6d9443c82e198a82a951e0b96462731632aac029 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 2 Jun 2019 18:57:00 +0200 Subject: [PATCH 133/202] Reword some docs sections --- docs/source/license.rst | 2 +- docs/source/support-pyrogram.rst | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/source/license.rst b/docs/source/license.rst index 1c8d99d1..43f59d73 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -8,7 +8,7 @@ Pyrogram is free software and is currently licensed under the terms of the `GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it provided that modifications are described and licensed for free under LGPLv3+. -In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or +In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or a different license, or even proprietary --- without being required to release the source code of your own applications. However, any modifications to the library itself are required to be published for free under the same LGPLv3+ license. diff --git a/docs/source/support-pyrogram.rst b/docs/source/support-pyrogram.rst index c867b706..81a0e533 100644 --- a/docs/source/support-pyrogram.rst +++ b/docs/source/support-pyrogram.rst @@ -1,8 +1,8 @@ Support Pyrogram ================ -Pyrogram is free and open source software, and thus supported by your love! If you like the project and have found it to -be useful, give Pyrogram a `Star on GitHub`_. Your appreciation means a lot and helps staying motivated. +Pyrogram is free and open source software, and thus powered by your love and support! If you like the project and have +found it to be useful, give Pyrogram a `Star on GitHub`_. Your appreciation means a lot and helps staying motivated. .. raw:: html @@ -12,8 +12,9 @@ be useful, give Pyrogram a `Star on GitHub`_. Your appreciation means a lot and Donate ------ -If you'd also like to donate in order to support Pyrogram -- or any of my `other works`_ -- you can use the PayPal -button below. Thank you. +As a developer, you probably understand that "open source" doesn't mean "free work". A lot of time and resources has +been put into the project and if you'd like to tip me for Pyrogram -- or any of my `other works`_ -- you can use the +PayPal button below. Thank you! .. image:: https://i.imgur.com/fasFTzK.png :target: https://paypal.me/delivrance From 6683b18b2b3ccde857d9b82c4bed17ddf0275f8a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 2 Jun 2019 18:57:43 +0200 Subject: [PATCH 134/202] Add FAQ about easter eggs --- docs/source/faq.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 33e7282f..a0fe3331 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -183,6 +183,13 @@ However, you might be right, and your account was deactivated/limited without an mistakes by either the automatic systems or a moderator. In such cases you can kindly email Telegram at recover@telegram.org, contact `@smstelegram`_ on Twitter or use `this form`_. +Are there any secret easter eggs? +--------------------------------- + +Yes. If you found one, `let me know`_! + +.. _let me know: https://t.me/pyrogram + .. _@smstelegram: https://twitter.com/smstelegram .. _this form: https://telegram.org/support From d5517f4d5fb13b6a459315865ae3a756f59d2837 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 3 Jun 2019 14:19:50 +0200 Subject: [PATCH 135/202] Rename Object to TLObject --- compiler/api/compiler.py | 14 +++++++------- compiler/api/template/mtproto.txt | 2 +- pyrogram/api/__init__.py | 4 ++-- pyrogram/api/core/__init__.py | 2 +- pyrogram/api/core/future_salt.py | 4 ++-- pyrogram/api/core/future_salts.py | 4 ++-- pyrogram/api/core/gzip_packed.py | 8 ++++---- pyrogram/api/core/list.py | 6 +++--- pyrogram/api/core/message.py | 8 ++++---- pyrogram/api/core/msg_container.py | 4 ++-- pyrogram/api/core/primitives/bool.py | 6 +++--- pyrogram/api/core/primitives/bytes.py | 4 ++-- pyrogram/api/core/primitives/double.py | 4 ++-- pyrogram/api/core/primitives/int.py | 4 ++-- pyrogram/api/core/primitives/null.py | 4 ++-- pyrogram/api/core/primitives/vector.py | 12 ++++++------ pyrogram/api/core/{object.py => tl_object.py} | 13 ++++++++----- pyrogram/client/client.py | 4 ++-- pyrogram/session/auth.py | 10 +++++----- pyrogram/session/internals/msg_factory.py | 4 ++-- pyrogram/session/session.py | 6 +++--- 21 files changed, 65 insertions(+), 62 deletions(-) rename pyrogram/api/core/{object.py => tl_object.py} (86%) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 64e88c9d..0ecc9212 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -53,10 +53,10 @@ def get_docstring_arg_type(t: str, is_list: bool = False, is_pyrogram_type: bool return "``{}``".format(t.lower()) elif t == "true": return "``bool``" - elif t == "Object" or t == "X": - return "Any object from :obj:`pyrogram.api.types`" + elif t == "TLObject" or t == "X": + return "Any object from :obj:`~pyrogram.api.types`" elif t == "!X": - return "Any method from :obj:`pyrogram.api.functions`" + return "Any method from :obj:`~pyrogram.api.functions`" elif t.startswith("Vector"): return "List of " + get_docstring_arg_type(t.split("<", 1)[1][:-1], True, is_pyrogram_type) else: @@ -394,7 +394,7 @@ def start(): ) read_types += "\n " - read_types += "{} = Object.read(b{}) if flags & (1 << {}) else []\n ".format( + read_types += "{} = TLObject.read(b{}) if flags & (1 << {}) else []\n ".format( arg_name, ", {}".format(sub_type.title()) if sub_type in core_types else "", index ) else: @@ -403,7 +403,7 @@ def start(): write_types += "b.write(self.{}.write())\n ".format(arg_name) read_types += "\n " - read_types += "{} = Object.read(b) if flags & (1 << {}) else None\n ".format( + read_types += "{} = TLObject.read(b) if flags & (1 << {}) else None\n ".format( arg_name, index ) else: @@ -422,7 +422,7 @@ def start(): ) read_types += "\n " - read_types += "{} = Object.read(b{})\n ".format( + read_types += "{} = TLObject.read(b{})\n ".format( arg_name, ", {}".format(sub_type.title()) if sub_type in core_types else "" ) else: @@ -430,7 +430,7 @@ def start(): write_types += "b.write(self.{}.write())\n ".format(arg_name) read_types += "\n " - read_types += "{} = Object.read(b)\n ".format(arg_name) + read_types += "{} = TLObject.read(b)\n ".format(arg_name) if c.docs: description = c.docs.split("|")[0].split("§")[1] diff --git a/compiler/api/template/mtproto.txt b/compiler/api/template/mtproto.txt index c63525d6..d7d3c7b7 100644 --- a/compiler/api/template/mtproto.txt +++ b/compiler/api/template/mtproto.txt @@ -5,7 +5,7 @@ from io import BytesIO from pyrogram.api.core import * -class {class_name}(Object): +class {class_name}(TLObject): """{docstring_args} """ diff --git a/pyrogram/api/__init__.py b/pyrogram/api/__init__.py index e57f0661..8d7831ff 100644 --- a/pyrogram/api/__init__.py +++ b/pyrogram/api/__init__.py @@ -19,8 +19,8 @@ from importlib import import_module from .all import objects -from .core.object import Object +from .core.tl_object import TLObject for k, v in objects.items(): path, name = v.rsplit(".", 1) - Object.all[k] = getattr(import_module(path), name) + TLObject.all[k] = getattr(import_module(path), name) diff --git a/pyrogram/api/core/__init__.py b/pyrogram/api/core/__init__.py index bf596446..f27a26a5 100644 --- a/pyrogram/api/core/__init__.py +++ b/pyrogram/api/core/__init__.py @@ -22,7 +22,7 @@ from .gzip_packed import GzipPacked from .list import List from .message import Message from .msg_container import MsgContainer -from .object import Object +from .tl_object import TLObject from .primitives import ( Bool, BoolTrue, BoolFalse, Bytes, Double, Int, Long, Int128, Int256, Null, String, Vector diff --git a/pyrogram/api/core/future_salt.py b/pyrogram/api/core/future_salt.py index c4ccea3d..699a416f 100644 --- a/pyrogram/api/core/future_salt.py +++ b/pyrogram/api/core/future_salt.py @@ -18,11 +18,11 @@ from io import BytesIO -from .object import Object +from .tl_object import TLObject from .primitives import Int, Long -class FutureSalt(Object): +class FutureSalt(TLObject): ID = 0x0949d9dc __slots__ = ["valid_since", "valid_until", "salt"] diff --git a/pyrogram/api/core/future_salts.py b/pyrogram/api/core/future_salts.py index 91ee7b51..c749c569 100644 --- a/pyrogram/api/core/future_salts.py +++ b/pyrogram/api/core/future_salts.py @@ -19,11 +19,11 @@ from io import BytesIO from . import FutureSalt -from .object import Object +from .tl_object import TLObject from .primitives import Int, Long -class FutureSalts(Object): +class FutureSalts(TLObject): ID = 0xae500895 __slots__ = ["req_msg_id", "now", "salts"] diff --git a/pyrogram/api/core/gzip_packed.py b/pyrogram/api/core/gzip_packed.py index 135c36bf..4b212184 100644 --- a/pyrogram/api/core/gzip_packed.py +++ b/pyrogram/api/core/gzip_packed.py @@ -19,24 +19,24 @@ from gzip import compress, decompress from io import BytesIO -from .object import Object +from .tl_object import TLObject from .primitives import Int, Bytes -class GzipPacked(Object): +class GzipPacked(TLObject): ID = 0x3072cfa1 __slots__ = ["packed_data"] QUALNAME = "GzipPacked" - def __init__(self, packed_data: Object): + def __init__(self, packed_data: TLObject): self.packed_data = packed_data @staticmethod def read(b: BytesIO, *args) -> "GzipPacked": # Return the Object itself instead of a GzipPacked wrapping it - return Object.read( + return TLObject.read( BytesIO( decompress( Bytes.read(b) diff --git a/pyrogram/api/core/list.py b/pyrogram/api/core/list.py index 922ec64d..4b309a6d 100644 --- a/pyrogram/api/core/list.py +++ b/pyrogram/api/core/list.py @@ -16,13 +16,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .object import Object +from .tl_object import TLObject -class List(list, Object): +class List(list, TLObject): __slots__ = [] def __repr__(self): return "pyrogram.api.core.List([{}])".format( - ",".join(Object.__repr__(i) for i in self) + ",".join(TLObject.__repr__(i) for i in self) ) diff --git a/pyrogram/api/core/message.py b/pyrogram/api/core/message.py index 5b2e5b64..db123db3 100644 --- a/pyrogram/api/core/message.py +++ b/pyrogram/api/core/message.py @@ -18,18 +18,18 @@ from io import BytesIO -from .object import Object +from .tl_object import TLObject from .primitives import Int, Long -class Message(Object): +class Message(TLObject): ID = 0x5bb8e511 # hex(crc32(b"message msg_id:long seqno:int bytes:int body:Object = Message")) __slots__ = ["msg_id", "seq_no", "length", "body"] QUALNAME = "Message" - def __init__(self, body: Object, msg_id: int, seq_no: int, length: int): + def __init__(self, body: TLObject, msg_id: int, seq_no: int, length: int): self.msg_id = msg_id self.seq_no = seq_no self.length = length @@ -42,7 +42,7 @@ class Message(Object): length = Int.read(b) body = b.read(length) - return Message(Object.read(BytesIO(body)), msg_id, seq_no, length) + return Message(TLObject.read(BytesIO(body)), msg_id, seq_no, length) def write(self) -> bytes: b = BytesIO() diff --git a/pyrogram/api/core/msg_container.py b/pyrogram/api/core/msg_container.py index bfc41333..7a17087e 100644 --- a/pyrogram/api/core/msg_container.py +++ b/pyrogram/api/core/msg_container.py @@ -19,11 +19,11 @@ from io import BytesIO from .message import Message -from .object import Object +from .tl_object import TLObject from .primitives import Int -class MsgContainer(Object): +class MsgContainer(TLObject): ID = 0x73f1f8dc __slots__ = ["messages"] diff --git a/pyrogram/api/core/primitives/bool.py b/pyrogram/api/core/primitives/bool.py index 117ee7a4..0d3732e0 100644 --- a/pyrogram/api/core/primitives/bool.py +++ b/pyrogram/api/core/primitives/bool.py @@ -18,10 +18,10 @@ from io import BytesIO -from ..object import Object +from ..tl_object import TLObject -class BoolFalse(Object): +class BoolFalse(TLObject): ID = 0xbc799737 value = False @@ -38,7 +38,7 @@ class BoolTrue(BoolFalse): value = True -class Bool(Object): +class Bool(TLObject): @classmethod def read(cls, b: BytesIO) -> bool: return int.from_bytes(b.read(4), "little") == BoolTrue.ID diff --git a/pyrogram/api/core/primitives/bytes.py b/pyrogram/api/core/primitives/bytes.py index 8030b598..f511fef3 100644 --- a/pyrogram/api/core/primitives/bytes.py +++ b/pyrogram/api/core/primitives/bytes.py @@ -18,10 +18,10 @@ from io import BytesIO -from ..object import Object +from ..tl_object import TLObject -class Bytes(Object): +class Bytes(TLObject): @staticmethod def read(b: BytesIO, *args) -> bytes: length = int.from_bytes(b.read(1), "little") diff --git a/pyrogram/api/core/primitives/double.py b/pyrogram/api/core/primitives/double.py index 3dcaa461..067d08bd 100644 --- a/pyrogram/api/core/primitives/double.py +++ b/pyrogram/api/core/primitives/double.py @@ -19,10 +19,10 @@ from io import BytesIO from struct import unpack, pack -from ..object import Object +from ..tl_object import TLObject -class Double(Object): +class Double(TLObject): @staticmethod def read(b: BytesIO, *args) -> float: return unpack("d", b.read(8))[0] diff --git a/pyrogram/api/core/primitives/int.py b/pyrogram/api/core/primitives/int.py index 7833a610..ea43983c 100644 --- a/pyrogram/api/core/primitives/int.py +++ b/pyrogram/api/core/primitives/int.py @@ -18,10 +18,10 @@ from io import BytesIO -from ..object import Object +from ..tl_object import TLObject -class Int(Object): +class Int(TLObject): SIZE = 4 @classmethod diff --git a/pyrogram/api/core/primitives/null.py b/pyrogram/api/core/primitives/null.py index d2d3b1c0..ffddea94 100644 --- a/pyrogram/api/core/primitives/null.py +++ b/pyrogram/api/core/primitives/null.py @@ -18,10 +18,10 @@ from io import BytesIO -from ..object import Object +from ..tl_object import TLObject -class Null(Object): +class Null(TLObject): ID = 0x56730bcc @staticmethod diff --git a/pyrogram/api/core/primitives/vector.py b/pyrogram/api/core/primitives/vector.py index 720486f2..641b33ef 100644 --- a/pyrogram/api/core/primitives/vector.py +++ b/pyrogram/api/core/primitives/vector.py @@ -20,31 +20,31 @@ from io import BytesIO from . import Int from ..list import List -from ..object import Object +from ..tl_object import TLObject -class Vector(Object): +class Vector(TLObject): ID = 0x1cb5c415 # Method added to handle the special case when a query returns a bare Vector (of Ints); # i.e., RpcResult body starts with 0x1cb5c415 (Vector Id) - e.g., messages.GetMessagesViews. @staticmethod - def _read(b: BytesIO) -> Object or int: + def _read(b: BytesIO) -> TLObject or int: try: - return Object.read(b) + return TLObject.read(b) except KeyError: b.seek(-4, 1) return Int.read(b) @staticmethod - def read(b: BytesIO, t: Object = None) -> list: + def read(b: BytesIO, t: TLObject = None) -> list: return List( t.read(b) if t else Vector._read(b) for _ in range(Int.read(b)) ) - def __new__(cls, value: list, t: Object = None) -> bytes: + def __new__(cls, value: list, t: TLObject = None) -> bytes: return b"".join( [Int(cls.ID, False), Int(len(value))] + [ diff --git a/pyrogram/api/core/object.py b/pyrogram/api/core/tl_object.py similarity index 86% rename from pyrogram/api/core/object.py rename to pyrogram/api/core/tl_object.py index 9d1a4852..4b951404 100644 --- a/pyrogram/api/core/object.py +++ b/pyrogram/api/core/tl_object.py @@ -21,7 +21,7 @@ from io import BytesIO from json import dumps -class Object: +class TLObject: all = {} __slots__ = [] @@ -30,13 +30,13 @@ class Object: @staticmethod def read(b: BytesIO, *args): # TODO: Rename b -> data - return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args) + return TLObject.all[int.from_bytes(b.read(4), "little")].read(b, *args) def write(self, *args) -> bytes: pass @staticmethod - def default(obj: "Object"): + def default(obj: "TLObject"): if isinstance(obj, bytes): return repr(obj) @@ -50,7 +50,7 @@ class Object: ) def __str__(self) -> str: - return dumps(self, indent=4, default=Object.default, ensure_ascii=False) + return dumps(self, indent=4, default=TLObject.default, ensure_ascii=False) def __repr__(self) -> str: return "pyrogram.api.{}({})".format( @@ -62,7 +62,7 @@ class Object: ) ) - def __eq__(self, other: "Object") -> bool: + def __eq__(self, other: "TLObject") -> bool: for attr in self.__slots__: try: if getattr(self, attr) != getattr(other, attr): @@ -77,3 +77,6 @@ class Object: def __getitem__(self, item): return getattr(self, item) + + def __setitem__(self, key, value): + setattr(self, key, value) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 2ba6b8fa..08a3072e 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -37,7 +37,7 @@ from threading import Thread from typing import Union, List from pyrogram.api import functions, types -from pyrogram.api.core import Object +from pyrogram.api.core import TLObject from pyrogram.client.handlers import DisconnectHandler from pyrogram.client.handlers.handler import Handler from pyrogram.client.methods.password.utils import compute_check @@ -998,7 +998,7 @@ class Client(Methods, BaseClient): log.debug("{} stopped".format(name)) - def send(self, data: Object, retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT): + def send(self, data: TLObject, retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT): """Send raw Telegram queries. This method makes it possible to manually call every single Telegram API method in a low-level manner. diff --git a/pyrogram/session/auth.py b/pyrogram/session/auth.py index 89e5b61f..fb6e7ca3 100644 --- a/pyrogram/session/auth.py +++ b/pyrogram/session/auth.py @@ -23,7 +23,7 @@ from io import BytesIO from os import urandom from pyrogram.api import functions, types -from pyrogram.api.core import Object, Long, Int +from pyrogram.api.core import TLObject, Long, Int from pyrogram.connection import Connection from pyrogram.crypto import AES, RSA, Prime from .internals import MsgId @@ -43,7 +43,7 @@ class Auth: self.connection = None @staticmethod - def pack(data: Object) -> bytes: + def pack(data: TLObject) -> bytes: return ( bytes(8) + Long(MsgId()) @@ -54,9 +54,9 @@ class Auth: @staticmethod def unpack(b: BytesIO): b.seek(20) # Skip auth_key_id (8), message_id (8) and message_length (4) - return Object.read(b) + return TLObject.read(b) - def send(self, data: Object): + def send(self, data: TLObject): data = self.pack(data) self.connection.send(data) response = BytesIO(self.connection.recv()) @@ -158,7 +158,7 @@ class Auth: answer_with_hash = AES.ige256_decrypt(encrypted_answer, tmp_aes_key, tmp_aes_iv) answer = answer_with_hash[20:] - server_dh_inner_data = Object.read(BytesIO(answer)) + server_dh_inner_data = TLObject.read(BytesIO(answer)) log.debug("Done decrypting answer") diff --git a/pyrogram/session/internals/msg_factory.py b/pyrogram/session/internals/msg_factory.py index 7d922ec3..2b833ce8 100644 --- a/pyrogram/session/internals/msg_factory.py +++ b/pyrogram/session/internals/msg_factory.py @@ -16,7 +16,7 @@ # 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, Object +from pyrogram.api.core import Message, MsgContainer, TLObject from pyrogram.api.functions import Ping from pyrogram.api.types import MsgsAck, HttpWait from .msg_id import MsgId @@ -29,7 +29,7 @@ class MsgFactory: def __init__(self): self.seq_no = SeqNo() - def __call__(self, body: Object) -> Message: + def __call__(self, body: TLObject) -> Message: return Message( body, MsgId(), diff --git a/pyrogram/session/session.py b/pyrogram/session/session.py index e4260be4..8ef5570c 100644 --- a/pyrogram/session/session.py +++ b/pyrogram/session/session.py @@ -30,7 +30,7 @@ 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, Object, MsgContainer, Long, FutureSalt, Int +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 @@ -391,7 +391,7 @@ class Session: log.debug("RecvThread stopped") - def _send(self, data: Object, wait_response: bool = True, timeout: float = WAIT_TIMEOUT): + def _send(self, data: TLObject, wait_response: bool = True, timeout: float = WAIT_TIMEOUT): message = self.msg_factory(data) msg_id = message.msg_id @@ -422,7 +422,7 @@ class Session: else: return result - def send(self, data: Object, retries: int = MAX_RETRIES, timeout: float = WAIT_TIMEOUT): + def send(self, data: TLObject, retries: int = MAX_RETRIES, timeout: float = WAIT_TIMEOUT): self.is_connected.wait(self.WAIT_TIMEOUT) try: From 9a44c79a82080de0ecb11728f4f4259c30db9577 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 3 Jun 2019 16:56:37 +0200 Subject: [PATCH 136/202] Rename PyrogramType to Object --- .../client/types/inline_mode/inline_query.py | 4 +- .../types/inline_mode/inline_query_result.py | 4 +- .../todo/inline_query_result_audio.py | 4 +- .../todo/inline_query_result_cached_audio.py | 4 +- .../inline_query_result_cached_document.py | 4 +- .../todo/inline_query_result_cached_gif.py | 4 +- .../inline_query_result_cached_mpeg4_gif.py | 4 +- .../todo/inline_query_result_cached_photo.py | 4 +- .../inline_query_result_cached_sticker.py | 4 +- .../todo/inline_query_result_cached_video.py | 4 +- .../todo/inline_query_result_cached_voice.py | 4 +- .../todo/inline_query_result_contact.py | 4 +- .../todo/inline_query_result_document.py | 4 +- .../todo/inline_query_result_game.py | 4 +- .../todo/inline_query_result_gif.py | 4 +- .../todo/inline_query_result_location.py | 4 +- .../todo/inline_query_result_mpeg4_gif.py | 4 +- .../todo/inline_query_result_photo.py | 4 +- .../todo/inline_query_result_venue.py | 4 +- .../todo/inline_query_result_video.py | 4 +- .../todo/inline_query_result_voice.py | 4 +- .../client/types/input_media/input_media.py | 4 +- .../types/input_media/input_phone_contact.py | 4 +- .../input_message_content.py | 4 +- .../client/types/keyboards/callback_game.py | 4 +- .../client/types/keyboards/callback_query.py | 4 +- .../client/types/keyboards/force_reply.py | 4 +- .../client/types/keyboards/game_high_score.py | 4 +- .../types/keyboards/game_high_scores.py | 4 +- .../types/keyboards/inline_keyboard_button.py | 4 +- .../types/keyboards/inline_keyboard_markup.py | 4 +- .../client/types/keyboards/keyboard_button.py | 4 +- .../types/keyboards/reply_keyboard_markup.py | 4 +- .../types/keyboards/reply_keyboard_remove.py | 4 +- .../types/{pyrogram_list.py => list.py} | 8 +-- .../types/messages_and_media/animation.py | 4 +- .../client/types/messages_and_media/audio.py | 4 +- .../types/messages_and_media/contact.py | 4 +- .../types/messages_and_media/document.py | 4 +- .../client/types/messages_and_media/game.py | 4 +- .../types/messages_and_media/location.py | 4 +- .../types/messages_and_media/message.py | 4 +- .../messages_and_media/message_entity.py | 4 +- .../types/messages_and_media/messages.py | 4 +- .../client/types/messages_and_media/photo.py | 4 +- .../client/types/messages_and_media/photos.py | 4 +- .../client/types/messages_and_media/poll.py | 4 +- .../types/messages_and_media/poll_option.py | 4 +- .../types/messages_and_media/sticker.py | 4 +- .../messages_and_media/stripped_thumbnail.py | 4 +- .../types/messages_and_media/thumbnail.py | 4 +- .../client/types/messages_and_media/venue.py | 4 +- .../client/types/messages_and_media/video.py | 4 +- .../types/messages_and_media/video_note.py | 4 +- .../client/types/messages_and_media/voice.py | 4 +- .../types/{pyrogram_type.py => object.py} | 63 +++++++++++-------- pyrogram/client/types/user_and_chats/chat.py | 4 +- .../types/user_and_chats/chat_member.py | 4 +- .../types/user_and_chats/chat_members.py | 4 +- .../types/user_and_chats/chat_permissions.py | 4 +- .../client/types/user_and_chats/chat_photo.py | 4 +- .../types/user_and_chats/chat_preview.py | 4 +- .../client/types/user_and_chats/dialog.py | 4 +- .../client/types/user_and_chats/dialogs.py | 4 +- pyrogram/client/types/user_and_chats/user.py | 4 +- .../types/user_and_chats/user_status.py | 4 +- 66 files changed, 168 insertions(+), 159 deletions(-) rename pyrogram/client/types/{pyrogram_list.py => list.py} (85%) rename pyrogram/client/types/{pyrogram_type.py => object.py} (63%) diff --git a/pyrogram/client/types/inline_mode/inline_query.py b/pyrogram/client/types/inline_mode/inline_query.py index 1985a0c0..6bfc58c3 100644 --- a/pyrogram/client/types/inline_mode/inline_query.py +++ b/pyrogram/client/types/inline_mode/inline_query.py @@ -22,12 +22,12 @@ import pyrogram from pyrogram.api import types from .inline_query_result import InlineQueryResult from ..messages_and_media import Location -from ..pyrogram_type import PyrogramType +from ..object import Object from ..update import Update from ..user_and_chats import User -class InlineQuery(PyrogramType, Update): +class InlineQuery(Object, Update): """An incoming inline query. When the user sends an empty query, your bot could return some default or trending results. diff --git a/pyrogram/client/types/inline_mode/inline_query_result.py b/pyrogram/client/types/inline_mode/inline_query_result.py index 4b7f7ca3..74fe77d3 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result.py +++ b/pyrogram/client/types/inline_mode/inline_query_result.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from ..pyrogram_type import PyrogramType +from ..object import Object """- :obj:`InlineQueryResultCachedAudio` - :obj:`InlineQueryResultCachedDocument` @@ -39,7 +39,7 @@ from ..pyrogram_type import PyrogramType - :obj:`InlineQueryResultVoice`""" -class InlineQueryResult(PyrogramType): +class InlineQueryResult(Object): """One result of an inline query. Pyrogram currently supports results of the following 20 types: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py index 6ca0478a..dbda676d 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultAudio(PyrogramType): +class InlineQueryResultAudio(Object): """Represents a link to an mp3 audio file. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py index dc51139b..a4ac1ec8 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py @@ -23,10 +23,10 @@ from pyrogram.api import types from pyrogram.errors import FileIdInvalid from pyrogram.client.ext import utils, BaseClient from pyrogram.client.style import HTML, Markdown -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedAudio(PyrogramType): +class InlineQueryResultCachedAudio(Object): """Represents a link to an audio file stored on the Telegram servers. By default, this audio file will be sent by the user. Alternatively, you can use *input_message_content* to send a message with the specified content instead of the audio. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py index ad6cb9af..0dfde1c4 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedDocument(PyrogramType): +class InlineQueryResultCachedDocument(Object): """Represents a link to a file stored on the Telegram servers. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py index 1c836f20..819b383f 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedGif(PyrogramType): +class InlineQueryResultCachedGif(Object): """Represents a link to an animated GIF file stored on the Telegram servers. By default, this animated GIF file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with specified content instead of the animation. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py index 2082150d..9856af66 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedMpeg4Gif(PyrogramType): +class InlineQueryResultCachedMpeg4Gif(Object): """Represents a link to a video animation (H.264/MPEG-4 AVC video without sound) stored on the Telegram servers. By default, this animated MPEG-4 file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py index 20c1adbc..53b479f9 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedPhoto(PyrogramType): +class InlineQueryResultCachedPhoto(Object): """Represents a link to a photo stored on the Telegram servers. By default, this photo will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py index 4711cd72..6b2b37c9 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_sticker.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedSticker(PyrogramType): +class InlineQueryResultCachedSticker(Object): """Represents a link to a sticker stored on the Telegram servers. By default, this sticker will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the sticker. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py index e47cae1b..3a04a766 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedVideo(PyrogramType): +class InlineQueryResultCachedVideo(Object): """Represents a link to a video file stored on the Telegram servers. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py index 3091cf65..fbdf6c19 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultCachedVoice(PyrogramType): +class InlineQueryResultCachedVoice(Object): """Represents a link to a voice message stored on the Telegram servers. By default, this voice message will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the voice message. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py index 60512f0d..a64d6ace 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultContact(PyrogramType): +class InlineQueryResultContact(Object): """Represents a contact with a phone number. By default, this contact will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the contact. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py index a95dd2e9..007f237b 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultDocument(PyrogramType): +class InlineQueryResultDocument(Object): """Represents a link to a file. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. Currently, only .PDF and .ZIP files can be sent using this method. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py index 98654463..bd6f25d2 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_game.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultGame(PyrogramType): +class InlineQueryResultGame(Object): """Represents a Game. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py index d84e098b..7273b79a 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultGif(PyrogramType): +class InlineQueryResultGif(Object): """Represents a link to an animated GIF file. By default, this animated GIF file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py index cd05c832..a32fc93d 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultLocation(PyrogramType): +class InlineQueryResultLocation(Object): """Represents a location on a map. By default, the location will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the location. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py index cb704eeb..04c68cf7 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultMpeg4Gif(PyrogramType): +class InlineQueryResultMpeg4Gif(Object): """Represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By default, this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py index db6b9090..57f36fae 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py @@ -18,10 +18,10 @@ from pyrogram.api import types from pyrogram.client.style import HTML, Markdown -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultPhoto(PyrogramType): +class InlineQueryResultPhoto(Object): """Represents a link to a photo. By default, this photo will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo. diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py index 51ee8ae7..3343ccf9 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultVenue(PyrogramType): +class InlineQueryResultVenue(Object): """Represents a venue. By default, the venue will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the venue. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py index c8e27f79..ebfe2047 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultVideo(PyrogramType): +class InlineQueryResultVideo(Object): """Represents a link to a page containing an embedded video player or a video file. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video. Attributes: diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py index 23cc741f..4e2bbb09 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object -class InlineQueryResultVoice(PyrogramType): +class InlineQueryResultVoice(Object): """Represents a link to a voice recording in an .ogg container encoded with OPUS. By default, this voice recording will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the the voice message. Attributes: diff --git a/pyrogram/client/types/input_media/input_media.py b/pyrogram/client/types/input_media/input_media.py index 8360862f..2b5d7f0f 100644 --- a/pyrogram/client/types/input_media/input_media.py +++ b/pyrogram/client/types/input_media/input_media.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from ..pyrogram_type import PyrogramType +from ..object import Object -class InputMedia(PyrogramType): +class InputMedia(Object): """Content of a media message to be sent. It should be one of: diff --git a/pyrogram/client/types/input_media/input_phone_contact.py b/pyrogram/client/types/input_media/input_phone_contact.py index c1627516..e49cee30 100644 --- a/pyrogram/client/types/input_media/input_phone_contact.py +++ b/pyrogram/client/types/input_media/input_phone_contact.py @@ -18,10 +18,10 @@ from pyrogram.api.types import InputPhoneContact as RawInputPhoneContact from pyrogram.session.internals import MsgId -from ..pyrogram_type import PyrogramType +from ..object import Object -class InputPhoneContact(PyrogramType): +class InputPhoneContact(Object): """A Phone Contact to be added in your Telegram address book. It is intended to be used with :meth:`~Client.add_contacts() ` 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 50e068b7..1941ffb5 100644 --- a/pyrogram/client/types/input_message_content/input_message_content.py +++ b/pyrogram/client/types/input_message_content/input_message_content.py @@ -16,14 +16,14 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from ..pyrogram_type import PyrogramType +from ..object import Object """- :obj:`InputLocationMessageContent` - :obj:`InputVenueMessageContent` - :obj:`InputContactMessageContent`""" -class InputMessageContent(PyrogramType): +class InputMessageContent(Object): """Content of a message to be sent as a result of an inline query. Pyrogram currently supports the following 4 types: diff --git a/pyrogram/client/types/keyboards/callback_game.py b/pyrogram/client/types/keyboards/callback_game.py index 4fa43a30..acf6df60 100644 --- a/pyrogram/client/types/keyboards/callback_game.py +++ b/pyrogram/client/types/keyboards/callback_game.py @@ -16,10 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from ..pyrogram_type import PyrogramType +from ..object import Object -class CallbackGame(PyrogramType): +class CallbackGame(Object): """Placeholder, currently holds no information. Use BotFather to set up your game. diff --git a/pyrogram/client/types/keyboards/callback_query.py b/pyrogram/client/types/keyboards/callback_query.py index fe6a2175..fa0d8be2 100644 --- a/pyrogram/client/types/keyboards/callback_query.py +++ b/pyrogram/client/types/keyboards/callback_query.py @@ -22,12 +22,12 @@ from typing import Union import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object from ..update import Update from ..user_and_chats import User -class CallbackQuery(PyrogramType, Update): +class CallbackQuery(Object, Update): """An incoming callback query from a callback button in an inline keyboard. If the button that originated the query was attached to a message sent by the bot, the field *message* diff --git a/pyrogram/client/types/keyboards/force_reply.py b/pyrogram/client/types/keyboards/force_reply.py index 5b263d03..59405529 100644 --- a/pyrogram/client/types/keyboards/force_reply.py +++ b/pyrogram/client/types/keyboards/force_reply.py @@ -17,10 +17,10 @@ # along with Pyrogram. If not, see . from pyrogram.api.types import ReplyKeyboardForceReply -from ..pyrogram_type import PyrogramType +from ..object import Object -class ForceReply(PyrogramType): +class ForceReply(Object): """Object used to force clients to show a reply interface. Upon receiving a message with this object, Telegram clients will display a reply interface to the user. diff --git a/pyrogram/client/types/keyboards/game_high_score.py b/pyrogram/client/types/keyboards/game_high_score.py index 56389b17..5d576ad4 100644 --- a/pyrogram/client/types/keyboards/game_high_score.py +++ b/pyrogram/client/types/keyboards/game_high_score.py @@ -19,11 +19,11 @@ import pyrogram from pyrogram.api import types -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object from pyrogram.client.types.user_and_chats import User -class GameHighScore(PyrogramType): +class GameHighScore(Object): """One row of the high scores table for a game. Parameters: diff --git a/pyrogram/client/types/keyboards/game_high_scores.py b/pyrogram/client/types/keyboards/game_high_scores.py index 8183b9b0..ea557cd5 100644 --- a/pyrogram/client/types/keyboards/game_high_scores.py +++ b/pyrogram/client/types/keyboards/game_high_scores.py @@ -20,11 +20,11 @@ from typing import List import pyrogram from pyrogram.api import types -from pyrogram.client.types.pyrogram_type import PyrogramType +from pyrogram.client.types.object import Object from .game_high_score import GameHighScore -class GameHighScores(PyrogramType): +class GameHighScores(Object): """The high scores table for a game. Parameters: diff --git a/pyrogram/client/types/keyboards/inline_keyboard_button.py b/pyrogram/client/types/keyboards/inline_keyboard_button.py index 08ad0f35..54aa7802 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_button.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_button.py @@ -23,10 +23,10 @@ from pyrogram.api.types import ( KeyboardButtonSwitchInline, KeyboardButtonGame ) from .callback_game import CallbackGame -from ..pyrogram_type import PyrogramType +from ..object import Object -class InlineKeyboardButton(PyrogramType): +class InlineKeyboardButton(Object): """One button of an inline keyboard. You must use exactly one of the optional fields. diff --git a/pyrogram/client/types/keyboards/inline_keyboard_markup.py b/pyrogram/client/types/keyboards/inline_keyboard_markup.py index c7230eaf..7b811f88 100644 --- a/pyrogram/client/types/keyboards/inline_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/inline_keyboard_markup.py @@ -20,10 +20,10 @@ from typing import List from pyrogram.api.types import ReplyInlineMarkup, KeyboardButtonRow from . import InlineKeyboardButton -from ..pyrogram_type import PyrogramType +from ..object import Object -class InlineKeyboardMarkup(PyrogramType): +class InlineKeyboardMarkup(Object): """An inline keyboard that appears right next to the message it belongs to. Parameters: diff --git a/pyrogram/client/types/keyboards/keyboard_button.py b/pyrogram/client/types/keyboards/keyboard_button.py index 93d2e5ef..2dc09f5d 100644 --- a/pyrogram/client/types/keyboards/keyboard_button.py +++ b/pyrogram/client/types/keyboards/keyboard_button.py @@ -18,10 +18,10 @@ from pyrogram.api.types import KeyboardButton as RawKeyboardButton from pyrogram.api.types import KeyboardButtonRequestPhone, KeyboardButtonRequestGeoLocation -from ..pyrogram_type import PyrogramType +from ..object import Object -class KeyboardButton(PyrogramType): +class KeyboardButton(Object): """One button of the reply keyboard. For simple text buttons String can be used instead of this object to specify text of the button. Optional fields are mutually exclusive. diff --git a/pyrogram/client/types/keyboards/reply_keyboard_markup.py b/pyrogram/client/types/keyboards/reply_keyboard_markup.py index c4b37b7c..4e666d1f 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_markup.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_markup.py @@ -21,10 +21,10 @@ from typing import List, Union from pyrogram.api.types import KeyboardButtonRow from pyrogram.api.types import ReplyKeyboardMarkup as RawReplyKeyboardMarkup from . import KeyboardButton -from ..pyrogram_type import PyrogramType +from ..object import Object -class ReplyKeyboardMarkup(PyrogramType): +class ReplyKeyboardMarkup(Object): """A custom keyboard with reply options. Parameters: diff --git a/pyrogram/client/types/keyboards/reply_keyboard_remove.py b/pyrogram/client/types/keyboards/reply_keyboard_remove.py index 9d6eb7d5..8dd84f72 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_remove.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_remove.py @@ -17,10 +17,10 @@ # along with Pyrogram. If not, see . from pyrogram.api.types import ReplyKeyboardHide -from ..pyrogram_type import PyrogramType +from ..object import Object -class ReplyKeyboardRemove(PyrogramType): +class ReplyKeyboardRemove(Object): """Object used to tell clients to remove a bot keyboard. Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and display diff --git a/pyrogram/client/types/pyrogram_list.py b/pyrogram/client/types/list.py similarity index 85% rename from pyrogram/client/types/pyrogram_list.py rename to pyrogram/client/types/list.py index cb802e51..cec2d8a2 100644 --- a/pyrogram/client/types/pyrogram_list.py +++ b/pyrogram/client/types/list.py @@ -16,17 +16,17 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .pyrogram_type import PyrogramType +from .object import Object -class PyrogramList(list): +class List(list): __slots__ = [] def __str__(self): # noinspection PyCallByClass - return PyrogramType.__str__(self) + return Object.__str__(self) def __repr__(self): return "pyrogram.client.types.pyrogram_list.PyrogramList([{}])".format( - ",".join(PyrogramType.__repr__(i) for i in self) + ",".join(Object.__repr__(i) for i in self) ) diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index d729c3ac..0dfbed17 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -22,11 +22,11 @@ from typing import List import pyrogram from pyrogram.api import types from .thumbnail import Thumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class Animation(PyrogramType): +class Animation(Object): """An animation file (GIF or H.264/MPEG-4 AVC video without sound). Parameters: diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index ccea2f3c..64e450f4 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -22,11 +22,11 @@ from typing import List import pyrogram from pyrogram.api import types from .thumbnail import Thumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class Audio(PyrogramType): +class Audio(Object): """An audio file to be treated as music by the Telegram clients. Parameters: diff --git a/pyrogram/client/types/messages_and_media/contact.py b/pyrogram/client/types/messages_and_media/contact.py index 9205304e..d18f5e18 100644 --- a/pyrogram/client/types/messages_and_media/contact.py +++ b/pyrogram/client/types/messages_and_media/contact.py @@ -19,10 +19,10 @@ import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object -class Contact(PyrogramType): +class Contact(Object): """A phone contact. Parameters: diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index a8838531..ad48a847 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -22,11 +22,11 @@ from typing import List import pyrogram from pyrogram.api import types from .thumbnail import Thumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class Document(PyrogramType): +class Document(Object): """A generic file (as opposed to photos, voice messages, audio files, ...). Parameters: diff --git a/pyrogram/client/types/messages_and_media/game.py b/pyrogram/client/types/messages_and_media/game.py index 1377173a..2b400e65 100644 --- a/pyrogram/client/types/messages_and_media/game.py +++ b/pyrogram/client/types/messages_and_media/game.py @@ -20,10 +20,10 @@ import pyrogram from pyrogram.api import types from .animation import Animation from .photo import Photo -from ..pyrogram_type import PyrogramType +from ..object import Object -class Game(PyrogramType): +class Game(Object): """A game. Use BotFather to create and edit games, their short names will act as unique identifiers. diff --git a/pyrogram/client/types/messages_and_media/location.py b/pyrogram/client/types/messages_and_media/location.py index 55def7a0..5af55f0f 100644 --- a/pyrogram/client/types/messages_and_media/location.py +++ b/pyrogram/client/types/messages_and_media/location.py @@ -19,10 +19,10 @@ import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object -class Location(PyrogramType): +class Location(Object): """A point on the map. Parameters: diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index c3a12f3e..f7dff7b5 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -27,7 +27,7 @@ from .contact import Contact from .location import Location from .message_entity import MessageEntity from ..messages_and_media.photo import Photo -from ..pyrogram_type import PyrogramType +from ..object import Object from ..update import Update from ..user_and_chats.chat import Chat from ..user_and_chats.user import User @@ -59,7 +59,7 @@ class Str(str): return self._client.html.unparse(self, self._entities) -class Message(PyrogramType, Update): +class Message(Object, Update): """A message. Parameters: diff --git a/pyrogram/client/types/messages_and_media/message_entity.py b/pyrogram/client/types/messages_and_media/message_entity.py index e369e74e..5f3483ee 100644 --- a/pyrogram/client/types/messages_and_media/message_entity.py +++ b/pyrogram/client/types/messages_and_media/message_entity.py @@ -19,11 +19,11 @@ import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object from ..user_and_chats.user import User -class MessageEntity(PyrogramType): +class MessageEntity(Object): """One special entity in a text message. For example, hashtags, usernames, URLs, etc. diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py index f94f1951..ee516f20 100644 --- a/pyrogram/client/types/messages_and_media/messages.py +++ b/pyrogram/client/types/messages_and_media/messages.py @@ -21,12 +21,12 @@ from typing import List, Union import pyrogram from pyrogram.api import types from .message import Message -from ..pyrogram_type import PyrogramType +from ..object import Object from ..update import Update from ..user_and_chats import Chat -class Messages(PyrogramType, Update): +class Messages(Object, Update): """Contains a chat's messages. Parameters: diff --git a/pyrogram/client/types/messages_and_media/photo.py b/pyrogram/client/types/messages_and_media/photo.py index ca42c3eb..b5d80b82 100644 --- a/pyrogram/client/types/messages_and_media/photo.py +++ b/pyrogram/client/types/messages_and_media/photo.py @@ -22,11 +22,11 @@ from typing import List import pyrogram from pyrogram.api import types from .thumbnail import Thumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class Photo(PyrogramType): +class Photo(Object): """A Photo. Parameters: diff --git a/pyrogram/client/types/messages_and_media/photos.py b/pyrogram/client/types/messages_and_media/photos.py index 1d5b193e..a1803923 100644 --- a/pyrogram/client/types/messages_and_media/photos.py +++ b/pyrogram/client/types/messages_and_media/photos.py @@ -20,10 +20,10 @@ from typing import List import pyrogram from .photo import Photo -from ..pyrogram_type import PyrogramType +from ..object import Object -class Photos(PyrogramType): +class Photos(Object): """Contains a user's profile pictures. Parameters: diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index e6c97bfb..2570fdf1 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -21,11 +21,11 @@ from typing import List, Union import pyrogram from pyrogram.api import types from .poll_option import PollOption -from ..pyrogram_type import PyrogramType +from ..object import Object from ..update import Update -class Poll(PyrogramType, Update): +class Poll(Object, Update): """A Poll. Parameters: diff --git a/pyrogram/client/types/messages_and_media/poll_option.py b/pyrogram/client/types/messages_and_media/poll_option.py index e7eb1f5f..35f6b071 100644 --- a/pyrogram/client/types/messages_and_media/poll_option.py +++ b/pyrogram/client/types/messages_and_media/poll_option.py @@ -17,10 +17,10 @@ # along with Pyrogram. If not, see . import pyrogram -from ..pyrogram_type import PyrogramType +from ..object import Object -class PollOption(PyrogramType): +class PollOption(Object): """Contains information about one answer option in a poll. Parameters: diff --git a/pyrogram/client/types/messages_and_media/sticker.py b/pyrogram/client/types/messages_and_media/sticker.py index d133b31b..9e528dd8 100644 --- a/pyrogram/client/types/messages_and_media/sticker.py +++ b/pyrogram/client/types/messages_and_media/sticker.py @@ -24,11 +24,11 @@ import pyrogram from pyrogram.api import types, functions from pyrogram.errors import StickersetInvalid from .thumbnail import Thumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class Sticker(PyrogramType): +class Sticker(Object): """A sticker. Parameters: diff --git a/pyrogram/client/types/messages_and_media/stripped_thumbnail.py b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py index 31638fc2..4dbeb7d1 100644 --- a/pyrogram/client/types/messages_and_media/stripped_thumbnail.py +++ b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py @@ -18,10 +18,10 @@ import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object -class StrippedThumbnail(PyrogramType): +class StrippedThumbnail(Object): """A stripped thumbnail Parameters: diff --git a/pyrogram/client/types/messages_and_media/thumbnail.py b/pyrogram/client/types/messages_and_media/thumbnail.py index 0ff15e66..ee173b1c 100644 --- a/pyrogram/client/types/messages_and_media/thumbnail.py +++ b/pyrogram/client/types/messages_and_media/thumbnail.py @@ -23,10 +23,10 @@ import pyrogram from pyrogram.api import types from pyrogram.client.ext.utils import encode from .stripped_thumbnail import StrippedThumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object -class Thumbnail(PyrogramType): +class Thumbnail(Object): """One size of a photo or a file/sticker thumbnail. Parameters: diff --git a/pyrogram/client/types/messages_and_media/venue.py b/pyrogram/client/types/messages_and_media/venue.py index e54a812e..45d9368f 100644 --- a/pyrogram/client/types/messages_and_media/venue.py +++ b/pyrogram/client/types/messages_and_media/venue.py @@ -19,10 +19,10 @@ import pyrogram from pyrogram.api import types from .location import Location -from ..pyrogram_type import PyrogramType +from ..object import Object -class Venue(PyrogramType): +class Venue(Object): """A venue. Parameters: diff --git a/pyrogram/client/types/messages_and_media/video.py b/pyrogram/client/types/messages_and_media/video.py index 7a20283f..feda9711 100644 --- a/pyrogram/client/types/messages_and_media/video.py +++ b/pyrogram/client/types/messages_and_media/video.py @@ -22,11 +22,11 @@ from typing import List import pyrogram from pyrogram.api import types from .thumbnail import Thumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class Video(PyrogramType): +class Video(Object): """A video file. Parameters: diff --git a/pyrogram/client/types/messages_and_media/video_note.py b/pyrogram/client/types/messages_and_media/video_note.py index 34f5972f..b1d9bcdb 100644 --- a/pyrogram/client/types/messages_and_media/video_note.py +++ b/pyrogram/client/types/messages_and_media/video_note.py @@ -22,11 +22,11 @@ from typing import List import pyrogram from pyrogram.api import types from .thumbnail import Thumbnail -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class VideoNote(PyrogramType): +class VideoNote(Object): """A video note. Parameters: diff --git a/pyrogram/client/types/messages_and_media/voice.py b/pyrogram/client/types/messages_and_media/voice.py index 3e08d57a..e4256197 100644 --- a/pyrogram/client/types/messages_and_media/voice.py +++ b/pyrogram/client/types/messages_and_media/voice.py @@ -20,11 +20,11 @@ from struct import pack import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class Voice(PyrogramType): +class Voice(Object): """A voice note. Parameters: diff --git a/pyrogram/client/types/pyrogram_type.py b/pyrogram/client/types/object.py similarity index 63% rename from pyrogram/client/types/pyrogram_type.py rename to pyrogram/client/types/object.py index 9a04c636..4d482e63 100644 --- a/pyrogram/client/types/pyrogram_type.py +++ b/pyrogram/client/types/object.py @@ -23,7 +23,12 @@ from json import dumps import pyrogram -class PyrogramType: +class Meta(type, metaclass=type("", (type,), {"__str__": lambda _: "~hi"})): + def __str__(self): + return "".format(self.__name__) + + +class Object(metaclass=Meta): __slots__ = ["_client"] def __init__(self, client: "pyrogram.BaseClient" = None): @@ -32,35 +37,26 @@ class PyrogramType: if self._client is None: del self._client - def __eq__(self, other: "PyrogramType") -> bool: - for attr in self.__slots__: - try: - if getattr(self, attr) != getattr(other, attr): - return False - except AttributeError: - return False + @staticmethod + def default(obj: "Object"): + if isinstance(obj, bytes): + return repr(obj) - return True + return OrderedDict( + [("_", "pyrogram." + obj.__class__.__name__)] + + [ + (attr, "*" * len(getattr(obj, attr))) + if attr == "phone_number" + else (attr, str(datetime.fromtimestamp(getattr(obj, attr)))) + if attr.endswith("date") + else (attr, getattr(obj, attr)) + for attr in obj.__slots__ + if getattr(obj, attr) is not None + ] + ) def __str__(self) -> str: - def default(obj: PyrogramType): - try: - return OrderedDict( - [("_", "pyrogram." + obj.__class__.__name__)] - + [ - (attr, "*" * len(getattr(obj, attr))) - if attr == "phone_number" - else (attr, str(datetime.fromtimestamp(getattr(obj, attr)))) - if attr.endswith("date") - else (attr, getattr(obj, attr)) - for attr in obj.__slots__ - if getattr(obj, attr) is not None - ] - ) - except AttributeError: - return repr(obj) - - return dumps(self, indent=4, default=default, ensure_ascii=False) + return dumps(self, indent=4, default=Object.default, ensure_ascii=False) def __repr__(self) -> str: return "pyrogram.{}({})".format( @@ -72,5 +68,18 @@ class PyrogramType: ) ) + def __eq__(self, other: "Object") -> bool: + for attr in self.__slots__: + try: + if getattr(self, attr) != getattr(other, attr): + return False + except AttributeError: + return False + + return True + def __getitem__(self, item): return getattr(self, item) + + def __setitem__(self, key, value): + setattr(self, key, value) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index e260d8cd..ca9acd65 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -22,10 +22,10 @@ import pyrogram from pyrogram.api import types from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto -from ..pyrogram_type import PyrogramType +from ..object import Object -class Chat(PyrogramType): +class Chat(Object): """A chat. Parameters: diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 536f9526..7451012c 100644 --- a/pyrogram/client/types/user_and_chats/chat_member.py +++ b/pyrogram/client/types/user_and_chats/chat_member.py @@ -19,10 +19,10 @@ import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object -class ChatMember(PyrogramType): +class ChatMember(Object): """Contains information about one member of a chat. Parameters: diff --git a/pyrogram/client/types/user_and_chats/chat_members.py b/pyrogram/client/types/user_and_chats/chat_members.py index f57b8b46..6abdd719 100644 --- a/pyrogram/client/types/user_and_chats/chat_members.py +++ b/pyrogram/client/types/user_and_chats/chat_members.py @@ -21,10 +21,10 @@ from typing import List import pyrogram from pyrogram.api import types from .chat_member import ChatMember -from ..pyrogram_type import PyrogramType +from ..object import Object -class ChatMembers(PyrogramType): +class ChatMembers(Object): """Contains information about the members list of a chat. Parameters: diff --git a/pyrogram/client/types/user_and_chats/chat_permissions.py b/pyrogram/client/types/user_and_chats/chat_permissions.py index 6fa1a2a8..84099955 100644 --- a/pyrogram/client/types/user_and_chats/chat_permissions.py +++ b/pyrogram/client/types/user_and_chats/chat_permissions.py @@ -19,10 +19,10 @@ from typing import Union from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object -class ChatPermissions(PyrogramType): +class ChatPermissions(Object): """A chat default permissions and a single member permissions within a chat. Some permissions make sense depending on the context: default chat permissions, restricted/kicked member or diff --git a/pyrogram/client/types/user_and_chats/chat_photo.py b/pyrogram/client/types/user_and_chats/chat_photo.py index 1885eff2..1584a286 100644 --- a/pyrogram/client/types/user_and_chats/chat_photo.py +++ b/pyrogram/client/types/user_and_chats/chat_photo.py @@ -20,11 +20,11 @@ from struct import pack import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object from ...ext.utils import encode -class ChatPhoto(PyrogramType): +class ChatPhoto(Object): """A chat photo. Parameters: diff --git a/pyrogram/client/types/user_and_chats/chat_preview.py b/pyrogram/client/types/user_and_chats/chat_preview.py index 38dda6b6..312bdfe6 100644 --- a/pyrogram/client/types/user_and_chats/chat_preview.py +++ b/pyrogram/client/types/user_and_chats/chat_preview.py @@ -21,11 +21,11 @@ from typing import List import pyrogram from pyrogram.api import types from .chat_photo import ChatPhoto -from ..pyrogram_type import PyrogramType +from ..object import Object from ..user_and_chats.user import User -class ChatPreview(PyrogramType): +class ChatPreview(Object): """A chat preview. Parameters: diff --git a/pyrogram/client/types/user_and_chats/dialog.py b/pyrogram/client/types/user_and_chats/dialog.py index 4b900012..4ea82184 100644 --- a/pyrogram/client/types/user_and_chats/dialog.py +++ b/pyrogram/client/types/user_and_chats/dialog.py @@ -19,11 +19,11 @@ import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object from ..user_and_chats import Chat -class Dialog(PyrogramType): +class Dialog(Object): """A user's dialog. Parameters: diff --git a/pyrogram/client/types/user_and_chats/dialogs.py b/pyrogram/client/types/user_and_chats/dialogs.py index 862fcf22..56cdfc72 100644 --- a/pyrogram/client/types/user_and_chats/dialogs.py +++ b/pyrogram/client/types/user_and_chats/dialogs.py @@ -22,10 +22,10 @@ import pyrogram from pyrogram.api import types from .dialog import Dialog from ..messages_and_media import Message -from ..pyrogram_type import PyrogramType +from ..object import Object -class Dialogs(PyrogramType): +class Dialogs(Object): """Contains a user's dialogs chunk. Parameters: diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index ae631df1..50dd8361 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -20,10 +20,10 @@ import pyrogram from pyrogram.api import types from .chat_photo import ChatPhoto from .user_status import UserStatus -from ..pyrogram_type import PyrogramType +from ..object import Object -class User(PyrogramType): +class User(Object): """A Telegram user or bot. Parameters: diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index e6f5b134..4d12afc1 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -19,11 +19,11 @@ import pyrogram from pyrogram.api import types -from ..pyrogram_type import PyrogramType +from ..object import Object from ..update import Update -class UserStatus(PyrogramType, Update): +class UserStatus(Object, Update): """A User status (Last Seen privacy). .. note:: From 1be8ca94cc2a3535b285f0c7d773e7f39a6a62a6 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 4 Jun 2019 16:10:32 +0200 Subject: [PATCH 137/202] Update docs with new content --- docs/source/faq.rst | 24 +++- docs/source/glossary.rst | 4 + docs/source/index.rst | 4 +- docs/source/start/invoking.rst | 38 ++--- docs/source/start/updates.rst | 39 ++--- docs/source/topics/create-filters.rst | 92 ++++++++++++ docs/source/topics/debugging.rst | 135 ++++++++++++++++++ .../topics/{filters.rst => use-filters.rst} | 90 ------------ 8 files changed, 295 insertions(+), 131 deletions(-) create mode 100644 docs/source/topics/create-filters.rst create mode 100644 docs/source/topics/debugging.rst rename docs/source/topics/{filters.rst => use-filters.rst} (50%) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index a0fe3331..6c3cc1ab 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -155,6 +155,14 @@ things: 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)``. +UnicodeEncodeError: '' codec can't encode … +----------------------------------------------------- + +Where ```` might be *ascii*, *cp932*, *charmap* or anything else other than **utf-8**. This error usually +shows up when you try to print something and has very little to do with Pyrogram itself as it is strictly related to +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 one. + My verification code expires immediately! ----------------------------------------- @@ -179,8 +187,20 @@ Having said that, here's a list of what Telegram definitely doesn't like: - Spam, sending unsolicited messages or adding people to unwanted groups and channels. - Virtual/VoIP and cheap real numbers, because they are relatively easy to get and likely used for spam/flood. -However, you might be right, and your account was deactivated/limited without any reason. This could happen because of -mistakes by either the automatic systems or a moderator. In such cases you can kindly email Telegram at +And here's a good explanation of how, probably, the system works: + +.. raw:: html + + + +.. centered:: Join the discussion at `@PyrogramChat `_ + +However, you might be right, and your account was deactivated/limited without any good reason. This could happen because +of mistakes by either the automatic systems or a moderator. In such cases you can kindly email Telegram at recover@telegram.org, contact `@smstelegram`_ on Twitter or use `this form`_. Are there any secret easter eggs? diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst index 72d308b7..bcb1193c 100644 --- a/docs/source/glossary.rst +++ b/docs/source/glossary.rst @@ -9,7 +9,11 @@ general. Some words may as well link to dedicated articles in case the topic is If you think something interesting could be added here, feel free to propose it by opening a `Feature Request`_. +Terms +----- + .. glossary:: + :sorted: API Application Programming Interface: a set of methods, protocols and tools that make it easier to develop programs diff --git a/docs/source/index.rst b/docs/source/index.rst index b99fcf3d..12ac705b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -122,7 +122,8 @@ Meta :hidden: :caption: Topic Guides - topics/filters + topics/use-filters + topics/create-filters topics/more-on-updates topics/config-file topics/smart-plugins @@ -134,6 +135,7 @@ Meta topics/proxy topics/bots-interaction topics/mtproto-vs-botapi + topics/debugging topics/test-servers topics/advanced-usage topics/voice-calls diff --git a/docs/source/start/invoking.rst b/docs/source/start/invoking.rst index 1357cd7b..5cb6817b 100644 --- a/docs/source/start/invoking.rst +++ b/docs/source/start/invoking.rst @@ -24,40 +24,40 @@ Making API method calls with Pyrogram is very simple. Here's an example we are g app.stop() -Let's begin by importing the Client class from the Pyrogram package: +#. Let's begin by importing the Client class from the Pyrogram package: -.. code-block:: python + .. code-block:: python - from pyrogram import Client + from pyrogram import Client -Now instantiate a new Client object, "my_account" is a session name of your choice: +#. Now instantiate a new Client object, "my_account" is a session name of your choice: -.. code-block:: python + .. code-block:: python - app = Client("my_account") + app = Client("my_account") -To actually make use of any method, the client has to be started first: +#. To actually make use of any method, the client has to be started first: -.. code-block:: python + .. code-block:: python - app.start() + app.start() -Now, you can call any method you like: +#. Now, you can call any method you like: -.. code-block:: python + .. code-block:: python - print(app.get_me()) # Print information about yourself + print(app.get_me()) # Print information about yourself - # Send messages to yourself: - app.send_message("me", "Hi!") # Text message - app.send_location("me", 51.500729, -0.124583) # Location - app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") # Sticker + # Send messages to yourself: + app.send_message("me", "Hi!") # Text message + app.send_location("me", 51.500729, -0.124583) # Location + app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") # Sticker -Finally, when done, simply stop the client: +#. Finally, when done, simply stop the client: -.. code-block:: python + .. code-block:: python - app.stop() + app.stop() Context Manager --------------- diff --git a/docs/source/start/updates.rst b/docs/source/start/updates.rst index b6838ad3..9ac428b3 100644 --- a/docs/source/start/updates.rst +++ b/docs/source/start/updates.rst @@ -45,36 +45,37 @@ arrives: app.run() -Let's examine these four new pieces. First one: a callback function we defined which accepts two arguments - -*(client, message)*. This will be the function that gets executed every time a new message arrives and Pyrogram will -call that function by passing the client instance and the new message instance as argument. +#. Let's examine these four new pieces. First one: a callback function we defined which accepts two arguments - + *(client, message)*. This will be the function that gets executed every time a new message arrives and Pyrogram will + call that function by passing the client instance and the new message instance as argument. -.. code-block:: python + .. code-block:: python - def my_function(client, message): - print(message) + def my_function(client, message): + print(message) -Second one: the :class:`~pyrogram.MessageHandler`. This object tells Pyrogram the function we defined above must only -handle updates that are in form of a :class:`~pyrogram.Message`: +#. Second one: the :class:`~pyrogram.MessageHandler`. This object tells Pyrogram the function we defined above must + only handle updates that are in form of a :class:`~pyrogram.Message`: -.. code-block:: python + .. code-block:: python - my_handler = MessageHandler(my_function) + my_handler = MessageHandler(my_function) -Third: the method :meth:`~pyrogram.Client.add_handler`. This method is used to actually register the handler and let -Pyrogram know it needs to be taken into consideration when new updates arrive and the internal dispatching phase begins. +#. Third: the method :meth:`~pyrogram.Client.add_handler`. This method is used to actually register the handler and let + Pyrogram know it needs to be taken into consideration when new updates arrive and the internal dispatching phase + begins. -.. code-block:: python + .. code-block:: python - app.add_handler(my_handler) + app.add_handler(my_handler) -Last one, the :meth:`~pyrogram.Client.run` method. What this does is simply call :meth:`~pyrogram.Client.start` and a -special method :meth:`~pyrogram.Client.idle` that keeps your main scripts alive until you press ``CTRL+C``; the client -will be automatically stopped after that. +#. Last one, the :meth:`~pyrogram.Client.run` method. What this does is simply call :meth:`~pyrogram.Client.start` and + a special method :meth:`~pyrogram.Client.idle` that keeps your main scripts alive until you press ``CTRL+C``; the + client will be automatically stopped after that. -.. code-block:: python + .. code-block:: python - app.run() + app.run() Using Decorators ---------------- diff --git a/docs/source/topics/create-filters.rst b/docs/source/topics/create-filters.rst new file mode 100644 index 00000000..0252221c --- /dev/null +++ b/docs/source/topics/create-filters.rst @@ -0,0 +1,92 @@ +Creating Filters +================ + +Pyrogram already provides lots of built-in :class:`~pyrogram.Filters` to work with, but in case you can't find +a specific one for your needs or want to build a custom filter by yourself (to be used in a different kind of handler, +for example) you can use :meth:`~pyrogram.Filters.create`. + +.. note:: + + At the moment, the built-in filters are intended to be used with the :class:`~pyrogram.MessageHandler` only. + +Custom Filters +-------------- + +An example to demonstrate how custom filters work is to show how to create and use one for the +:class:`~pyrogram.CallbackQueryHandler`. Note that callback queries updates are only received by bots; create and +:doc:`authorize your bot <../start/auth>`, then send a message with an inline keyboard to yourself. This allows you to +test your filter by pressing the inline button: + +.. code-block:: python + + from pyrogram import InlineKeyboardMarkup, InlineKeyboardButton + + app.send_message( + "username", # Change this to your username or id + "Pyrogram's custom filter test", + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Press me", b"pyrogram")]] + ) + ) + +Basic Filters +------------- + +For this basic filter we will be using only the first two parameters of :meth:`~pyrogram.Filters.create`. + +The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries +containing "Pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data +equals to ``b"Pyrogram"``. + +.. code-block:: python + + static_data = Filters.create( + name="StaticdData", + func=lambda flt, callback_query: callback_query.data == b"Pyrogram" + ) + +The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same +could be achieved with a normal function, but we don't really need it as it makes sense only inside the filter's scope: + +.. code-block:: python + + def func(flt, callback_query): + return callback_query.data == b"Pyrogram" + + static_data = Filters.create( + name="StaticData", + func=func + ) + +The filter usage remains the same: + +.. code-block:: python + + @app.on_callback_query(static_data) + def pyrogram_data(client, callback_query): + client.answer_callback_query(callback_query.id, "it works!") + +Filters with Arguments +---------------------- + +A much cooler filter would be one that accepts "Pyrogram" or any other data as argument at usage time. +A dynamic filter like this will make use of the third parameter of :meth:`~pyrogram.Filters.create`. + +This is how a dynamic custom filter looks like: + +.. code-block:: python + + def dynamic_data(data): + return Filters.create( + name="DynamicData", + func=lambda flt, callback_query: flt.data == callback_query.data, + data=data # "data" kwarg is accessed with "filter.data" + ) + +And its usage: + +.. code-block:: python + + @app.on_callback_query(dynamic_data(b"Pyrogram")) + def pyrogram_data(client, callback_query): + client.answer_callback_query(callback_query.id, "it works!") \ No newline at end of file diff --git a/docs/source/topics/debugging.rst b/docs/source/topics/debugging.rst new file mode 100644 index 00000000..153c0927 --- /dev/null +++ b/docs/source/topics/debugging.rst @@ -0,0 +1,135 @@ +Debugging +========= + +When working with the API, chances are you'll stumble upon bugs, get stuck and start wondering how to continue. Nothing +to actually worry about -- that's normal -- and luckily for you, Pyrogram provides some commodities to help you in this. + +Caveman Debugging +----------------- + + *The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.* + + -- Brian Kernighan, "Unix for Beginners" (1979) + +Adding ``print()`` statements in crucial parts of your code is by far the most ancient, yet efficient technique for +debugging programs, especially considering the concurrent nature of the framework itself. Pyrogram goodness in this +respect comes with the fact that any object can be nicely printed just by calling ``print(obj)``, thus giving to you +an insight of all its inner details. + +Consider the following code: + +.. code-block:: python + + dan = app.get_users("haskell") + print(dan) # User + +This will show a JSON representation of the object returned by :meth:`~pyrogram.Client.get_users`, which is a +:class:`~pyrogram.User` instance, in this case. The output on your terminal will be something similar to this: + +.. code-block:: json + + { + "_": "pyrogram.User", + "id": 23122162, + "is_self": false, + "is_contact": false, + "is_mutual_contact": false, + "is_deleted": false, + "is_bot": false, + "is_verified": false, + "is_restricted": false, + "is_support": false, + "is_scam": false, + "first_name": "Dan", + "status": { + "_": "pyrogram.UserStatus", + "user_id": 23122162, + "recently": true + }, + "username": "haskell", + "language_code": "en", + "photo": { + "_": "pyrogram.ChatPhoto", + "small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC", + "big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg" + } + } + +As you've probably guessed already, Pyrogram objects can be nested. That's how compound data are built, and nesting +keeps going until we are left with base data types only, such as ``str``, ``int``, ``bool``, etc. + +Accessing Attributes +-------------------- + +Even though you see a JSON output, it doesn't mean we are dealing with dictionaries; in fact, all Pyrogram types are +full-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``: + +.. code-block:: python + + dan_photo = dan.photo + print(dan_photo) # ChatPhoto + +.. code-block:: json + + { + "_": "pyrogram.ChatPhoto", + "small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC", + "big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg" + } + +However, the bracket notation ``[]`` is also supported, but its usage is discouraged: + +.. warning:: + + Bracket notation in Python is not commonly used for getting/setting object attributes. While it works for Pyrogram + objects, it might not work for anything else and you should not rely on this. + +.. code-block:: python + + dan_photo_big = dan["photo"]["big_file_id"] + print(dan_photo_big) # str + +.. code-block:: text + + AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg + +Checking an Object's Type +------------------------- + +Another thing worth talking about is how to tell and check for an object's type. + +As you noticed already, when printing an object you'll see the special attribute ``"_"``. This is just a visual thing +useful to show humans the object type, but doesn't really exist anywhere; any attempt in accessing it will lead to an +error. The correct way to get the object type is by using the built-in function ``type()``: + +.. code-block:: python + + dan_status = dan.status + print(type(dan_status)) + +.. code-block:: text + + + +And to check if an object is an instance of a given class, you use the built-in function ``isinstance()``: + +.. code-block:: python + :name: this-py + + from pyrogram import UserStatus + + dan_status = dan.status + print(isinstance(dan_status, UserStatus)) + +.. code-block:: text + + True + +.. raw:: html + + \ No newline at end of file diff --git a/docs/source/topics/filters.rst b/docs/source/topics/use-filters.rst similarity index 50% rename from docs/source/topics/filters.rst rename to docs/source/topics/use-filters.rst index 7ff02ffc..c23a98df 100644 --- a/docs/source/topics/filters.rst +++ b/docs/source/topics/use-filters.rst @@ -105,93 +105,3 @@ More handlers using different filters can also live together. @app.on_message(Filters.chat("PyrogramChat")) def from_pyrogramchat(client, message): print("New message in @PyrogramChat") - -Custom Filters --------------- - -Pyrogram already provides lots of built-in :class:`~pyrogram.Filters` to work with, but in case you can't find -a specific one for your needs or want to build a custom filter by yourself (to be used in a different kind of handler, -for example) you can use :meth:`~pyrogram.Filters.create`. - -.. note:: - - At the moment, the built-in filters are intended to be used with the :class:`~pyrogram.MessageHandler` only. - -An example to demonstrate how custom filters work is to show how to create and use one for the -:class:`~pyrogram.CallbackQueryHandler`. Note that callback queries updates are only received by bots; create and -:doc:`authorize your bot <../start/auth>`, then send a message with an inline keyboard to yourself. This allows you to -test your filter by pressing the inline button: - -.. code-block:: python - - from pyrogram import InlineKeyboardMarkup, InlineKeyboardButton - - app.send_message( - "username", # Change this to your username or id - "Pyrogram's custom filter test", - reply_markup=InlineKeyboardMarkup( - [[InlineKeyboardButton("Press me", b"pyrogram")]] - ) - ) - -Basic Filters -^^^^^^^^^^^^^ - -For this basic filter we will be using only the first two parameters of :meth:`~pyrogram.Filters.create`. - -The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries -containing "Pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data -equals to ``b"Pyrogram"``. - -.. code-block:: python - - static_data = Filters.create( - name="StaticdData", - func=lambda flt, callback_query: callback_query.data == b"Pyrogram" - ) - -The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same -could be achieved with a normal function, but we don't really need it as it makes sense only inside the filter's scope: - -.. code-block:: python - - def func(flt, callback_query): - return callback_query.data == b"Pyrogram" - - static_data = Filters.create( - name="StaticData", - func=func - ) - -The filter usage remains the same: - -.. code-block:: python - - @app.on_callback_query(static_data) - def pyrogram_data(client, callback_query): - client.answer_callback_query(callback_query.id, "it works!") - -Filters with Arguments -^^^^^^^^^^^^^^^^^^^^^^ - -A much cooler filter would be one that accepts "Pyrogram" or any other data as argument at usage time. -A dynamic filter like this will make use of the third parameter of :meth:`~pyrogram.Filters.create`. - -This is how a dynamic custom filter looks like: - -.. code-block:: python - - def dynamic_data(data): - return Filters.create( - name="DynamicData", - func=lambda flt, callback_query: flt.data == callback_query.data, - data=data # "data" kwarg is accessed with "filter.data" - ) - -And its usage: - -.. code-block:: python - - @app.on_callback_query(dynamic_data(b"Pyrogram")) - def pyrogram_data(client, callback_query): - client.answer_callback_query(callback_query.id, "it works!") \ No newline at end of file From 896c9fa4fdd76e3897704c2b33894d8ca667ba5a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 4 Jun 2019 16:32:42 +0200 Subject: [PATCH 138/202] Add "unsave" parameter to send_animation --- .../client/methods/messages/send_animation.py | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/methods/messages/send_animation.py b/pyrogram/client/methods/messages/send_animation.py index 8a4ec7bd..0c4649dd 100644 --- a/pyrogram/client/methods/messages/send_animation.py +++ b/pyrogram/client/methods/messages/send_animation.py @@ -31,6 +31,7 @@ class SendAnimation(BaseClient): chat_id: Union[int, str], animation: str, caption: str = "", + unsave: bool = False, parse_mode: str = "", duration: int = 0, width: int = 0, @@ -64,6 +65,10 @@ class SendAnimation(BaseClient): caption (``str``, *optional*): Animation caption, 0-1024 characters. + unsave (``bool``, *optional*): + By default, the server will save into your own collection any new animation GIF you send. + Pass True to automatically unsave the sent animation. Defaults to False. + parse_mode (``str``, *optional*): Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your caption. Defaults to "markdown". @@ -171,10 +176,24 @@ class SendAnimation(BaseClient): else: for i in r.updates: if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): - return pyrogram.Message._parse( + message = pyrogram.Message._parse( self, i.message, {i.id: i for i in r.users}, {i.id: i for i in r.chats} ) + + if unsave: + document = message.animation or message.document + document_id = utils.get_input_media_from_file_id(document.file_id).id + + self.send( + functions.messages.SaveGif( + id=document_id, + unsave=True + ) + ) + + return message + except BaseClient.StopTransmission: return None From 806e0d79ec6459d3b6f649f20cfe221f397d5a13 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 4 Jun 2019 19:11:40 +0200 Subject: [PATCH 139/202] Tiny fixup --- docs/source/topics/advanced-usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/topics/advanced-usage.rst b/docs/source/topics/advanced-usage.rst index 41eee961..ff1afa5c 100644 --- a/docs/source/topics/advanced-usage.rst +++ b/docs/source/topics/advanced-usage.rst @@ -122,7 +122,7 @@ For example, given the ID *123456789*, here's how Pyrogram can tell entities apa - ``+ID`` User: *123456789* - ``-ID`` Chat: *-123456789* - - ``-100ID`` Channel (and Supergroup): *-100123456789* + - ``-100ID`` Channel or Supergroup: *-100123456789* So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an high-level method. From a425e00a96a9f27f7ad9218cbeab5ed7a1a8c120 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 4 Jun 2019 19:16:30 +0200 Subject: [PATCH 140/202] Add read_history method --- docs/source/api/methods.rst | 2 + pyrogram/client/methods/messages/__init__.py | 4 +- .../client/methods/messages/read_history.py | 65 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 pyrogram/client/methods/messages/read_history.py diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index b9fa180c..ed150e4c 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -67,6 +67,7 @@ Messages - :meth:`~Client.get_messages` - :meth:`~Client.get_history` - :meth:`~Client.get_history_count` + - :meth:`~Client.read_history` - :meth:`~Client.iter_history` - :meth:`~Client.send_poll` - :meth:`~Client.vote_poll` @@ -200,6 +201,7 @@ Details .. automethod:: Client.get_messages() .. automethod:: Client.get_history() .. automethod:: Client.get_history_count() +.. automethod:: Client.read_history() .. automethod:: Client.iter_history() .. automethod:: Client.send_poll() .. automethod:: Client.vote_poll() diff --git a/pyrogram/client/methods/messages/__init__.py b/pyrogram/client/methods/messages/__init__.py index 9ed6e33b..07df7a64 100644 --- a/pyrogram/client/methods/messages/__init__.py +++ b/pyrogram/client/methods/messages/__init__.py @@ -27,6 +27,7 @@ from .get_history import GetHistory from .get_history_count import GetHistoryCount from .get_messages import GetMessages from .iter_history import IterHistory +from .read_history import ReadHistory from .retract_vote import RetractVote from .send_animated_sticker import SendAnimatedSticker from .send_animation import SendAnimation @@ -80,6 +81,7 @@ class Messages( IterHistory, SendCachedMedia, GetHistoryCount, - SendAnimatedSticker + SendAnimatedSticker, + ReadHistory ): pass diff --git a/pyrogram/client/methods/messages/read_history.py b/pyrogram/client/methods/messages/read_history.py new file mode 100644 index 00000000..f0278e91 --- /dev/null +++ b/pyrogram/client/methods/messages/read_history.py @@ -0,0 +1,65 @@ +# 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 typing import Union + +from pyrogram.api import functions, types +from ...ext import BaseClient + + +class ReadHistory(BaseClient): + def read_history( + self, + chat_id: Union[int, str], + max_id: int = 0 + ) -> bool: + """Mark a chat's message history as read. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For your personal cloud (Saved Messages) you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + max_id (``int``, *optional*): + The id of the last message you want to mark as read; all the messages before this one will be marked as + read as well. Defaults to 0 (mark every unread message as read). + + Returns: + ``bool`` - On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + peer = self.resolve_peer(chat_id) + + if isinstance(peer, types.InputPeerChannel): + q = functions.channels.ReadHistory( + channel=peer, + max_id=max_id + ) + else: + q = functions.messages.ReadHistory( + peer=peer, + max_id=max_id + ) + + self.send(q) + + return True From a35e2620f867678935d76b65e1961caf35fc0ecf Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 4 Jun 2019 23:36:10 +0200 Subject: [PATCH 141/202] Fix export_chat_invite_link for basic groups in Layer 100 --- compiler/api/source/main_api.tl | 5 ++++- pyrogram/client/methods/chats/export_chat_invite_link.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/api/source/main_api.tl b/compiler/api/source/main_api.tl index 43b02e80..16a93420 100644 --- a/compiler/api/source/main_api.tl +++ b/compiler/api/source/main_api.tl @@ -1356,4 +1356,7 @@ langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLangua folders.editPeerFolders#6847d0ab folder_peers:Vector = Updates; folders.deleteFolder#1c295881 folder_id:int = Updates; -// LAYER 100 \ No newline at end of file +// LAYER 100 + +// Ports +channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite; \ No newline at end of file diff --git a/pyrogram/client/methods/chats/export_chat_invite_link.py b/pyrogram/client/methods/chats/export_chat_invite_link.py index 26263d53..9266183d 100644 --- a/pyrogram/client/methods/chats/export_chat_invite_link.py +++ b/pyrogram/client/methods/chats/export_chat_invite_link.py @@ -54,7 +54,7 @@ class ExportChatInviteLink(BaseClient): if isinstance(peer, types.InputPeerChat): return self.send( functions.messages.ExportChatInvite( - peer=peer.chat_id + peer=peer ) ).link elif isinstance(peer, types.InputPeerChannel): From 0ea512bbc3f672686da3cd562013def18df344ae Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 5 Jun 2019 11:05:01 +0200 Subject: [PATCH 142/202] Update docs: add release notes from GitHub --- docs/releases.py | 80 ++++++++++++++++++++++++++ docs/source/conf.py | 2 +- docs/source/index.rst | 4 +- docs/source/releases.rst | 13 ----- docs/source/topics/more-on-updates.rst | 2 +- 5 files changed, 84 insertions(+), 17 deletions(-) create mode 100644 docs/releases.py delete mode 100644 docs/source/releases.rst diff --git a/docs/releases.py b/docs/releases.py new file mode 100644 index 00000000..98563ccd --- /dev/null +++ b/docs/releases.py @@ -0,0 +1,80 @@ +# 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 . + +import shutil +from datetime import datetime +from pathlib import Path + +import pypandoc +import requests + +URL = "https://api.github.com/repos/pyrogram/pyrogram/releases" +DEST = Path("source/releases") +INTRO = """ +Release Notes +============= + +Release notes for Pyrogram releases will describe what's new in each version, and will also make you aware of any +backwards-incompatible changes made in that version. + +When upgrading to a new version of Pyrogram, you will need to check all the breaking changes in order to find +incompatible code in your application, but also to take advantage of new features and improvements. + +Releases +-------- + +""".lstrip("\n") + +shutil.rmtree(DEST, ignore_errors=True) +DEST.mkdir(parents=True) + +releases = requests.get(URL).json() + +with open(DEST / "index.rst", "w") as index: + index.write(INTRO) + + tags = [] + + for release in releases: + tag = release["tag_name"] + title = release["name"] + name = title.split(" - ")[1] + + date = datetime.strptime( + release["published_at"], + "%Y-%m-%dT%H:%M:%SZ" + ).strftime("%b %d, %Y - %H:%M:%S (UTC)") + + body = pypandoc.convert_text( + release["body"].replace(r"\r\n", "\n"), + "rst", + format="markdown_github", + extra_args=["--wrap=none"] + ) + + index.write("- :doc:`{} <{}>`\n".format(title, tag)) + tags.append(tag) + + with open(DEST / "{}.rst".format(tag), "w") as page: + page.write("Pyrogram " + tag + "\n" + "=" * (len(tag) + 9) + "\n\n") + page.write("--- *Released on " + str(date) + "*\n\n") + page.write(name + "\n" + "-" * len(name) + "\n\n") + page.write(body + "\n\n") + + index.write("\n.. toctree::\n :hidden:\n\n") + index.write("\n".join(" {}".format(tag) for tag in tags)) diff --git a/docs/source/conf.py b/docs/source/conf.py index 7ddeaa94..01fbe6de 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -58,7 +58,7 @@ html_show_copyright = False html_theme_options = { "canonical_url": "https://docs.pyrogram.org/", "collapse_navigation": True, - "sticky_navigation": False, + "sticky_navigation": True, "logo_only": True, "display_version": True, "style_external_links": True diff --git a/docs/source/index.rst b/docs/source/index.rst index 12ac705b..a2e08cd0 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -83,10 +83,10 @@ Meta - :doc:`Pyrogram FAQ `: Answers to common Pyrogram questions. - :doc:`Pyrogram Glossary `: List of words with brief explanations. - - :doc:`Release Notes `: Release notes for Pyrogram releases. - :doc:`Powered by Pyrogram `: Collection of Pyrogram Projects. - :doc:`Support Pyrogram `: Ways to show your appreciation. - :doc:`About the License `: Information about the Project license. + - :doc:`Release Notes `: Release notes for Pyrogram releases. .. toctree:: :hidden: @@ -146,10 +146,10 @@ Meta faq glossary - releases powered-by support-pyrogram license + releases/index .. toctree:: :hidden: diff --git a/docs/source/releases.rst b/docs/source/releases.rst deleted file mode 100644 index 6c3b5b75..00000000 --- a/docs/source/releases.rst +++ /dev/null @@ -1,13 +0,0 @@ -Release Notes -============= - -Release notes for Pyrogram releases will describe what's new in each version, and will also make you aware of any -backwards-incompatible changes made in that version. - -When upgrading to a new version of Pyrogram, you will need to check all the breaking changes in order to find -incompatible code in your application, but also to take advantage of new features and improvements. - -.. note:: - - Currently, all Pyrogram release notes live inside the GitHub repository web page: - https://github.com/pyrogram/pyrogram/releases. diff --git a/docs/source/topics/more-on-updates.rst b/docs/source/topics/more-on-updates.rst index c3737b38..df0aff7d 100644 --- a/docs/source/topics/more-on-updates.rst +++ b/docs/source/topics/more-on-updates.rst @@ -2,7 +2,7 @@ More on Updates =============== Here we'll show some advanced usages when working with :doc:`update handlers <../start/updates>` and -:doc:`filters `. +:doc:`filters `. Handler Groups -------------- From 17ddb0d1b7f172d6f032fd08ae474b421c7cb38d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 5 Jun 2019 13:58:32 +0200 Subject: [PATCH 143/202] Update get_chat_member docstrings --- pyrogram/client/methods/chats/get_chat_member.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/methods/chats/get_chat_member.py b/pyrogram/client/methods/chats/get_chat_member.py index c77e46b6..4deab9ec 100644 --- a/pyrogram/client/methods/chats/get_chat_member.py +++ b/pyrogram/client/methods/chats/get_chat_member.py @@ -37,8 +37,8 @@ class GetChatMember(BaseClient): Unique identifier (int) or username (str) of the target chat. user_id (``int`` | ``str``):: - Unique identifier (int) or username (str) of the target chat. - For your personal cloud (Saved Messages) you can simply use "me" or "self". + Unique identifier (int) or username (str) of the target user. + For you yourself you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). Returns: From 6bebe2297ee8852b7fada2915c12386a9cfb9bac Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 5 Jun 2019 21:03:46 +0200 Subject: [PATCH 144/202] Rename "thumbnails" to "thumbs" --- .../client/types/messages_and_media/animation.py | 10 +++++----- pyrogram/client/types/messages_and_media/audio.py | 10 +++++----- pyrogram/client/types/messages_and_media/document.py | 10 +++++----- pyrogram/client/types/messages_and_media/photo.py | 12 ++++++------ pyrogram/client/types/messages_and_media/sticker.py | 10 +++++----- pyrogram/client/types/messages_and_media/video.py | 10 +++++----- .../client/types/messages_and_media/video_note.py | 10 +++++----- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index 0dfbed17..2a9c9e66 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -54,11 +54,11 @@ class Animation(Object): date (``int``, *optional*): Date the animation was sent in Unix time. - thumbnails (List of :obj:`Thumbnail`, *optional*): + thumbs (List of :obj:`Thumbnail`, *optional*): Animation thumbnails. """ - __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "duration", "thumbnails"] + __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "duration", "thumbs"] def __init__( self, @@ -72,7 +72,7 @@ class Animation(Object): mime_type: str = None, file_size: int = None, date: int = None, - thumbnails: List[Thumbnail] = None, + thumbs: List[Thumbnail] = None, ): super().__init__(client) @@ -84,7 +84,7 @@ class Animation(Object): self.width = width self.height = height self.duration = duration - self.thumbnails = thumbnails + self.thumbs = thumbs @staticmethod def _parse( @@ -110,6 +110,6 @@ class Animation(Object): file_size=animation.size, file_name=file_name, date=animation.date, - thumbnails=Thumbnail._parse(client, animation), + thumbs=Thumbnail._parse(client, animation), client=client ) diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index 64e450f4..d6324e83 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -54,12 +54,12 @@ class Audio(Object): title (``str``, *optional*): Title of the audio as defined by sender or by audio tags. - thumbnails (List of :obj:`Thumbnail`, *optional*): + thumbs (List of :obj:`Thumbnail`, *optional*): Thumbnails of the music file album cover. """ __slots__ = [ - "file_id", "file_name", "mime_type", "file_size", "date", "duration", "performer", "title", "thumbnails" + "file_id", "file_name", "mime_type", "file_size", "date", "duration", "performer", "title", "thumbs" ] def __init__( @@ -74,7 +74,7 @@ class Audio(Object): date: int = None, performer: str = None, title: str = None, - thumbnails: List[Thumbnail] = None, + thumbs: List[Thumbnail] = None, ): super().__init__(client) @@ -86,7 +86,7 @@ class Audio(Object): self.duration = duration self.performer = performer self.title = title - self.thumbnails = thumbnails + self.thumbs = thumbs @staticmethod def _parse( @@ -112,6 +112,6 @@ class Audio(Object): file_size=audio.size, file_name=file_name, date=audio.date, - thumbnails=Thumbnail._parse(client, audio), + thumbs=Thumbnail._parse(client, audio), client=client ) diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index ad48a847..023e4204 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -45,11 +45,11 @@ class Document(Object): date (``int``, *optional*): Date the document was sent in Unix time. - thumbnails (List of :obj:`Thumbnail`, *optional*): + thumbs (List of :obj:`Thumbnail`, *optional*): Document thumbnails as defined by sender. """ - __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "thumbnails"] + __slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "thumbs"] def __init__( self, @@ -60,7 +60,7 @@ class Document(Object): mime_type: str = None, file_size: int = None, date: int = None, - thumbnails: List[Thumbnail] = None, + thumbs: List[Thumbnail] = None, ): super().__init__(client) @@ -69,7 +69,7 @@ class Document(Object): self.mime_type = mime_type self.file_size = file_size self.date = date - self.thumbnails = thumbnails + self.thumbs = thumbs @staticmethod def _parse(client, document: types.Document, file_name: str) -> "Document": @@ -87,6 +87,6 @@ class Document(Object): mime_type=document.mime_type, file_size=document.size, date=document.date, - thumbnails=Thumbnail._parse(client, document), + thumbs=Thumbnail._parse(client, document), client=client ) diff --git a/pyrogram/client/types/messages_and_media/photo.py b/pyrogram/client/types/messages_and_media/photo.py index b5d80b82..653fe4c0 100644 --- a/pyrogram/client/types/messages_and_media/photo.py +++ b/pyrogram/client/types/messages_and_media/photo.py @@ -45,11 +45,11 @@ class Photo(Object): date (``int``): Date the photo was sent in Unix time. - thumbnails (List of :obj:`Thumbnail`): - Available sizes of this photo. + thumbs (List of :obj:`Thumbnail`, *optional*): + Available thumbnails of this photo. """ - __slots__ = ["file_id", "width", "height", "file_size", "date", "thumbnails"] + __slots__ = ["file_id", "width", "height", "file_size", "date", "thumbs"] def __init__( self, @@ -60,7 +60,7 @@ class Photo(Object): height: int, file_size: int, date: int, - thumbnails: List[Thumbnail] + thumbs: List[Thumbnail] ): super().__init__(client) @@ -69,7 +69,7 @@ class Photo(Object): self.height = height self.file_size = file_size self.date = date - self.thumbnails = thumbnails + self.thumbs = thumbs @staticmethod def _parse(client, photo: types.Photo) -> "Photo": @@ -89,6 +89,6 @@ class Photo(Object): height=big.h, file_size=big.size, date=photo.date, - thumbnails=Thumbnail._parse(client, photo), + thumbs=Thumbnail._parse(client, photo), client=client ) diff --git a/pyrogram/client/types/messages_and_media/sticker.py b/pyrogram/client/types/messages_and_media/sticker.py index 9e528dd8..3c171543 100644 --- a/pyrogram/client/types/messages_and_media/sticker.py +++ b/pyrogram/client/types/messages_and_media/sticker.py @@ -59,14 +59,14 @@ class Sticker(Object): set_name (``str``, *optional*): Name of the sticker set to which the sticker belongs. - thumbnails (List of :obj:`Thumbnail`, *optional*): + thumbs (List of :obj:`Thumbnail`, *optional*): Sticker thumbnails in the .webp or .jpg format. """ # TODO: Add mask position __slots__ = [ - "file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "emoji", "set_name", "thumbnails" + "file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "emoji", "set_name", "thumbs" ] def __init__( @@ -82,7 +82,7 @@ class Sticker(Object): date: int = None, emoji: str = None, set_name: str = None, - thumbnails: List[Thumbnail] = None + thumbs: List[Thumbnail] = None ): super().__init__(client) @@ -95,7 +95,7 @@ class Sticker(Object): self.height = height self.emoji = emoji self.set_name = set_name, - self.thumbnails = thumbnails + self.thumbs = thumbs # self.mask_position = mask_position @staticmethod @@ -143,6 +143,6 @@ class Sticker(Object): mime_type=sticker.mime_type, file_name=file_name, date=sticker.date, - thumbnails=Thumbnail._parse(client, sticker), + thumbs=Thumbnail._parse(client, sticker), client=client ) diff --git a/pyrogram/client/types/messages_and_media/video.py b/pyrogram/client/types/messages_and_media/video.py index feda9711..0a7f47cd 100644 --- a/pyrogram/client/types/messages_and_media/video.py +++ b/pyrogram/client/types/messages_and_media/video.py @@ -57,13 +57,13 @@ class Video(Object): date (``int``, *optional*): Date the video was sent in Unix time. - thumbnails (List of :obj:`Thumbnail`, *optional*): + thumbs (List of :obj:`Thumbnail`, *optional*): Video thumbnails. """ __slots__ = [ "file_id", "width", "height", "duration", "file_name", "mime_type", "supports_streaming", "file_size", "date", - "thumbnails" + "thumbs" ] def __init__( @@ -79,7 +79,7 @@ class Video(Object): supports_streaming: bool = None, file_size: int = None, date: int = None, - thumbnails: List[Thumbnail] = None + thumbs: List[Thumbnail] = None ): super().__init__(client) @@ -92,7 +92,7 @@ class Video(Object): self.supports_streaming = supports_streaming self.file_size = file_size self.date = date - self.thumbnails = thumbnails + self.thumbs = thumbs @staticmethod def _parse( @@ -119,6 +119,6 @@ class Video(Object): supports_streaming=video_attributes.supports_streaming, file_size=video.size, date=video.date, - thumbnails=Thumbnail._parse(client, video), + thumbs=Thumbnail._parse(client, video), client=client ) diff --git a/pyrogram/client/types/messages_and_media/video_note.py b/pyrogram/client/types/messages_and_media/video_note.py index b1d9bcdb..54c9ec8d 100644 --- a/pyrogram/client/types/messages_and_media/video_note.py +++ b/pyrogram/client/types/messages_and_media/video_note.py @@ -48,11 +48,11 @@ class VideoNote(Object): date (``int``, *optional*): Date the video note was sent in Unix time. - thumbnails (List of :obj:`Thumbnail`, *optional*): + thumbs (List of :obj:`Thumbnail`, *optional*): Video thumbnails. """ - __slots__ = ["file_id", "mime_type", "file_size", "date", "length", "duration", "thumbnails"] + __slots__ = ["file_id", "mime_type", "file_size", "date", "length", "duration", "thumbs"] def __init__( self, @@ -61,7 +61,7 @@ class VideoNote(Object): file_id: str, length: int, duration: int, - thumbnails: List[Thumbnail] = None, + thumbs: List[Thumbnail] = None, mime_type: str = None, file_size: int = None, date: int = None @@ -74,7 +74,7 @@ class VideoNote(Object): self.date = date self.length = length self.duration = duration - self.thumbnails = thumbnails + self.thumbs = thumbs @staticmethod def _parse(client, video_note: types.Document, video_attributes: types.DocumentAttributeVideo) -> "VideoNote": @@ -93,6 +93,6 @@ class VideoNote(Object): file_size=video_note.size, mime_type=video_note.mime_type, date=video_note.date, - thumbnails=Thumbnail._parse(client, video_note), + thumbs=Thumbnail._parse(client, video_note), client=client ) From 8151270a94df19eb5e40f7d93fd1975185adb201 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 6 Jun 2019 18:25:23 +0200 Subject: [PATCH 145/202] Update docs --- docs/releases.py | 9 +++++++-- docs/source/faq.rst | 2 +- docs/source/index.rst | 4 ++-- docs/source/start/auth.rst | 4 ++-- pyrogram/client/types/inline_mode/inline_query_result.py | 2 +- .../types/input_message_content/input_message_content.py | 2 +- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/docs/releases.py b/docs/releases.py index 98563ccd..0c284f0b 100644 --- a/docs/releases.py +++ b/docs/releases.py @@ -58,7 +58,7 @@ with open(DEST / "index.rst", "w") as index: date = datetime.strptime( release["published_at"], "%Y-%m-%dT%H:%M:%SZ" - ).strftime("%b %d, %Y - %H:%M:%S (UTC)") + ).strftime("%b %d, %Y") body = pypandoc.convert_text( release["body"].replace(r"\r\n", "\n"), @@ -67,12 +67,17 @@ with open(DEST / "index.rst", "w") as index: extra_args=["--wrap=none"] ) + tarball_url = release["tarball_url"] + zipball_url = release["zipball_url"] + index.write("- :doc:`{} <{}>`\n".format(title, tag)) tags.append(tag) with open(DEST / "{}.rst".format(tag), "w") as page: page.write("Pyrogram " + tag + "\n" + "=" * (len(tag) + 9) + "\n\n") - page.write("--- *Released on " + str(date) + "*\n\n") + page.write("\t\tReleased on " + str(date) + "\n\n") + page.write("- :download:`Source Code (zip) <{}>`\n".format(zipball_url)) + page.write("- :download:`Source Code (tar.gz) <{}>`\n\n".format(tarball_url)) page.write(name + "\n" + "-" * len(name) + "\n\n") page.write(body + "\n\n") diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 6c3cc1ab..1800a032 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -197,7 +197,7 @@ And here's a good explanation of how, probably, the system works: data-width="100%"> -.. centered:: Join the discussion at `@PyrogramChat `_ +.. centered:: Join the discussion at `@Pyrogram `_ However, you might be right, and your account was deactivated/limited without any good reason. This could happen because of mistakes by either the automatic systems or a moderator. In such cases you can kindly email Telegram at diff --git a/docs/source/index.rst b/docs/source/index.rst index a2e08cd0..0bc175ee 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -50,8 +50,8 @@ How the Documentation is Organized ---------------------------------- Contents are organized into self-contained topics and can be all accessed from the sidebar, or by following them in -order using the Next button at the end of each page. Here below you can, instead, find a list of the most relevant -pages for a quick access. +order using the :guilabel:`Next` button at the end of each page. Here below you can, instead, find a list of the most +relevant pages for a quick access. First Steps ----------- diff --git a/docs/source/start/auth.rst b/docs/source/start/auth.rst index 79264bfa..ca1ddd8f 100644 --- a/docs/source/start/auth.rst +++ b/docs/source/start/auth.rst @@ -39,8 +39,8 @@ keep the session alive, Pyrogram won't ask you again to enter your phone number. .. note:: - The code above does nothing except asking for credentials and keeping the client online, hit ``CTRL+C`` now to stop - your application and keep reading. + The code above does nothing except asking for credentials and keeping the client online, hit :guilabel:`CTRL+C` now + to stop your application and keep reading. Bot Authorization ----------------- diff --git a/pyrogram/client/types/inline_mode/inline_query_result.py b/pyrogram/client/types/inline_mode/inline_query_result.py index 74fe77d3..3fc70885 100644 --- a/pyrogram/client/types/inline_mode/inline_query_result.py +++ b/pyrogram/client/types/inline_mode/inline_query_result.py @@ -42,7 +42,7 @@ from ..object import Object class InlineQueryResult(Object): """One result of an inline query. - Pyrogram currently supports results of the following 20 types: + Pyrogram currently supports results of the following types: - :obj:`InlineQueryResultArticle` """ 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 1941ffb5..fe11ef7a 100644 --- a/pyrogram/client/types/input_message_content/input_message_content.py +++ b/pyrogram/client/types/input_message_content/input_message_content.py @@ -26,7 +26,7 @@ from ..object import Object class InputMessageContent(Object): """Content of a message to be sent as a result of an inline query. - Pyrogram currently supports the following 4 types: + Pyrogram currently supports the following types: - :obj:`InputTextMessageContent` """ From b205c6cce08ef5866310b3572118d0b3866f3f31 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 6 Jun 2019 19:09:52 +0200 Subject: [PATCH 146/202] Rename Photos to ProfilePhotos --- docs/source/api/types.rst | 4 ++-- .../client/methods/users/get_profile_photos.py | 10 +++++----- .../client/types/messages_and_media/__init__.py | 5 +++-- .../{photos.py => profile_photos.py} | 16 ++++++++-------- 4 files changed, 18 insertions(+), 17 deletions(-) rename pyrogram/client/types/messages_and_media/{photos.py => profile_photos.py} (79%) diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 15f81ae7..4eef9638 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -45,7 +45,7 @@ Messages & Media - :class:`Messages` - :class:`MessageEntity` - :class:`Photo` - - :class:`Photos` + - :class:`ProfilePhotos` - :class:`Thumbnail` - :class:`Audio` - :class:`Document` @@ -133,7 +133,7 @@ Details .. autoclass:: Messages() .. autoclass:: MessageEntity() .. autoclass:: Photo() -.. autoclass:: Photos() +.. autoclass:: ProfilePhotos() .. autoclass:: Thumbnail() .. autoclass:: Audio() .. autoclass:: Document() diff --git a/pyrogram/client/methods/users/get_profile_photos.py b/pyrogram/client/methods/users/get_profile_photos.py index d45bd5b6..e4e202e0 100644 --- a/pyrogram/client/methods/users/get_profile_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -29,7 +29,7 @@ class GetProfilePhotos(BaseClient): chat_id: Union[int, str], offset: int = 0, limit: int = 100 - ) -> "pyrogram.Photos": + ) -> "pyrogram.ProfilePhotos": """Get a list of profile pictures for a user or a chat. Parameters: @@ -47,7 +47,7 @@ class GetProfilePhotos(BaseClient): Values between 1—100 are accepted. Defaults to 100. Returns: - :obj:`Photos`: On success, an object containing a list of the profile photos is returned. + :obj:`ProfilePhotos`: On success, an object containing a list of the profile photos is returned. Raises: RPCError: In case of a Telegram RPC error. @@ -55,7 +55,7 @@ class GetProfilePhotos(BaseClient): peer_id = self.resolve_peer(chat_id) if isinstance(peer_id, types.InputPeerUser): - return pyrogram.Photos._parse( + return pyrogram.ProfilePhotos._parse( self, self.send( functions.photos.GetUserPhotos( @@ -86,7 +86,7 @@ class GetProfilePhotos(BaseClient): ) ) - return pyrogram.Photos( + return pyrogram.ProfilePhotos( total_count=new_chat_photos.total_count, - photos=[m.new_chat_photo for m in new_chat_photos.messages][:limit] + profile_photos=[m.new_chat_photo for m in new_chat_photos.messages][:limit] ) diff --git a/pyrogram/client/types/messages_and_media/__init__.py b/pyrogram/client/types/messages_and_media/__init__.py index d312611b..17a6e36a 100644 --- a/pyrogram/client/types/messages_and_media/__init__.py +++ b/pyrogram/client/types/messages_and_media/__init__.py @@ -28,10 +28,10 @@ from .messages import Messages from .photo import Photo from .poll import Poll from .poll_option import PollOption +from .profile_photos import ProfilePhotos from .sticker import Sticker from .stripped_thumbnail import StrippedThumbnail from .thumbnail import Thumbnail -from .photos import Photos from .venue import Venue from .video import Video from .video_note import VideoNote @@ -39,5 +39,6 @@ from .voice import Voice __all__ = [ "Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Messages", "Photo", - "Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Photos", "Venue", "Video", "VideoNote", "Voice" + "Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "ProfilePhotos", "Venue", "Video", "VideoNote", + "Voice" ] diff --git a/pyrogram/client/types/messages_and_media/photos.py b/pyrogram/client/types/messages_and_media/profile_photos.py similarity index 79% rename from pyrogram/client/types/messages_and_media/photos.py rename to pyrogram/client/types/messages_and_media/profile_photos.py index a1803923..11b8e4dd 100644 --- a/pyrogram/client/types/messages_and_media/photos.py +++ b/pyrogram/client/types/messages_and_media/profile_photos.py @@ -23,35 +23,35 @@ from .photo import Photo from ..object import Object -class Photos(Object): +class ProfilePhotos(Object): """Contains a user's profile pictures. Parameters: total_count (``int``): Total number of profile pictures the target user has. - photos (List of :obj:`Photo`): + profile_photos (List of :obj:`Photo`): Requested profile pictures. """ - __slots__ = ["total_count", "photos"] + __slots__ = ["total_count", "profile_photos"] def __init__( self, *, client: "pyrogram.BaseClient" = None, total_count: int, - photos: List[Photo] + profile_photos: List[Photo] ): super().__init__(client) self.total_count = total_count - self.photos = photos + self.profile_photos = profile_photos @staticmethod - def _parse(client, photos) -> "Photos": - return Photos( + def _parse(client, photos) -> "ProfilePhotos": + return ProfilePhotos( total_count=getattr(photos, "count", len(photos.photos)), - photos=[Photo._parse(client, photo) for photo in photos.photos], + profile_photos=[Photo._parse(client, photo) for photo in photos.photos], client=client ) From da515af9597f9533d9315ace6096c7cb22fe122c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 6 Jun 2019 19:29:44 +0200 Subject: [PATCH 147/202] Rearrange code --- compiler/api/compiler.py | 6 ++--- pyrogram/api/core/__init__.py | 2 +- pyrogram/api/core/future_salt.py | 2 +- pyrogram/api/core/future_salts.py | 2 +- pyrogram/api/core/gzip_packed.py | 2 +- pyrogram/api/core/message.py | 2 +- pyrogram/api/core/msg_container.py | 2 +- .../methods/bots/get_inline_bot_results.py | 2 +- pyrogram/client/methods/chats/__init__.py | 2 +- pyrogram/client/methods/users/get_user_dc.py | 1 - .../todo/inline_query_result_audio.py | 3 ++- .../todo/inline_query_result_cached_audio.py | 2 +- .../inline_query_result_cached_document.py | 3 ++- .../todo/inline_query_result_cached_gif.py | 3 ++- .../inline_query_result_cached_mpeg4_gif.py | 3 ++- .../todo/inline_query_result_cached_photo.py | 3 ++- .../todo/inline_query_result_cached_video.py | 3 ++- .../todo/inline_query_result_cached_voice.py | 3 ++- .../todo/inline_query_result_contact.py | 4 +++- .../todo/inline_query_result_document.py | 4 +++- .../todo/inline_query_result_gif.py | 4 +++- .../todo/inline_query_result_location.py | 4 +++- .../todo/inline_query_result_mpeg4_gif.py | 4 +++- .../todo/inline_query_result_photo.py | 24 +++++++++---------- .../todo/inline_query_result_venue.py | 4 +++- .../todo/inline_query_result_video.py | 4 +++- .../todo/inline_query_result_voice.py | 3 ++- .../types/input_media/input_phone_contact.py | 1 + .../client/types/keyboards/force_reply.py | 1 + .../client/types/keyboards/keyboard_button.py | 1 + .../types/keyboards/reply_keyboard_remove.py | 1 + 31 files changed, 65 insertions(+), 40 deletions(-) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 0ecc9212..3995fd5f 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -288,9 +288,9 @@ def start(): sorted_args = sort_args(c.args) arguments = ( - ", " - + ("*, " if c.args else "") - + (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "") + ", " + + ("*, " if c.args else "") + + (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "") ) fields = "\n ".join( diff --git a/pyrogram/api/core/__init__.py b/pyrogram/api/core/__init__.py index f27a26a5..aaf5a324 100644 --- a/pyrogram/api/core/__init__.py +++ b/pyrogram/api/core/__init__.py @@ -22,8 +22,8 @@ from .gzip_packed import GzipPacked from .list import List from .message import Message from .msg_container import MsgContainer -from .tl_object import TLObject from .primitives import ( Bool, BoolTrue, BoolFalse, Bytes, Double, Int, Long, Int128, Int256, Null, String, Vector ) +from .tl_object import TLObject diff --git a/pyrogram/api/core/future_salt.py b/pyrogram/api/core/future_salt.py index 699a416f..ab387f6c 100644 --- a/pyrogram/api/core/future_salt.py +++ b/pyrogram/api/core/future_salt.py @@ -18,8 +18,8 @@ from io import BytesIO -from .tl_object import TLObject from .primitives import Int, Long +from .tl_object import TLObject class FutureSalt(TLObject): diff --git a/pyrogram/api/core/future_salts.py b/pyrogram/api/core/future_salts.py index c749c569..a97b9d2a 100644 --- a/pyrogram/api/core/future_salts.py +++ b/pyrogram/api/core/future_salts.py @@ -19,8 +19,8 @@ from io import BytesIO from . import FutureSalt -from .tl_object import TLObject from .primitives import Int, Long +from .tl_object import TLObject class FutureSalts(TLObject): diff --git a/pyrogram/api/core/gzip_packed.py b/pyrogram/api/core/gzip_packed.py index 4b212184..5a8e76da 100644 --- a/pyrogram/api/core/gzip_packed.py +++ b/pyrogram/api/core/gzip_packed.py @@ -19,8 +19,8 @@ from gzip import compress, decompress from io import BytesIO -from .tl_object import TLObject from .primitives import Int, Bytes +from .tl_object import TLObject class GzipPacked(TLObject): diff --git a/pyrogram/api/core/message.py b/pyrogram/api/core/message.py index db123db3..1b9b55f1 100644 --- a/pyrogram/api/core/message.py +++ b/pyrogram/api/core/message.py @@ -18,8 +18,8 @@ from io import BytesIO -from .tl_object import TLObject from .primitives import Int, Long +from .tl_object import TLObject class Message(TLObject): diff --git a/pyrogram/api/core/msg_container.py b/pyrogram/api/core/msg_container.py index 7a17087e..58732403 100644 --- a/pyrogram/api/core/msg_container.py +++ b/pyrogram/api/core/msg_container.py @@ -19,8 +19,8 @@ from io import BytesIO from .message import Message -from .tl_object import TLObject from .primitives import Int +from .tl_object import TLObject class MsgContainer(TLObject): diff --git a/pyrogram/client/methods/bots/get_inline_bot_results.py b/pyrogram/client/methods/bots/get_inline_bot_results.py index 307238e3..cc0fc1b1 100644 --- a/pyrogram/client/methods/bots/get_inline_bot_results.py +++ b/pyrogram/client/methods/bots/get_inline_bot_results.py @@ -19,8 +19,8 @@ from typing import Union from pyrogram.api import functions, types -from pyrogram.errors import UnknownError from pyrogram.client.ext import BaseClient +from pyrogram.errors import UnknownError class GetInlineBotResults(BaseClient): diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index 698255f5..c0176939 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -23,6 +23,7 @@ from .get_chat_member import GetChatMember from .get_chat_members import GetChatMembers from .get_chat_members_count import GetChatMembersCount from .get_dialogs import GetDialogs +from .get_dialogs_count import GetDialogsCount from .iter_chat_members import IterChatMembers from .iter_dialogs import IterDialogs from .join_chat import JoinChat @@ -38,7 +39,6 @@ from .set_chat_title import SetChatTitle from .unban_chat_member import UnbanChatMember from .unpin_chat_message import UnpinChatMessage from .update_chat_username import UpdateChatUsername -from .get_dialogs_count import GetDialogsCount class Chats( diff --git a/pyrogram/client/methods/users/get_user_dc.py b/pyrogram/client/methods/users/get_user_dc.py index 49596c11..89e97526 100644 --- a/pyrogram/client/methods/users/get_user_dc.py +++ b/pyrogram/client/methods/users/get_user_dc.py @@ -19,7 +19,6 @@ from typing import Union from pyrogram.api import functions, types - from ...ext import BaseClient diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py index dbda676d..d5fb954a 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_audio.py @@ -58,7 +58,8 @@ class InlineQueryResultAudio(Object): """ - def __init__(self, type: str, id: str, audio_url: str, title: str, caption: str = None, parse_mode: str = None, performer: str = None, audio_duration: int = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, audio_url: str, title: str, caption: str = None, parse_mode: str = None, + performer: str = None, audio_duration: int = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.audio_url = audio_url # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py index a4ac1ec8..47b9bbe2 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_audio.py @@ -20,10 +20,10 @@ import binascii import struct from pyrogram.api import types -from pyrogram.errors import FileIdInvalid from pyrogram.client.ext import utils, BaseClient from pyrogram.client.style import HTML, Markdown from pyrogram.client.types.object import Object +from pyrogram.errors import FileIdInvalid class InlineQueryResultCachedAudio(Object): diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py index 0dfde1c4..d3b3d0dc 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_document.py @@ -56,7 +56,8 @@ class InlineQueryResultCachedDocument(Object): """ ID = 0xb0700015 - def __init__(self, type: str, id: str, title: str, document_file_id: str, description: str = None, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, title: str, document_file_id: str, description: str = None, + caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.title = title # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py index 819b383f..28a3595b 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_gif.py @@ -53,7 +53,8 @@ class InlineQueryResultCachedGif(Object): """ ID = 0xb0700012 - def __init__(self, type: str, id: str, gif_file_id: str, title: str = None, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, gif_file_id: str, title: str = None, caption: str = None, + parse_mode: str = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.gif_file_id = gif_file_id # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py index 9856af66..95ab03a0 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_mpeg4_gif.py @@ -53,7 +53,8 @@ class InlineQueryResultCachedMpeg4Gif(Object): """ ID = 0xb0700013 - def __init__(self, type: str, id: str, mpeg4_file_id: str, title: str = None, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, mpeg4_file_id: str, title: str = None, caption: str = None, + parse_mode: str = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.mpeg4_file_id = mpeg4_file_id # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py index 53b479f9..22793cef 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_photo.py @@ -56,7 +56,8 @@ class InlineQueryResultCachedPhoto(Object): """ ID = 0xb0700011 - def __init__(self, type: str, id: str, photo_file_id: str, title: str = None, description: str = None, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, photo_file_id: str, title: str = None, description: str = None, + caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.photo_file_id = photo_file_id # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py index 3a04a766..77dcd6dd 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_video.py @@ -56,7 +56,8 @@ class InlineQueryResultCachedVideo(Object): """ ID = 0xb0700016 - def __init__(self, type: str, id: str, video_file_id: str, title: str, description: str = None, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, video_file_id: str, title: str, description: str = None, caption: str = None, + parse_mode: str = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.video_file_id = video_file_id # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py index fbdf6c19..a80d5a20 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_cached_voice.py @@ -53,7 +53,8 @@ class InlineQueryResultCachedVoice(Object): """ ID = 0xb0700017 - def __init__(self, type: str, id: str, voice_file_id: str, title: str, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, voice_file_id: str, title: str, caption: str = None, parse_mode: str = None, + reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.voice_file_id = voice_file_id # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py index a64d6ace..afddb9ec 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_contact.py @@ -62,7 +62,9 @@ class InlineQueryResultContact(Object): """ ID = 0xb0700009 - def __init__(self, type: str, id: str, phone_number: str, first_name: str, last_name: str = None, vcard: str = None, reply_markup=None, input_message_content=None, thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): + def __init__(self, type: str, id: str, phone_number: str, first_name: str, last_name: str = None, vcard: str = None, + reply_markup=None, input_message_content=None, thumb_url: str = None, thumb_width: int = None, + thumb_height: int = None): self.type = type # string self.id = id # string self.phone_number = phone_number # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py index 007f237b..370dc3c6 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_document.py @@ -68,7 +68,9 @@ class InlineQueryResultDocument(Object): """ ID = 0xb0700006 - def __init__(self, type: str, id: str, title: str, document_url: str, mime_type: str, caption: str = None, parse_mode: str = None, description: str = None, reply_markup=None, input_message_content=None, thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): + def __init__(self, type: str, id: str, title: str, document_url: str, mime_type: str, caption: str = None, + parse_mode: str = None, description: str = None, reply_markup=None, input_message_content=None, + thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): self.type = type # string self.id = id # string self.title = title # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py index 7273b79a..56817d76 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_gif.py @@ -65,7 +65,9 @@ class InlineQueryResultGif(Object): """ ID = 0xb0700001 - def __init__(self, type: str, id: str, gif_url: str, thumb_url: str, gif_width: int = None, gif_height: int = None, gif_duration: int = None, title: str = None, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, gif_url: str, thumb_url: str, gif_width: int = None, gif_height: int = None, + gif_duration: int = None, title: str = None, caption: str = None, parse_mode: str = None, + reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.gif_url = gif_url # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py index a32fc93d..74c63ede 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_location.py @@ -62,7 +62,9 @@ class InlineQueryResultLocation(Object): """ ID = 0xb0700007 - def __init__(self, type: str, id: str, latitude: float, longitude: float, title: str, live_period: int = None, reply_markup=None, input_message_content=None, thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): + def __init__(self, type: str, id: str, latitude: float, longitude: float, title: str, live_period: int = None, + reply_markup=None, input_message_content=None, thumb_url: str = None, thumb_width: int = None, + thumb_height: int = None): self.type = type # string self.id = id # string self.latitude = latitude # double diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py index 04c68cf7..e4da6b89 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_mpeg4_gif.py @@ -65,7 +65,9 @@ class InlineQueryResultMpeg4Gif(Object): """ ID = 0xb0700002 - def __init__(self, type: str, id: str, mpeg4_url: str, thumb_url: str, mpeg4_width: int = None, mpeg4_height: int = None, mpeg4_duration: int = None, title: str = None, caption: str = None, parse_mode: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, mpeg4_url: str, thumb_url: str, mpeg4_width: int = None, + mpeg4_height: int = None, mpeg4_duration: int = None, title: str = None, caption: str = None, + parse_mode: str = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.mpeg4_url = mpeg4_url # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py index 57f36fae..570bd55d 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_photo.py @@ -63,18 +63,18 @@ class InlineQueryResultPhoto(Object): """ def __init__( - self, - id: str, - photo_url: str, - thumb_url: str, - photo_width: int = 0, - photo_height: int = 0, - title: str = None, - description: str = None, - caption: str = "", - parse_mode: str = "", - reply_markup=None, - input_message_content=None + self, + id: str, + photo_url: str, + thumb_url: str, + photo_width: int = 0, + photo_height: int = 0, + title: str = None, + description: str = None, + caption: str = "", + parse_mode: str = "", + reply_markup=None, + input_message_content=None ): self.id = id # string self.photo_url = photo_url # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py index 3343ccf9..29eb86a6 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_venue.py @@ -68,7 +68,9 @@ class InlineQueryResultVenue(Object): """ ID = 0xb0700008 - def __init__(self, type: str, id: str, latitude: float, longitude: float, title: str, address: str, foursquare_id: str = None, foursquare_type: str = None, reply_markup=None, input_message_content=None, thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): + def __init__(self, type: str, id: str, latitude: float, longitude: float, title: str, address: str, + foursquare_id: str = None, foursquare_type: str = None, reply_markup=None, input_message_content=None, + thumb_url: str = None, thumb_width: int = None, thumb_height: int = None): self.type = type # string self.id = id # string self.latitude = latitude # double diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py index ebfe2047..61984d48 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_video.py @@ -71,7 +71,9 @@ class InlineQueryResultVideo(Object): """ ID = 0xb0700003 - def __init__(self, type: str, id: str, video_url: str, mime_type: str, thumb_url: str, title: str, caption: str = None, parse_mode: str = None, video_width: int = None, video_height: int = None, video_duration: int = None, description: str = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, video_url: str, mime_type: str, thumb_url: str, title: str, + caption: str = None, parse_mode: str = None, video_width: int = None, video_height: int = None, + video_duration: int = None, description: str = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.video_url = video_url # string diff --git a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py index 4e2bbb09..7a5f3cd1 100644 --- a/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py +++ b/pyrogram/client/types/inline_mode/todo/inline_query_result_voice.py @@ -56,7 +56,8 @@ class InlineQueryResultVoice(Object): """ ID = 0xb0700005 - def __init__(self, type: str, id: str, voice_url: str, title: str, caption: str = None, parse_mode: str = None, voice_duration: int = None, reply_markup=None, input_message_content=None): + def __init__(self, type: str, id: str, voice_url: str, title: str, caption: str = None, parse_mode: str = None, + voice_duration: int = None, reply_markup=None, input_message_content=None): self.type = type # string self.id = id # string self.voice_url = voice_url # string diff --git a/pyrogram/client/types/input_media/input_phone_contact.py b/pyrogram/client/types/input_media/input_phone_contact.py index e49cee30..f60dd39d 100644 --- a/pyrogram/client/types/input_media/input_phone_contact.py +++ b/pyrogram/client/types/input_media/input_phone_contact.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from pyrogram.api.types import InputPhoneContact as RawInputPhoneContact + from pyrogram.session.internals import MsgId from ..object import Object diff --git a/pyrogram/client/types/keyboards/force_reply.py b/pyrogram/client/types/keyboards/force_reply.py index 59405529..6c542aa8 100644 --- a/pyrogram/client/types/keyboards/force_reply.py +++ b/pyrogram/client/types/keyboards/force_reply.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from pyrogram.api.types import ReplyKeyboardForceReply + from ..object import Object diff --git a/pyrogram/client/types/keyboards/keyboard_button.py b/pyrogram/client/types/keyboards/keyboard_button.py index 2dc09f5d..8374db1b 100644 --- a/pyrogram/client/types/keyboards/keyboard_button.py +++ b/pyrogram/client/types/keyboards/keyboard_button.py @@ -18,6 +18,7 @@ from pyrogram.api.types import KeyboardButton as RawKeyboardButton from pyrogram.api.types import KeyboardButtonRequestPhone, KeyboardButtonRequestGeoLocation + from ..object import Object diff --git a/pyrogram/client/types/keyboards/reply_keyboard_remove.py b/pyrogram/client/types/keyboards/reply_keyboard_remove.py index 8dd84f72..d451a8e8 100644 --- a/pyrogram/client/types/keyboards/reply_keyboard_remove.py +++ b/pyrogram/client/types/keyboards/reply_keyboard_remove.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from pyrogram.api.types import ReplyKeyboardHide + from ..object import Object From a80c5c1dbb6084004d855724135b093c818d3a59 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 15:48:46 +0200 Subject: [PATCH 148/202] Fix broken links on decorators' docs --- pyrogram/client/methods/decorators/on_callback_query.py | 5 +++-- pyrogram/client/methods/decorators/on_deleted_messages.py | 5 +++-- pyrogram/client/methods/decorators/on_disconnect.py | 2 +- pyrogram/client/methods/decorators/on_inline_query.py | 4 ++-- pyrogram/client/methods/decorators/on_message.py | 4 ++-- pyrogram/client/methods/decorators/on_poll.py | 4 ++-- pyrogram/client/methods/decorators/on_raw_update.py | 2 +- pyrogram/client/methods/decorators/on_user_status.py | 4 ++-- 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pyrogram/client/methods/decorators/on_callback_query.py b/pyrogram/client/methods/decorators/on_callback_query.py index 5057f59f..1552bae7 100644 --- a/pyrogram/client/methods/decorators/on_callback_query.py +++ b/pyrogram/client/methods/decorators/on_callback_query.py @@ -32,10 +32,11 @@ class OnCallbackQuery(BaseClient): ) -> callable: """Decorator for handling callback queries. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`CallbackQueryHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the + :obj:`~pyrogram.CallbackQueryHandler`. Parameters: - filters (:obj:`Filters`): + filters (:obj:`~pyrogram.Filters`, *optional*): Pass one or more filters to allow only a subset of callback queries to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_deleted_messages.py b/pyrogram/client/methods/decorators/on_deleted_messages.py index 53457b55..0d87ba5a 100644 --- a/pyrogram/client/methods/decorators/on_deleted_messages.py +++ b/pyrogram/client/methods/decorators/on_deleted_messages.py @@ -32,10 +32,11 @@ class OnDeletedMessages(BaseClient): ) -> callable: """Decorator for handling deleted messages. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`DeletedMessagesHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the + :obj:`~pyrogram.DeletedMessagesHandler`. Parameters: - filters (:obj:`Filters`): + filters (:obj:`~pyrogram.Filters`, *optional*): Pass one or more filters to allow only a subset of messages to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_disconnect.py b/pyrogram/client/methods/decorators/on_disconnect.py index b195ac54..4a514a41 100644 --- a/pyrogram/client/methods/decorators/on_disconnect.py +++ b/pyrogram/client/methods/decorators/on_disconnect.py @@ -25,7 +25,7 @@ class OnDisconnect(BaseClient): def on_disconnect(self=None) -> callable: """Decorator for handling disconnections. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`DisconnectHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the :obj:`~pyrogram.DisconnectHandler`. """ def decorator(func: callable) -> Handler: diff --git a/pyrogram/client/methods/decorators/on_inline_query.py b/pyrogram/client/methods/decorators/on_inline_query.py index ee7175eb..adc65d25 100644 --- a/pyrogram/client/methods/decorators/on_inline_query.py +++ b/pyrogram/client/methods/decorators/on_inline_query.py @@ -32,10 +32,10 @@ class OnInlineQuery(BaseClient): ) -> callable: """Decorator for handling inline queries. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`InlineQueryHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the :obj:`~pyrogram.InlineQueryHandler`. Parameters: - filters (:obj:`Filters `): + filters (:obj:`~pyrogram.Filters`, *optional*): Pass one or more filters to allow only a subset of inline queries to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_message.py b/pyrogram/client/methods/decorators/on_message.py index 0f5c836c..758a6831 100644 --- a/pyrogram/client/methods/decorators/on_message.py +++ b/pyrogram/client/methods/decorators/on_message.py @@ -32,10 +32,10 @@ class OnMessage(BaseClient): ) -> callable: """Decorator for handling messages. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`MessageHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the :obj:`~pyrogram.MessageHandler`. Parameters: - filters (:obj:`Filters`): + filters (:obj:`~pyrogram.Filters`, *optional*): Pass one or more filters to allow only a subset of messages to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_poll.py b/pyrogram/client/methods/decorators/on_poll.py index 7442858d..0ade42c0 100644 --- a/pyrogram/client/methods/decorators/on_poll.py +++ b/pyrogram/client/methods/decorators/on_poll.py @@ -32,10 +32,10 @@ class OnPoll(BaseClient): ) -> callable: """Decorator for handling poll updates. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`PollHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the :obj:`~pyrogram.PollHandler`. Parameters: - filters (:obj:`Filters`): + filters (:obj:`~pyrogram.Filters`, *optional*): Pass one or more filters to allow only a subset of polls to be passed in your function. diff --git a/pyrogram/client/methods/decorators/on_raw_update.py b/pyrogram/client/methods/decorators/on_raw_update.py index e03402ca..7dff75fa 100644 --- a/pyrogram/client/methods/decorators/on_raw_update.py +++ b/pyrogram/client/methods/decorators/on_raw_update.py @@ -30,7 +30,7 @@ class OnRawUpdate(BaseClient): ) -> callable: """Decorator for handling raw updates. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`RawUpdateHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the :obj:`~pyrogram.RawUpdateHandler`. Parameters: group (``int``, *optional*): diff --git a/pyrogram/client/methods/decorators/on_user_status.py b/pyrogram/client/methods/decorators/on_user_status.py index bcdcf024..09e037f7 100644 --- a/pyrogram/client/methods/decorators/on_user_status.py +++ b/pyrogram/client/methods/decorators/on_user_status.py @@ -31,10 +31,10 @@ class OnUserStatus(BaseClient): group: int = 0 ) -> callable: """Decorator for handling user status updates. - This does the same thing as :meth:`~Client.add_handler` using the :obj:`UserStatusHandler`. + This does the same thing as :meth:`~pyrogram.Client.add_handler` using the :obj:`~pyrogram.UserStatusHandler`. Parameters: - filters (:obj:`Filters`): + filters (:obj:`~pyrogram.Filters`, *optional*): Pass one or more filters to allow only a subset of UserStatus updated to be passed in your function. group (``int``, *optional*): From 317a647583604a3eb477cd42f2ff2267c15616c2 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 15:50:15 +0200 Subject: [PATCH 149/202] Reword some parts of the docs --- docs/source/topics/advanced-usage.rst | 12 +++++----- docs/source/topics/config-file.rst | 6 ++--- docs/source/topics/create-filters.rst | 31 +++++++++++++------------- docs/source/topics/more-on-updates.rst | 4 ++-- docs/source/topics/use-filters.rst | 3 ++- 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/docs/source/topics/advanced-usage.rst b/docs/source/topics/advanced-usage.rst index ff1afa5c..9c794be0 100644 --- a/docs/source/topics/advanced-usage.rst +++ b/docs/source/topics/advanced-usage.rst @@ -103,9 +103,9 @@ sending messages with IDs only thanks to cached access hashes. There are three different InputPeer types, one for each kind of Telegram entity. Whenever an InputPeer is needed you must pass one of these: - - :class:`~pyrogram.api.types.InputPeerUser` - Users - - :class:`~pyrogram.api.types.InputPeerChat` - Basic Chats - - :class:`~pyrogram.api.types.InputPeerChannel` - Either Channels or Supergroups +- :class:`~pyrogram.api.types.InputPeerUser` - Users +- :class:`~pyrogram.api.types.InputPeerChat` - Basic Chats +- :class:`~pyrogram.api.types.InputPeerChannel` - Either Channels or Supergroups But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides :meth:`~pyrogram.Client.resolve_peer` as a convenience utility method that returns the correct InputPeer @@ -120,9 +120,9 @@ kind of ID. For example, given the ID *123456789*, here's how Pyrogram can tell entities apart: - - ``+ID`` User: *123456789* - - ``-ID`` Chat: *-123456789* - - ``-100ID`` Channel or Supergroup: *-100123456789* +- ``+ID`` User: *123456789* +- ``-ID`` Chat: *-123456789* +- ``-100ID`` Channel or Supergroup: *-100123456789* So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an high-level method. diff --git a/docs/source/topics/config-file.rst b/docs/source/topics/config-file.rst index 14ae9fb6..a28025db 100644 --- a/docs/source/topics/config-file.rst +++ b/docs/source/topics/config-file.rst @@ -1,14 +1,14 @@ Configuration File ================== -As already mentioned in previous sections, Pyrogram can be configured by the use of an INI file. -This page explains how this file is structured in Pyrogram, how to use it and why. +As already mentioned in previous pages, Pyrogram can be configured by the use of an INI file. +This page explains how this file is structured, how to use it and why. Introduction ------------ The idea behind using a configuration file is to help keeping your code free of private settings information such as -the API Key and Proxy without having you to even deal with how to load such settings. The configuration file, usually +the API Key and Proxy, without having you to even deal with how to load such settings. The configuration file, usually referred as ``config.ini`` file, is automatically loaded from the root of your working directory; all you need to do is fill in the necessary parts. diff --git a/docs/source/topics/create-filters.rst b/docs/source/topics/create-filters.rst index 0252221c..6cb33a50 100644 --- a/docs/source/topics/create-filters.rst +++ b/docs/source/topics/create-filters.rst @@ -13,9 +13,10 @@ Custom Filters -------------- An example to demonstrate how custom filters work is to show how to create and use one for the -:class:`~pyrogram.CallbackQueryHandler`. Note that callback queries updates are only received by bots; create and -:doc:`authorize your bot <../start/auth>`, then send a message with an inline keyboard to yourself. This allows you to -test your filter by pressing the inline button: +:class:`~pyrogram.CallbackQueryHandler`. Note that callback queries updates are only received by bots as result of a +user pressing an inline button attached to the bot's message; create and :doc:`authorize your bot <../start/auth>`, +then send a message with an inline keyboard to yourself. This allows you to test your filter by pressing the inline +button: .. code-block:: python @@ -25,7 +26,7 @@ test your filter by pressing the inline button: "username", # Change this to your username or id "Pyrogram's custom filter test", reply_markup=InlineKeyboardMarkup( - [[InlineKeyboardButton("Press me", b"pyrogram")]] + [[InlineKeyboardButton("Press me", "pyrogram")]] ) ) @@ -36,13 +37,13 @@ For this basic filter we will be using only the first two parameters of :meth:`~ The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries containing "Pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data -equals to ``b"Pyrogram"``. +equals to ``"Pyrogram"``. .. code-block:: python static_data = Filters.create( name="StaticdData", - func=lambda flt, callback_query: callback_query.data == b"Pyrogram" + func=lambda flt, query: query.data == "Pyrogram" ) The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same @@ -50,8 +51,8 @@ could be achieved with a normal function, but we don't really need it as it make .. code-block:: python - def func(flt, callback_query): - return callback_query.data == b"Pyrogram" + def func(flt, query): + return query.data == "Pyrogram" static_data = Filters.create( name="StaticData", @@ -63,8 +64,8 @@ The filter usage remains the same: .. code-block:: python @app.on_callback_query(static_data) - def pyrogram_data(client, callback_query): - client.answer_callback_query(callback_query.id, "it works!") + def pyrogram_data(_, query): + query.answer("it works!") Filters with Arguments ---------------------- @@ -79,14 +80,14 @@ This is how a dynamic custom filter looks like: def dynamic_data(data): return Filters.create( name="DynamicData", - func=lambda flt, callback_query: flt.data == callback_query.data, - data=data # "data" kwarg is accessed with "filter.data" + func=lambda flt, query: flt.data == query.data, + data=data # "data" kwarg is accessed with "flt.data" ) And its usage: .. code-block:: python - @app.on_callback_query(dynamic_data(b"Pyrogram")) - def pyrogram_data(client, callback_query): - client.answer_callback_query(callback_query.id, "it works!") \ No newline at end of file + @app.on_callback_query(dynamic_data("Pyrogram")) + def pyrogram_data(_, query): + query.answer("it works!") diff --git a/docs/source/topics/more-on-updates.rst b/docs/source/topics/more-on-updates.rst index df0aff7d..f23e692e 100644 --- a/docs/source/topics/more-on-updates.rst +++ b/docs/source/topics/more-on-updates.rst @@ -29,7 +29,7 @@ For example, take these two handlers: print("Just Text") Here, ``just_text`` is never executed because ``text_or_sticker``, which has been registered first, already handles -texts (``Filters.text`` is shared and conflicting). To enable it, register the function using a different group: +texts (``Filters.text`` is shared and conflicting). To enable it, register the handler using a different group: .. code-block:: python @@ -37,7 +37,7 @@ texts (``Filters.text`` is shared and conflicting). To enable it, register the f def just_text(client, message): print("Just Text") -Or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``): +Or, if you want ``just_text`` to be executed *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``): .. code-block:: python diff --git a/docs/source/topics/use-filters.rst b/docs/source/topics/use-filters.rst index c23a98df..d481b393 100644 --- a/docs/source/topics/use-filters.rst +++ b/docs/source/topics/use-filters.rst @@ -25,7 +25,8 @@ Let's start right away with a simple example: def my_handler(client, message): print(message) -- or, without decorators. Here filters are passed as the second argument of the handler constructor: +- or, without decorators. Here filters are passed as the second argument of the handler constructor; the first is the + callback function itself: .. code-block:: python :emphasize-lines: 8 From 571af6e0b9e8d2f41a1d754398ea5b92c24e1d83 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 16:05:33 +0200 Subject: [PATCH 150/202] Update Pyrogram to v0.14.0 --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index f87b2b0d..61899174 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -24,7 +24,7 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]: # Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one. sys.modules["typing"] = typing -__version__ = "0.14.0-develop" +__version__ = "0.14.0" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __copyright__ = "Copyright (C) 2017-2019 Dan " From 3c1faff2a6f1b6a4a2e758fca5611fce92050d09 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 16:24:18 +0200 Subject: [PATCH 151/202] Update sitemap.py --- docs/sitemap.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/sitemap.py b/docs/sitemap.py index 4def886f..d4abeb32 100644 --- a/docs/sitemap.py +++ b/docs/sitemap.py @@ -27,6 +27,7 @@ dirs = { "start": ("weekly", 0.9), "api": ("weekly", 0.8), "topics": ("weekly", 0.8), + "releases": ("weekly", 0.8), "telegram": ("weekly", 0.6) } From d95bbdf445e924575a964de9512766661326fab7 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 16:37:28 +0200 Subject: [PATCH 152/202] Update next develop version --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 61899174..ac184844 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -24,7 +24,7 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]: # Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one. sys.modules["typing"] = typing -__version__ = "0.14.0" +__version__ = "0.15.0-develop" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __copyright__ = "Copyright (C) 2017-2019 Dan " From 89e6f4137b5a9aa5dbe0d3bcfaf458109c5949ac Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 18:00:00 +0200 Subject: [PATCH 153/202] Fix get_chat_member always returning self for basic groups --- .../client/methods/chats/get_chat_member.py | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/pyrogram/client/methods/chats/get_chat_member.py b/pyrogram/client/methods/chats/get_chat_member.py index 4deab9ec..b84836c6 100644 --- a/pyrogram/client/methods/chats/get_chat_member.py +++ b/pyrogram/client/methods/chats/get_chat_member.py @@ -47,26 +47,30 @@ class GetChatMember(BaseClient): Raises: RPCError: In case of a Telegram RPC error. """ - chat_id = self.resolve_peer(chat_id) - user_id = self.resolve_peer(user_id) + chat = self.resolve_peer(chat_id) + user = self.resolve_peer(user_id) - if isinstance(chat_id, types.InputPeerChat): + if isinstance(chat, types.InputPeerChat): full_chat = self.send( functions.messages.GetFullChat( - chat_id=chat_id.chat_id + chat_id=chat.chat_id ) ) for member in pyrogram.ChatMembers._parse(self, full_chat).chat_members: - if member.user.is_self: - return member + if isinstance(user, types.InputPeerSelf): + if member.user.is_self: + return member + else: + if member.user.id == user.user_id: + return member else: raise UserNotParticipant - elif isinstance(chat_id, types.InputPeerChannel): + elif isinstance(chat, types.InputPeerChannel): r = self.send( functions.channels.GetParticipant( - channel=chat_id, - user_id=user_id + channel=chat, + user_id=user ) ) From c65e210c0301342131fe164ec08c3b1a0033a204 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 18:48:34 +0200 Subject: [PATCH 154/202] Fix FileData namedtuple using Python 3.7+ features --- pyrogram/client/client.py | 10 ++--- pyrogram/client/ext/__init__.py | 2 + pyrogram/client/ext/base_client.py | 5 --- pyrogram/client/ext/file_data.py | 38 +++++++++++++++++++ .../client/methods/messages/download_media.py | 20 +++++----- 5 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 pyrogram/client/ext/file_data.py diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 08a3072e..6dc8ce97 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -877,7 +877,7 @@ class Client(Methods, BaseClient): temp_file_path = self.get_file( media_type=data.media_type, dc_id=data.dc_id, - file_id=data.file_id, + document_id=data.document_id, access_hash=data.access_hash, thumb_size=data.thumb_size, peer_id=data.peer_id, @@ -1520,7 +1520,7 @@ class Client(Methods, BaseClient): self, media_type: int, dc_id: int, - file_id: int, + document_id: int, access_hash: int, thumb_size: str, peer_id: int, @@ -1580,21 +1580,21 @@ class Client(Methods, BaseClient): ) elif media_type in (0, 2): location = types.InputPhotoFileLocation( - id=file_id, + id=document_id, access_hash=access_hash, file_reference=b"", thumb_size=thumb_size ) elif media_type == 14: location = types.InputDocumentFileLocation( - id=file_id, + id=document_id, access_hash=access_hash, file_reference=b"", thumb_size=thumb_size ) else: location = types.InputDocumentFileLocation( - id=file_id, + id=document_id, access_hash=access_hash, file_reference=b"", thumb_size="" diff --git a/pyrogram/client/ext/__init__.py b/pyrogram/client/ext/__init__.py index 917c9e62..58897c55 100644 --- a/pyrogram/client/ext/__init__.py +++ b/pyrogram/client/ext/__init__.py @@ -20,3 +20,5 @@ from .base_client import BaseClient from .dispatcher import Dispatcher from .emoji import Emoji from .syncer import Syncer +from .file_data import FileData + diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index 9c0d661e..9e7cd677 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -19,7 +19,6 @@ import os import platform import re -from collections import namedtuple from queue import Queue from threading import Lock @@ -84,10 +83,6 @@ class BaseClient: mime_types_to_extensions[mime_type] = " ".join(extensions) - fields = ("media_type", "dc_id", "file_id", "access_hash", "thumb_size", "peer_id", "volume_id", "local_id", - "is_big", "file_size", "mime_type", "file_name", "date") - FileData = namedtuple("FileData", fields, defaults=(None,) * len(fields)) - def __init__(self): self.is_bot = None self.dc_id = None diff --git a/pyrogram/client/ext/file_data.py b/pyrogram/client/ext/file_data.py new file mode 100644 index 00000000..9a19cd5d --- /dev/null +++ b/pyrogram/client/ext/file_data.py @@ -0,0 +1,38 @@ +# 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 . + + +class FileData: + def __init__( + self, *, media_type: int = None, dc_id: int = None, document_id: int = None, access_hash: int = None, + thumb_size: str = None, peer_id: int = None, volume_id: int = None, local_id: int = None, is_big: bool = None, + file_size: int = None, mime_type: str = None, file_name: str = None, date: int = None + ): + self.media_type = media_type + self.dc_id = dc_id + self.document_id = document_id + self.access_hash = access_hash + self.thumb_size = thumb_size + self.peer_id = peer_id + self.volume_id = volume_id + self.local_id = local_id + self.is_big = is_big + self.file_size = file_size + self.mime_type = mime_type + self.file_name = file_name + self.date = date diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index 88c9c2d9..d822a88b 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -22,7 +22,7 @@ from threading import Event from typing import Union import pyrogram -from pyrogram.client.ext import BaseClient, utils +from pyrogram.client.ext import BaseClient, FileData, utils from pyrogram.errors import FileIdInvalid @@ -110,7 +110,7 @@ class DownloadMedia(BaseClient): mime_type = getattr(media, "mime_type", None) date = getattr(media, "date", None) - data = self.FileData( + data = FileData( file_name=file_name, file_size=file_size, mime_type=mime_type, @@ -118,7 +118,7 @@ class DownloadMedia(BaseClient): ) def get_existing_attributes() -> dict: - return dict(filter(lambda x: x[1] is not None, data._asdict().items())) + return dict(filter(lambda x: x[1] is not None, data.__dict__.items())) try: decoded = utils.decode(file_id_str) @@ -128,7 +128,7 @@ class DownloadMedia(BaseClient): unpacked = struct.unpack(" Date: Fri, 7 Jun 2019 18:51:04 +0200 Subject: [PATCH 155/202] Fix trailing commas breaking older Python versions --- pyrogram/client/types/messages_and_media/animation.py | 2 +- pyrogram/client/types/messages_and_media/audio.py | 2 +- pyrogram/client/types/messages_and_media/document.py | 2 +- pyrogram/client/types/messages_and_media/stripped_thumbnail.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/animation.py b/pyrogram/client/types/messages_and_media/animation.py index 2a9c9e66..5441a114 100644 --- a/pyrogram/client/types/messages_and_media/animation.py +++ b/pyrogram/client/types/messages_and_media/animation.py @@ -72,7 +72,7 @@ class Animation(Object): mime_type: str = None, file_size: int = None, date: int = None, - thumbs: List[Thumbnail] = None, + thumbs: List[Thumbnail] = None ): super().__init__(client) diff --git a/pyrogram/client/types/messages_and_media/audio.py b/pyrogram/client/types/messages_and_media/audio.py index d6324e83..3d9cf8a6 100644 --- a/pyrogram/client/types/messages_and_media/audio.py +++ b/pyrogram/client/types/messages_and_media/audio.py @@ -74,7 +74,7 @@ class Audio(Object): date: int = None, performer: str = None, title: str = None, - thumbs: List[Thumbnail] = None, + thumbs: List[Thumbnail] = None ): super().__init__(client) diff --git a/pyrogram/client/types/messages_and_media/document.py b/pyrogram/client/types/messages_and_media/document.py index 023e4204..45994e16 100644 --- a/pyrogram/client/types/messages_and_media/document.py +++ b/pyrogram/client/types/messages_and_media/document.py @@ -60,7 +60,7 @@ class Document(Object): mime_type: str = None, file_size: int = None, date: int = None, - thumbs: List[Thumbnail] = None, + thumbs: List[Thumbnail] = None ): super().__init__(client) diff --git a/pyrogram/client/types/messages_and_media/stripped_thumbnail.py b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py index 4dbeb7d1..1c967042 100644 --- a/pyrogram/client/types/messages_and_media/stripped_thumbnail.py +++ b/pyrogram/client/types/messages_and_media/stripped_thumbnail.py @@ -35,7 +35,7 @@ class StrippedThumbnail(Object): self, *, client: "pyrogram.BaseClient" = None, - data: bytes, + data: bytes ): super().__init__(client) From b46ffe1414a0448d1b813278a0b5b30e0a6d2f84 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 7 Jun 2019 18:53:45 +0200 Subject: [PATCH 156/202] Update Pyrogram to v0.14.1 --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index ac184844..b15bd0c5 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -24,7 +24,7 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]: # Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one. sys.modules["typing"] = typing -__version__ = "0.15.0-develop" +__version__ = "0.14.1" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __copyright__ = "Copyright (C) 2017-2019 Dan " From 2e05c81a5c3727143d3c3190d673c32fe713523e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 11:33:52 +0200 Subject: [PATCH 157/202] Update docs about Telegram data centers --- docs/source/faq.rst | 23 ++++++++++++++------ pyrogram/client/methods/users/get_user_dc.py | 6 +++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 1800a032..6ff16559 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -134,14 +134,23 @@ in a bunch of seconds: import logging logging.basicConfig(level=logging.INFO) -Another way to confirm you aren't able to connect to Telegram is by pinging these IP addresses and see whether ping -fails or not: +Another way to confirm you aren't able to connect to Telegram is by pinging the IP addresses below and see whether ping +fails or not. -- DC1: ``149.154.175.50`` -- DC2: ``149.154.167.51`` -- DC3: ``149.154.175.100`` -- DC4: ``149.154.167.91`` -- DC5: ``91.108.56.149`` +What are the IP addresses of Telegram Data Centers? +--------------------------------------------------- + +Telegram is currently composed by a decentralized, multi-DC infrastructure (each of which can work independently) spread +in 5 different locations. However, two of the less busy DCs have been lately dismissed and their IP addresses are now +kept as aliases. + +- **DC1** - MIA, Miami FL, USA: ``149.154.175.50`` +- **DC2** - AMS, Amsterdam, NL: ``149.154.167.51`` +- **DC3*** - MIA, Miami FL, USA: ``149.154.175.100`` +- **DC4*** - AMS, Amsterdam, NL: ``149.154.167.91`` +- **DC5** - SIN, Singapore, SG: ``91.108.56.149`` + +***** Alias DC I keep getting PEER_ID_INVALID error! ------------------------------------------- diff --git a/pyrogram/client/methods/users/get_user_dc.py b/pyrogram/client/methods/users/get_user_dc.py index 89e97526..7cb43d83 100644 --- a/pyrogram/client/methods/users/get_user_dc.py +++ b/pyrogram/client/methods/users/get_user_dc.py @@ -26,6 +26,12 @@ class GetUserDC(BaseClient): def get_user_dc(self, user_id: Union[int, str]) -> Union[int, None]: """Get the assigned data center (DC) of a user. + .. note:: + + This information is approximate: it is based on where the user stores their profile pictures and does not by + any means tell you the user location. More info at + `FAQs <../faq#what-are-the-ip-addresses-of-telegram-data-centers>`_. + Parameters: user_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. From 2db2ca3283ed433e4e8be5512eca1b0fc571a987 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 13:49:01 +0200 Subject: [PATCH 158/202] Remove ChatMembers type --- docs/source/api/types.rst | 2 - .../client/methods/chats/get_chat_member.py | 9 ++- .../client/methods/chats/get_chat_members.py | 48 +++++++------ .../client/methods/chats/iter_chat_members.py | 2 +- pyrogram/client/types/__init__.py | 2 + .../client/types/user_and_chats/__init__.py | 4 +- .../types/user_and_chats/chat_members.py | 71 ------------------- 7 files changed, 38 insertions(+), 100 deletions(-) delete mode 100644 pyrogram/client/types/user_and_chats/chat_members.py diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 4eef9638..0aab7b5e 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -30,7 +30,6 @@ Users & Chats - :class:`ChatPreview` - :class:`ChatPhoto` - :class:`ChatMember` - - :class:`ChatMembers` - :class:`ChatPermissions` - :class:`Dialog` - :class:`Dialogs` @@ -123,7 +122,6 @@ Details .. autoclass:: ChatPreview() .. autoclass:: ChatPhoto() .. autoclass:: ChatMember() -.. autoclass:: ChatMembers() .. autoclass:: ChatPermissions() .. autoclass:: Dialog() .. autoclass:: Dialogs() diff --git a/pyrogram/client/methods/chats/get_chat_member.py b/pyrogram/client/methods/chats/get_chat_member.py index b84836c6..b0d0641a 100644 --- a/pyrogram/client/methods/chats/get_chat_member.py +++ b/pyrogram/client/methods/chats/get_chat_member.py @@ -51,13 +51,18 @@ class GetChatMember(BaseClient): user = self.resolve_peer(user_id) if isinstance(chat, types.InputPeerChat): - full_chat = self.send( + r = self.send( functions.messages.GetFullChat( chat_id=chat.chat_id ) ) - for member in pyrogram.ChatMembers._parse(self, full_chat).chat_members: + members = r.full_chat.participants.participants + users = {i.id: i for i in r.users} + + for member in members: + member = pyrogram.ChatMember._parse(self, member, users) + if isinstance(user, types.InputPeerSelf): if member.user.is_self: return member diff --git a/pyrogram/client/methods/chats/get_chat_members.py b/pyrogram/client/methods/chats/get_chat_members.py index 1c966f36..0b4613d8 100644 --- a/pyrogram/client/methods/chats/get_chat_members.py +++ b/pyrogram/client/methods/chats/get_chat_members.py @@ -18,7 +18,7 @@ import logging import time -from typing import Union +from typing import Union, List import pyrogram from pyrogram.api import functions, types @@ -45,7 +45,7 @@ class GetChatMembers(BaseClient): limit: int = 200, query: str = "", filter: str = Filters.ALL - ) -> "pyrogram.ChatMembers": + ) -> List["pyrogram.ChatMember"]: """Get a chunk of the members list of a chat. You can get up to 200 chat members at once. @@ -59,15 +59,16 @@ class GetChatMembers(BaseClient): offset (``int``, *optional*): Sequential number of the first member to be returned. - Defaults to 0 [1]_. + Only applicable to supergroups and channels. Defaults to 0 [1]_. limit (``int``, *optional*): Limits the number of members to be retrieved. + Only applicable to supergroups and channels. Defaults to 200, which is also the maximum server limit allowed per method call. query (``str``, *optional*): Query string to filter members based on their display names and usernames. - Defaults to "" (empty string) [2]_. + Only applicable to supergroups and channels. Defaults to "" (empty string) [2]_. filter (``str``, *optional*): Filter used to select the kind of members you want to retrieve. Only applicable for supergroups @@ -78,6 +79,7 @@ class GetChatMembers(BaseClient): *"bots"* - bots only, *"recent"* - recent members only, *"administrators"* - chat administrators only. + Only applicable to supergroups and channels. Defaults to *"all"*. .. [1] Server limit: on supergroups, you can get up to 10,000 members for a single query and up to 200 members @@ -86,7 +88,7 @@ class GetChatMembers(BaseClient): .. [2] A query string is applicable only for *"all"*, *"kicked"* and *"restricted"* filters only. Returns: - :obj:`ChatMembers`: On success, an object containing a list of chat members is returned. + List of :obj:`ChatMember`: On success, a list of chat members is returned. Raises: RPCError: In case of a Telegram RPC error. @@ -95,14 +97,16 @@ class GetChatMembers(BaseClient): peer = self.resolve_peer(chat_id) if isinstance(peer, types.InputPeerChat): - return pyrogram.ChatMembers._parse( - self, - self.send( - functions.messages.GetFullChat( - chat_id=peer.chat_id - ) + r = self.send( + functions.messages.GetFullChat( + chat_id=peer.chat_id ) ) + + members = r.full_chat.participants.participants + users = {i.id: i for i in r.users} + + return pyrogram.List(pyrogram.ChatMember._parse(self, member, users) for member in members) elif isinstance(peer, types.InputPeerChannel): filter = filter.lower() @@ -123,18 +127,20 @@ class GetChatMembers(BaseClient): while True: try: - return pyrogram.ChatMembers._parse( - self, - self.send( - functions.channels.GetParticipants( - channel=peer, - filter=filter, - offset=offset, - limit=limit, - hash=0 - ) + r = self.send( + functions.channels.GetParticipants( + channel=peer, + filter=filter, + offset=offset, + limit=limit, + hash=0 ) ) + + members = r.participants + users = {i.id: i for i in r.users} + + return pyrogram.List(pyrogram.ChatMember._parse(self, member, users) for member in members) except FloodWait as e: log.warning("Sleeping for {}s".format(e.x)) time.sleep(e.x) diff --git a/pyrogram/client/methods/chats/iter_chat_members.py b/pyrogram/client/methods/chats/iter_chat_members.py index 961f6d98..fe117694 100644 --- a/pyrogram/client/methods/chats/iter_chat_members.py +++ b/pyrogram/client/methods/chats/iter_chat_members.py @@ -106,7 +106,7 @@ class IterChatMembers(BaseClient): limit=limit, query=q, filter=filter - ).chat_members + ) if not chat_members: break diff --git a/pyrogram/client/types/__init__.py b/pyrogram/client/types/__init__.py index 3d430c44..8a725a9e 100644 --- a/pyrogram/client/types/__init__.py +++ b/pyrogram/client/types/__init__.py @@ -20,6 +20,8 @@ from .keyboards import * from .inline_mode import * from .input_media import * from .input_message_content import * +from .list import List from .messages_and_media import * +from .object import Object from .update import * from .user_and_chats import * diff --git a/pyrogram/client/types/user_and_chats/__init__.py b/pyrogram/client/types/user_and_chats/__init__.py index 2059589a..cf032850 100644 --- a/pyrogram/client/types/user_and_chats/__init__.py +++ b/pyrogram/client/types/user_and_chats/__init__.py @@ -18,7 +18,6 @@ from .chat import Chat from .chat_member import ChatMember -from .chat_members import ChatMembers from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto from .chat_preview import ChatPreview @@ -28,6 +27,5 @@ from .user import User from .user_status import UserStatus __all__ = [ - "Chat", "ChatMember", "ChatMembers", "ChatPermissions", "ChatPhoto", "ChatPreview", "Dialog", "Dialogs", "User", - "UserStatus" + "Chat", "ChatMember", "ChatPermissions", "ChatPhoto", "ChatPreview", "Dialog", "Dialogs", "User", "UserStatus" ] diff --git a/pyrogram/client/types/user_and_chats/chat_members.py b/pyrogram/client/types/user_and_chats/chat_members.py deleted file mode 100644 index 6abdd719..00000000 --- a/pyrogram/client/types/user_and_chats/chat_members.py +++ /dev/null @@ -1,71 +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 typing import List - -import pyrogram -from pyrogram.api import types -from .chat_member import ChatMember -from ..object import Object - - -class ChatMembers(Object): - """Contains information about the members list of a chat. - - Parameters: - total_count (``int``): - Total number of members the chat has. - - chat_members (List of :obj:`ChatMember `): - Requested chat members. - """ - - __slots__ = ["total_count", "chat_members"] - - def __init__( - self, - *, - client: "pyrogram.BaseClient" = None, - total_count: int, - chat_members: List[ChatMember] - ): - super().__init__(client) - - self.total_count = total_count - self.chat_members = chat_members - - @staticmethod - def _parse(client, members): - users = {i.id: i for i in members.users} - chat_members = [] - - if isinstance(members, types.channels.ChannelParticipants): - total_count = members.count - members = members.participants - else: - members = members.full_chat.participants.participants - total_count = len(members) - - for member in members: - chat_members.append(ChatMember._parse(client, member, users)) - - return ChatMembers( - total_count=total_count, - chat_members=chat_members, - client=client - ) From c8fd446cb6185b52d9da9090a2c4b9811dd9162a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 14:00:00 +0200 Subject: [PATCH 159/202] Remove Dialogs type --- docs/source/api/types.rst | 2 - pyrogram/client/methods/chats/get_dialogs.py | 35 +++++++- pyrogram/client/methods/chats/iter_dialogs.py | 4 +- .../client/types/user_and_chats/__init__.py | 3 +- .../client/types/user_and_chats/dialogs.py | 87 ------------------- 5 files changed, 35 insertions(+), 96 deletions(-) delete mode 100644 pyrogram/client/types/user_and_chats/dialogs.py diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 0aab7b5e..957cfa52 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -32,7 +32,6 @@ Users & Chats - :class:`ChatMember` - :class:`ChatPermissions` - :class:`Dialog` - - :class:`Dialogs` Messages & Media ^^^^^^^^^^^^^^^^ @@ -124,7 +123,6 @@ Details .. autoclass:: ChatMember() .. autoclass:: ChatPermissions() .. autoclass:: Dialog() -.. autoclass:: Dialogs() .. Messages & Media .. autoclass:: Message() diff --git a/pyrogram/client/methods/chats/get_dialogs.py b/pyrogram/client/methods/chats/get_dialogs.py index 8d5baa15..8c374a44 100644 --- a/pyrogram/client/methods/chats/get_dialogs.py +++ b/pyrogram/client/methods/chats/get_dialogs.py @@ -18,6 +18,7 @@ import logging import time +from typing import List import pyrogram from pyrogram.api import functions, types @@ -33,7 +34,7 @@ class GetDialogs(BaseClient): offset_date: int = 0, limit: int = 100, pinned_only: bool = False - ) -> "pyrogram.Dialogs": + ) -> List["pyrogram.Dialog"]: """Get a chunk of the user's dialogs. You can get up to 100 dialogs at once. @@ -53,7 +54,7 @@ class GetDialogs(BaseClient): Defaults to False. Returns: - :obj:`Dialogs`: On success, an object containing a list of dialogs is returned. + List of :obj:`Dialog`: On success, a list of dialogs is returned. Raises: RPCError: In case of a Telegram RPC error. @@ -80,4 +81,32 @@ class GetDialogs(BaseClient): else: break - return pyrogram.Dialogs._parse(self, r) + users = {i.id: i for i in r.users} + chats = {i.id: i for i in r.chats} + + messages = {} + + for message in r.messages: + to_id = message.to_id + + if isinstance(to_id, types.PeerUser): + if message.out: + 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)) + + messages[chat_id] = pyrogram.Message._parse(self, message, users, chats) + + parsed_dialogs = [] + + for dialog in r.dialogs: + if not isinstance(dialog, types.Dialog): + continue + + parsed_dialogs.append(pyrogram.Dialog._parse(self, dialog, messages, users, chats)) + + return pyrogram.List(parsed_dialogs) diff --git a/pyrogram/client/methods/chats/iter_dialogs.py b/pyrogram/client/methods/chats/iter_dialogs.py index e7fb7330..fce9fb99 100644 --- a/pyrogram/client/methods/chats/iter_dialogs.py +++ b/pyrogram/client/methods/chats/iter_dialogs.py @@ -55,7 +55,7 @@ class IterDialogs(BaseClient): pinned_dialogs = self.get_dialogs( pinned_only=True - ).dialogs + ) for dialog in pinned_dialogs: yield dialog @@ -69,7 +69,7 @@ class IterDialogs(BaseClient): dialogs = self.get_dialogs( offset_date=offset_date, limit=limit - ).dialogs + ) if not dialogs: return diff --git a/pyrogram/client/types/user_and_chats/__init__.py b/pyrogram/client/types/user_and_chats/__init__.py index cf032850..922ac86a 100644 --- a/pyrogram/client/types/user_and_chats/__init__.py +++ b/pyrogram/client/types/user_and_chats/__init__.py @@ -22,10 +22,9 @@ from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto from .chat_preview import ChatPreview from .dialog import Dialog -from .dialogs import Dialogs from .user import User from .user_status import UserStatus __all__ = [ - "Chat", "ChatMember", "ChatPermissions", "ChatPhoto", "ChatPreview", "Dialog", "Dialogs", "User", "UserStatus" + "Chat", "ChatMember", "ChatPermissions", "ChatPhoto", "ChatPreview", "Dialog", "User", "UserStatus" ] diff --git a/pyrogram/client/types/user_and_chats/dialogs.py b/pyrogram/client/types/user_and_chats/dialogs.py deleted file mode 100644 index 56cdfc72..00000000 --- a/pyrogram/client/types/user_and_chats/dialogs.py +++ /dev/null @@ -1,87 +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 typing import List - -import pyrogram -from pyrogram.api import types -from .dialog import Dialog -from ..messages_and_media import Message -from ..object import Object - - -class Dialogs(Object): - """Contains a user's dialogs chunk. - - Parameters: - total_count (``int``): - Total number of dialogs the user has. - - dialogs (List of :obj:`Dialog`): - Requested dialogs. - """ - - __slots__ = ["total_count", "dialogs"] - - def __init__( - self, - *, - client: "pyrogram.BaseClient" = None, - total_count: int, - dialogs: List[Dialog] - ): - super().__init__(client) - - self.total_count = total_count - self.dialogs = dialogs - - @staticmethod - def _parse(client, dialogs: types.messages.Dialogs) -> "Dialogs": - users = {i.id: i for i in dialogs.users} - chats = {i.id: i for i in dialogs.chats} - - messages = {} - - for message in dialogs.messages: - to_id = message.to_id - - if isinstance(to_id, types.PeerUser): - if message.out: - 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)) - - messages[chat_id] = Message._parse(client, message, users, chats) - - parsed_dialogs = [] - - for dialog in dialogs.dialogs: - if not isinstance(dialog, types.Dialog): - continue - - parsed_dialogs.append(Dialog._parse(client, dialog, messages, users, chats)) - - return Dialogs( - total_count=getattr(dialogs, "count", len(dialogs.dialogs)), - dialogs=parsed_dialogs, - client=client - ) From 797de058e8cbaa0128d6879f390c658f550f2872 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 14:08:39 +0200 Subject: [PATCH 160/202] Remove ProfilePhotos type --- docs/source/api/types.rst | 2 - .../methods/users/get_profile_photos.py | 28 ++++----- .../methods/users/iter_profile_photos.py | 2 +- .../types/messages_and_media/__init__.py | 4 +- .../messages_and_media/profile_photos.py | 57 ------------------- 5 files changed, 14 insertions(+), 79 deletions(-) delete mode 100644 pyrogram/client/types/messages_and_media/profile_photos.py diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 957cfa52..a18e01a6 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -43,7 +43,6 @@ Messages & Media - :class:`Messages` - :class:`MessageEntity` - :class:`Photo` - - :class:`ProfilePhotos` - :class:`Thumbnail` - :class:`Audio` - :class:`Document` @@ -129,7 +128,6 @@ Details .. autoclass:: Messages() .. autoclass:: MessageEntity() .. autoclass:: Photo() -.. autoclass:: ProfilePhotos() .. autoclass:: Thumbnail() .. autoclass:: Audio() .. autoclass:: Document() diff --git a/pyrogram/client/methods/users/get_profile_photos.py b/pyrogram/client/methods/users/get_profile_photos.py index e4e202e0..32e7e513 100644 --- a/pyrogram/client/methods/users/get_profile_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import Union +from typing import Union, List import pyrogram from pyrogram.api import functions, types @@ -29,7 +29,7 @@ class GetProfilePhotos(BaseClient): chat_id: Union[int, str], offset: int = 0, limit: int = 100 - ) -> "pyrogram.ProfilePhotos": + ) -> List["pyrogram.Photo"]: """Get a list of profile pictures for a user or a chat. Parameters: @@ -47,7 +47,7 @@ class GetProfilePhotos(BaseClient): Values between 1—100 are accepted. Defaults to 100. Returns: - :obj:`ProfilePhotos`: On success, an object containing a list of the profile photos is returned. + List of :obj:`Photo`: On success, a list of profile photos is returned. Raises: RPCError: In case of a Telegram RPC error. @@ -55,17 +55,16 @@ class GetProfilePhotos(BaseClient): peer_id = self.resolve_peer(chat_id) if isinstance(peer_id, types.InputPeerUser): - return pyrogram.ProfilePhotos._parse( - self, - self.send( - functions.photos.GetUserPhotos( - user_id=peer_id, - offset=offset, - max_id=0, - limit=limit - ) + r = self.send( + functions.photos.GetUserPhotos( + user_id=peer_id, + offset=offset, + max_id=0, + limit=limit ) ) + + return pyrogram.List(pyrogram.Photo._parse(self, photo) for photo in r.photos) else: new_chat_photos = pyrogram.Messages._parse( self, @@ -86,7 +85,4 @@ class GetProfilePhotos(BaseClient): ) ) - return pyrogram.ProfilePhotos( - total_count=new_chat_photos.total_count, - profile_photos=[m.new_chat_photo for m in new_chat_photos.messages][:limit] - ) + return pyrogram.List([m.new_chat_photo for m in new_chat_photos.messages][:limit]) diff --git a/pyrogram/client/methods/users/iter_profile_photos.py b/pyrogram/client/methods/users/iter_profile_photos.py index 1773634e..49317f87 100644 --- a/pyrogram/client/methods/users/iter_profile_photos.py +++ b/pyrogram/client/methods/users/iter_profile_photos.py @@ -63,7 +63,7 @@ class IterProfilePhotos(BaseClient): chat_id=chat_id, offset=offset, limit=limit - ).photos + ) if not photos: return diff --git a/pyrogram/client/types/messages_and_media/__init__.py b/pyrogram/client/types/messages_and_media/__init__.py index 17a6e36a..2de2c6a3 100644 --- a/pyrogram/client/types/messages_and_media/__init__.py +++ b/pyrogram/client/types/messages_and_media/__init__.py @@ -28,7 +28,6 @@ from .messages import Messages from .photo import Photo from .poll import Poll from .poll_option import PollOption -from .profile_photos import ProfilePhotos from .sticker import Sticker from .stripped_thumbnail import StrippedThumbnail from .thumbnail import Thumbnail @@ -39,6 +38,5 @@ from .voice import Voice __all__ = [ "Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Messages", "Photo", - "Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "ProfilePhotos", "Venue", "Video", "VideoNote", - "Voice" + "Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice" ] diff --git a/pyrogram/client/types/messages_and_media/profile_photos.py b/pyrogram/client/types/messages_and_media/profile_photos.py deleted file mode 100644 index 11b8e4dd..00000000 --- a/pyrogram/client/types/messages_and_media/profile_photos.py +++ /dev/null @@ -1,57 +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 typing import List - -import pyrogram -from .photo import Photo -from ..object import Object - - -class ProfilePhotos(Object): - """Contains a user's profile pictures. - - Parameters: - total_count (``int``): - Total number of profile pictures the target user has. - - profile_photos (List of :obj:`Photo`): - Requested profile pictures. - """ - - __slots__ = ["total_count", "profile_photos"] - - def __init__( - self, - *, - client: "pyrogram.BaseClient" = None, - total_count: int, - profile_photos: List[Photo] - ): - super().__init__(client) - - self.total_count = total_count - self.profile_photos = profile_photos - - @staticmethod - def _parse(client, photos) -> "ProfilePhotos": - return ProfilePhotos( - total_count=getattr(photos, "count", len(photos.photos)), - profile_photos=[Photo._parse(client, photo) for photo in photos.photos], - client=client - ) From cfbc5298dfaad33fa537839f909fef1b81200980 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 15:13:52 +0200 Subject: [PATCH 161/202] Remove Messages type --- docs/source/api/types.rst | 2 - pyrogram/client/ext/dispatcher.py | 3 +- pyrogram/client/ext/utils.py | 58 +++++- .../handlers/deleted_messages_handler.py | 13 +- .../methods/messages/forward_messages.py | 26 +-- .../client/methods/messages/get_history.py | 13 +- .../client/methods/messages/get_messages.py | 16 +- .../client/methods/messages/iter_history.py | 2 +- .../methods/messages/send_media_group.py | 6 +- .../methods/users/get_profile_photos.py | 5 +- .../types/messages_and_media/__init__.py | 5 +- .../types/messages_and_media/message.py | 2 +- .../types/messages_and_media/messages.py | 170 ------------------ 13 files changed, 100 insertions(+), 221 deletions(-) delete mode 100644 pyrogram/client/types/messages_and_media/messages.py diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index a18e01a6..66d409c4 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -40,7 +40,6 @@ Messages & Media :columns: 5 - :class:`Message` - - :class:`Messages` - :class:`MessageEntity` - :class:`Photo` - :class:`Thumbnail` @@ -125,7 +124,6 @@ Details .. Messages & Media .. autoclass:: Message() -.. autoclass:: Messages() .. autoclass:: MessageEntity() .. autoclass:: Photo() .. autoclass:: Thumbnail() diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 2f1ec2b9..12d5a5de 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -21,6 +21,7 @@ import threading from collections import OrderedDict from queue import Queue from threading import Thread +from . import utils import pyrogram from pyrogram.api import types @@ -68,7 +69,7 @@ class Dispatcher: lambda upd, usr, cht: (pyrogram.Message._parse(self.client, upd.message, usr, cht), MessageHandler), Dispatcher.DELETE_MESSAGES_UPDATES: - lambda upd, usr, cht: (pyrogram.Messages._parse_deleted(self.client, upd), DeletedMessagesHandler), + lambda upd, usr, cht: (utils.parse_deleted_messages(self.client, upd), DeletedMessagesHandler), Dispatcher.CALLBACK_QUERY_UPDATES: lambda upd, usr, cht: (pyrogram.CallbackQuery._parse(self.client, upd, usr), CallbackQueryHandler), diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index e1959309..41270d39 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -18,8 +18,9 @@ import struct from base64 import b64decode, b64encode -from typing import Union +from typing import Union, List +import pyrogram from . import BaseClient from ...api import types @@ -135,3 +136,58 @@ def get_input_media_from_file_id( ) raise ValueError("Unknown media type: {}".format(file_id_str)) + + +def parse_messages(client, messages: types.messages.Messages, replies: int = 1) -> List["pyrogram.Message"]: + users = {i.id: i for i in messages.users} + chats = {i.id: i for i in messages.chats} + + if not messages.messages: + return pyrogram.List() + + parsed_messages = [ + pyrogram.Message._parse(client, message, users, chats, replies=0) + for message in messages.messages + ] + + if replies: + messages_with_replies = {i.id: getattr(i, "reply_to_msg_id", None) for i in messages.messages} + reply_message_ids = [i[0] for i in filter(lambda x: x[1] is not None, messages_with_replies.items())] + + if reply_message_ids: + reply_messages = client.get_messages( + parsed_messages[0].chat.id, + reply_to_message_ids=reply_message_ids, + replies=replies - 1 + ) + + for message in parsed_messages: + reply_id = messages_with_replies[message.message_id] + + for reply in reply_messages: + if reply.message_id == reply_id: + message.reply_to_message = reply + + return pyrogram.List(parsed_messages) + + +def parse_deleted_messages(client, update) -> List["pyrogram.Message"]: + messages = update.messages + channel_id = getattr(update, "channel_id", None) + + parsed_messages = [] + + for message in messages: + parsed_messages.append( + pyrogram.Message( + message_id=message, + chat=pyrogram.Chat( + id=int("-100" + str(channel_id)), + type="channel", + client=client + ) if channel_id is not None else None, + client=client + ) + ) + + return pyrogram.List(parsed_messages) diff --git a/pyrogram/client/handlers/deleted_messages_handler.py b/pyrogram/client/handlers/deleted_messages_handler.py index b6651fba..3230b9bd 100644 --- a/pyrogram/client/handlers/deleted_messages_handler.py +++ b/pyrogram/client/handlers/deleted_messages_handler.py @@ -20,16 +20,15 @@ from .handler import Handler class DeletedMessagesHandler(Handler): - """The deleted Messages handler class. Used to handle deleted messages coming from any chat - (private, group, channel). It is intended to be used with - :meth:`~Client.add_handler` + """The deleted messages handler class. Used to handle deleted messages coming from any chat + (private, group, channel). It is intended to be used with :meth:`~Client.add_handler` For a nicer way to register this handler, have a look at the :meth:`~Client.on_deleted_messages` decorator. Parameters: callback (``callable``): - Pass a function that will be called when one or more Messages have been deleted. + Pass a function that will be called when one or more messages have been deleted. It takes *(client, messages)* as positional arguments (look at the section below for a detailed description). filters (:obj:`Filters`): @@ -40,12 +39,12 @@ class DeletedMessagesHandler(Handler): client (:obj:`Client`): The Client itself, useful when you want to call other API methods inside the message handler. - messages (:obj:`Messages`): - The deleted messages. + messages (List of :obj:`Message`): + The deleted messages, as list. """ def __init__(self, callback: callable, filters=None): super().__init__(callback, filters) def check(self, messages): - return super().check(messages.messages[0]) + return super().check(messages[0]) diff --git a/pyrogram/client/methods/messages/forward_messages.py b/pyrogram/client/methods/messages/forward_messages.py index bc9ad331..c69df608 100644 --- a/pyrogram/client/methods/messages/forward_messages.py +++ b/pyrogram/client/methods/messages/forward_messages.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import Union, Iterable +from typing import Union, Iterable, List import pyrogram from pyrogram.api import functions, types @@ -32,7 +32,7 @@ class ForwardMessages(BaseClient): disable_notification: bool = None, as_copy: bool = False, remove_caption: bool = False - ) -> "pyrogram.Messages": + ) -> List["pyrogram.Message"]: """Forward messages of any kind. Parameters: @@ -64,9 +64,9 @@ class ForwardMessages(BaseClient): Defaults to False. Returns: - :obj:`Message` | :obj:`Messages`: In case *message_ids* was an integer, the single forwarded message is - returned, otherwise, in case *message_ids* was an iterable, the returned value will be an object containing - a list of messages, even if such iterable contained just a single element. + :obj:`Message` | List of :obj:`Message`: In case *message_ids* was an integer, the single forwarded message + is returned, otherwise, in case *message_ids* was an iterable, the returned value will be a list of + messages, even if such iterable contained just a single element. Raises: RPCError: In case of a Telegram RPC error. @@ -79,9 +79,9 @@ class ForwardMessages(BaseClient): forwarded_messages = [] for chunk in [message_ids[i:i + 200] for i in range(0, len(message_ids), 200)]: - messages = self.get_messages(chat_id=from_chat_id, message_ids=chunk) # type: pyrogram.Messages + messages = self.get_messages(chat_id=from_chat_id, message_ids=chunk) - for message in messages.messages: + for message in messages: forwarded_messages.append( message.forward( chat_id, @@ -91,11 +91,7 @@ class ForwardMessages(BaseClient): ) ) - return pyrogram.Messages( - client=self, - total_count=len(forwarded_messages), - messages=forwarded_messages - ) if is_iterable else forwarded_messages[0] + return pyrogram.List(forwarded_messages) if is_iterable else forwarded_messages[0] else: r = self.send( functions.messages.ForwardMessages( @@ -121,8 +117,4 @@ class ForwardMessages(BaseClient): ) ) - return pyrogram.Messages( - client=self, - total_count=len(forwarded_messages), - messages=forwarded_messages - ) if is_iterable else forwarded_messages[0] + return pyrogram.List(forwarded_messages) if is_iterable else forwarded_messages[0] diff --git a/pyrogram/client/methods/messages/get_history.py b/pyrogram/client/methods/messages/get_history.py index c0810474..8adafe22 100644 --- a/pyrogram/client/methods/messages/get_history.py +++ b/pyrogram/client/methods/messages/get_history.py @@ -18,10 +18,11 @@ import logging import time -from typing import Union +from typing import Union, List import pyrogram from pyrogram.api import functions +from pyrogram.client.ext import utils from pyrogram.errors import FloodWait from ...ext import BaseClient @@ -37,7 +38,7 @@ class GetHistory(BaseClient): offset_id: int = 0, offset_date: int = 0, reverse: bool = False - ) -> "pyrogram.Messages": + ) -> List["pyrogram.Message"]: """Retrieve a chunk of the history of a chat. You can get up to 100 messages at once. @@ -67,15 +68,17 @@ class GetHistory(BaseClient): Pass True to retrieve the messages in reversed order (from older to most recent). Returns: - :obj:`Messages` - On success, an object containing a list of the retrieved messages. + List of :obj:`Message` - On success, a list of the retrieved messages is returned. Raises: RPCError: In case of a Telegram RPC error. """ + offset_id = offset_id or (1 if reverse else 0) + while True: try: - messages = pyrogram.Messages._parse( + messages = utils.parse_messages( self, self.send( functions.messages.GetHistory( @@ -97,6 +100,6 @@ class GetHistory(BaseClient): break if reverse: - messages.messages.reverse() + messages.reverse() return messages diff --git a/pyrogram/client/methods/messages/get_messages.py b/pyrogram/client/methods/messages/get_messages.py index 7a60f276..0f901174 100644 --- a/pyrogram/client/methods/messages/get_messages.py +++ b/pyrogram/client/methods/messages/get_messages.py @@ -18,12 +18,12 @@ import logging import time -from typing import Union, Iterable +from typing import Union, Iterable, 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__) @@ -35,7 +35,7 @@ class GetMessages(BaseClient): message_ids: Union[int, Iterable[int]] = None, reply_to_message_ids: Union[int, Iterable[int]] = None, replies: int = 1 - ) -> Union["pyrogram.Message", "pyrogram.Messages"]: + ) -> Union["pyrogram.Message", List["pyrogram.Message"]]: """Get one or more messages that belong to a specific chat. You can retrieve up to 200 messages at once. @@ -60,9 +60,9 @@ class GetMessages(BaseClient): Defaults to 1. Returns: - :obj:`Message` | :obj:`Messages`: In case *message_ids* was an integer, the single requested message is - returned, otherwise, in case *message_ids* was an iterable, the returned value will be an object containing - a list of messages, even if such iterable contained just a single element. + :obj:`Message` | List of :obj:`Message`: In case *message_ids* was an integer, the single requested message is + returned, otherwise, in case *message_ids* was an iterable, the returned value will be a list of messages, + even if such iterable contained just a single element. Raises: RPCError: In case of a Telegram RPC error. @@ -99,6 +99,6 @@ class GetMessages(BaseClient): else: break - messages = pyrogram.Messages._parse(self, r, replies=replies) + messages = utils.parse_messages(self, r, replies=replies) - return messages if is_iterable else messages.messages[0] + return messages if is_iterable else messages[0] diff --git a/pyrogram/client/methods/messages/iter_history.py b/pyrogram/client/methods/messages/iter_history.py index 57da3da5..15c48c95 100644 --- a/pyrogram/client/methods/messages/iter_history.py +++ b/pyrogram/client/methods/messages/iter_history.py @@ -80,7 +80,7 @@ class IterHistory(BaseClient): offset_id=offset_id, offset_date=offset_date, reverse=reverse - ).messages + ) if not messages: return diff --git a/pyrogram/client/methods/messages/send_media_group.py b/pyrogram/client/methods/messages/send_media_group.py index fb029a66..194a2202 100644 --- a/pyrogram/client/methods/messages/send_media_group.py +++ b/pyrogram/client/methods/messages/send_media_group.py @@ -38,7 +38,7 @@ class SendMediaGroup(BaseClient): media: List[Union["pyrogram.InputMediaPhoto", "pyrogram.InputMediaVideo"]], disable_notification: bool = None, reply_to_message_id: int = None - ): + ) -> List["pyrogram.Message"]: """Send a group of photos or videos as an album. Parameters: @@ -58,7 +58,7 @@ class SendMediaGroup(BaseClient): If the message is a reply, ID of the original message. Returns: - :obj:`Messages`: On success, an object is returned containing all the single messages sent. + List of :obj:`Message`: On success, a list of the sent messages is returned. Raises: RPCError: In case of a Telegram RPC error. @@ -158,7 +158,7 @@ class SendMediaGroup(BaseClient): else: break - return pyrogram.Messages._parse( + return utils.parse_messages( self, types.messages.Messages( messages=[m.message for m in filter( diff --git a/pyrogram/client/methods/users/get_profile_photos.py b/pyrogram/client/methods/users/get_profile_photos.py index 32e7e513..eaf632e2 100644 --- a/pyrogram/client/methods/users/get_profile_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -20,6 +20,7 @@ from typing import Union, List import pyrogram from pyrogram.api import functions, types +from pyrogram.client.ext import utils from ...ext import BaseClient @@ -66,7 +67,7 @@ class GetProfilePhotos(BaseClient): return pyrogram.List(pyrogram.Photo._parse(self, photo) for photo in r.photos) else: - new_chat_photos = pyrogram.Messages._parse( + r = utils.parse_messages( self, self.send( functions.messages.Search( @@ -85,4 +86,4 @@ class GetProfilePhotos(BaseClient): ) ) - return pyrogram.List([m.new_chat_photo for m in new_chat_photos.messages][:limit]) + return pyrogram.List([message.new_chat_photo for message in r][:limit]) diff --git a/pyrogram/client/types/messages_and_media/__init__.py b/pyrogram/client/types/messages_and_media/__init__.py index 2de2c6a3..b9bcb460 100644 --- a/pyrogram/client/types/messages_and_media/__init__.py +++ b/pyrogram/client/types/messages_and_media/__init__.py @@ -24,7 +24,6 @@ from .game import Game from .location import Location from .message import Message from .message_entity import MessageEntity -from .messages import Messages from .photo import Photo from .poll import Poll from .poll_option import PollOption @@ -37,6 +36,6 @@ from .video_note import VideoNote from .voice import Voice __all__ = [ - "Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Messages", "Photo", - "Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice" + "Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Photo", "Thumbnail", + "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice" ] diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index f7dff7b5..f7e99d0a 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -2617,7 +2617,7 @@ class Message(Object, Update): ) if self.photo: - file_id = self.photo.sizes[-1].file_id + file_id = self.photo.file_id elif self.audio: file_id = self.audio.file_id elif self.document: diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py deleted file mode 100644 index ee516f20..00000000 --- a/pyrogram/client/types/messages_and_media/messages.py +++ /dev/null @@ -1,170 +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 typing import List, Union - -import pyrogram -from pyrogram.api import types -from .message import Message -from ..object import Object -from ..update import Update -from ..user_and_chats import Chat - - -class Messages(Object, Update): - """Contains a chat's messages. - - Parameters: - total_count (``int``): - Total number of messages the target chat has. - - messages (List of :obj:`Message`): - Requested messages. - """ - - __slots__ = ["total_count", "messages"] - - def __init__( - self, - *, - client: "pyrogram.BaseClient" = None, - total_count: int, - messages: List[Message] - ): - super().__init__(client) - - self.total_count = total_count - self.messages = messages - - @staticmethod - def _parse(client, messages: types.messages.Messages, replies: int = 1) -> "Messages": - users = {i.id: i for i in messages.users} - chats = {i.id: i for i in messages.chats} - - total_count = getattr(messages, "count", len(messages.messages)) - - if not messages.messages: - return Messages( - total_count=total_count, - messages=[], - client=client - ) - - parsed_messages = [Message._parse(client, message, users, chats, replies=0) for message in messages.messages] - - if replies: - messages_with_replies = {i.id: getattr(i, "reply_to_msg_id", None) for i in messages.messages} - reply_message_ids = [i[0] for i in filter(lambda x: x[1] is not None, messages_with_replies.items())] - - if reply_message_ids: - reply_messages = client.get_messages( - parsed_messages[0].chat.id, - reply_to_message_ids=reply_message_ids, - replies=replies - 1 - ).messages - - for message in parsed_messages: - reply_id = messages_with_replies[message.message_id] - - for reply in reply_messages: - if reply.message_id == reply_id: - message.reply_to_message = reply - - return Messages( - total_count=total_count, - messages=parsed_messages, - client=client - ) - - @staticmethod - def _parse_deleted(client, update) -> "Messages": - messages = update.messages - channel_id = getattr(update, "channel_id", None) - - parsed_messages = [] - - for message in messages: - parsed_messages.append( - Message( - message_id=message, - chat=Chat( - id=int("-100" + str(channel_id)), - type="channel", - client=client - ) if channel_id is not None else None, - client=client - ) - ) - - return Messages( - total_count=len(parsed_messages), - messages=parsed_messages, - client=client - ) - - def forward( - self, - chat_id: Union[int, str], - disable_notification: bool = None, - as_copy: bool = False, - remove_caption: bool = False - ): - """Bound method *forward* of :obj:`Message`. - - Parameters: - chat_id (``int`` | ``str``): - Unique identifier (int) or username (str) of the target chat. - For your personal cloud (Saved Messages) you can simply use "me" or "self". - For a contact that exists in your Telegram address book you can use his phone number (str). - - disable_notification (``bool``, *optional*): - Sends messages silently. - Users will receive a notification with no sound. - - as_copy (``bool``, *optional*): - Pass True to forward messages without the forward header (i.e.: send a copy of the message content). - Defaults to False. - - remove_caption (``bool``, *optional*): - If set to True and *as_copy* is enabled as well, media captions are not preserved when copying the - message. Has no effect if *as_copy* is not enabled. - Defaults to False. - - Returns: - On success, a :obj:`Messages` containing forwarded messages is returned. - - Raises: - RPCError: In case of a Telegram RPC error. - """ - forwarded_messages = [] - - for message in self.messages: - forwarded_messages.append( - message.forward( - chat_id=chat_id, - as_copy=as_copy, - disable_notification=disable_notification, - remove_caption=remove_caption - ) - ) - - return Messages( - total_count=len(forwarded_messages), - messages=forwarded_messages, - client=self._client - ) From a769fdfd20ad94f54e5caee0079ffc39a15de9a3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 15:14:28 +0200 Subject: [PATCH 162/202] Remove GameHighScores type --- docs/source/api/types.rst | 2 - .../methods/bots/get_game_high_scores.py | 21 ++++--- pyrogram/client/types/keyboards/__init__.py | 5 +- .../types/keyboards/game_high_scores.py | 60 ------------------- 4 files changed, 12 insertions(+), 76 deletions(-) delete mode 100644 pyrogram/client/types/keyboards/game_high_scores.py diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 66d409c4..118c4261 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -71,7 +71,6 @@ Keyboards - :class:`ForceReply` - :class:`CallbackQuery` - :class:`GameHighScore` - - :class:`GameHighScores` - :class:`CallbackGame` Input Media @@ -150,7 +149,6 @@ Details .. autoclass:: ForceReply() .. autoclass:: CallbackQuery() .. autoclass:: GameHighScore() -.. autoclass:: GameHighScores() .. autoclass:: CallbackGame() .. Input Media diff --git a/pyrogram/client/methods/bots/get_game_high_scores.py b/pyrogram/client/methods/bots/get_game_high_scores.py index e1472b9e..e6459bac 100644 --- a/pyrogram/client/methods/bots/get_game_high_scores.py +++ b/pyrogram/client/methods/bots/get_game_high_scores.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import Union +from typing import Union, List import pyrogram from pyrogram.api import functions @@ -29,7 +29,7 @@ class GetGameHighScores(BaseClient): user_id: Union[int, str], chat_id: Union[int, str], message_id: int = None - ) -> "pyrogram.GameHighScores": + ) -> List["pyrogram.GameHighScore"]: """Get data for high score tables. Parameters: @@ -49,20 +49,19 @@ class GetGameHighScores(BaseClient): Required if inline_message_id is not specified. Returns: - :obj:`GameHighScores`: On success. + List of :obj:`GameHighScore`: On success. Raises: RPCError: In case of a Telegram RPC error. """ # TODO: inline_message_id - return pyrogram.GameHighScores._parse( - self, - self.send( - functions.messages.GetGameHighScores( - peer=self.resolve_peer(chat_id), - id=message_id, - user_id=self.resolve_peer(user_id) - ) + r = self.send( + functions.messages.GetGameHighScores( + peer=self.resolve_peer(chat_id), + id=message_id, + user_id=self.resolve_peer(user_id) ) ) + + return pyrogram.List(pyrogram.GameHighScore._parse(self, score, r.users) for score in r.scores) diff --git a/pyrogram/client/types/keyboards/__init__.py b/pyrogram/client/types/keyboards/__init__.py index dae33e10..90376504 100644 --- a/pyrogram/client/types/keyboards/__init__.py +++ b/pyrogram/client/types/keyboards/__init__.py @@ -20,7 +20,6 @@ from .callback_game import CallbackGame from .callback_query import CallbackQuery from .force_reply import ForceReply from .game_high_score import GameHighScore -from .game_high_scores import GameHighScores from .inline_keyboard_button import InlineKeyboardButton from .inline_keyboard_markup import InlineKeyboardMarkup from .keyboard_button import KeyboardButton @@ -28,6 +27,6 @@ from .reply_keyboard_markup import ReplyKeyboardMarkup from .reply_keyboard_remove import ReplyKeyboardRemove __all__ = [ - "CallbackGame", "CallbackQuery", "ForceReply", "GameHighScore", "GameHighScores", "InlineKeyboardButton", - "InlineKeyboardMarkup", "KeyboardButton", "ReplyKeyboardMarkup", "ReplyKeyboardRemove" + "CallbackGame", "CallbackQuery", "ForceReply", "GameHighScore", "InlineKeyboardButton", "InlineKeyboardMarkup", + "KeyboardButton", "ReplyKeyboardMarkup", "ReplyKeyboardRemove" ] diff --git a/pyrogram/client/types/keyboards/game_high_scores.py b/pyrogram/client/types/keyboards/game_high_scores.py deleted file mode 100644 index ea557cd5..00000000 --- a/pyrogram/client/types/keyboards/game_high_scores.py +++ /dev/null @@ -1,60 +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 typing import List - -import pyrogram -from pyrogram.api import types -from pyrogram.client.types.object import Object -from .game_high_score import GameHighScore - - -class GameHighScores(Object): - """The high scores table for a game. - - Parameters: - total_count (``int``): - Total number of scores the target game has. - - game_high_scores (List of :obj:`GameHighScore`): - Game scores. - """ - - __slots__ = ["total_count", "game_high_scores"] - - def __init__( - self, - *, - client: "pyrogram.BaseClient" = None, - total_count: int, - game_high_scores: List[GameHighScore] - ): - super().__init__(client) - - self.total_count = total_count - self.game_high_scores = game_high_scores - - @staticmethod - def _parse(client, game_high_scores: types.messages.HighScores) -> "GameHighScores": - return GameHighScores( - total_count=len(game_high_scores.scores), - game_high_scores=[ - GameHighScore._parse(client, score, game_high_scores.users) - for score in game_high_scores.scores], - client=client - ) From 09c5b239be029abde40c9613877ab4bc33307947 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 15:21:32 +0200 Subject: [PATCH 163/202] Add FOLDER_DEAC_AUTOFIX_ALL error. Weird new 500-class error --- compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv index 4dfe5994..c85fe7e0 100644 --- a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv +++ b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv @@ -8,4 +8,5 @@ REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again la RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later WORKER_BUSY_TOO_LONG_RETRY Telegram is having internal problems. Please try again later INTERDC_X_CALL_ERROR Telegram is having internal problems. Please try again later -INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems. Please try again later \ No newline at end of file +INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems. Please try again later +FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later \ No newline at end of file From 94d90efc80961a58253dcbc59f9c573ff4f12cc9 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 15:27:09 +0200 Subject: [PATCH 164/202] Rename section from "Keyboards" to "Bots & Keyboards" --- docs/source/api/types.rst | 6 +++--- pyrogram/client/filters/filters.py | 2 +- pyrogram/client/types/__init__.py | 2 +- .../types/{keyboards => bots_and_keyboards}/__init__.py | 0 .../{keyboards => bots_and_keyboards}/callback_game.py | 0 .../{keyboards => bots_and_keyboards}/callback_query.py | 0 .../types/{keyboards => bots_and_keyboards}/force_reply.py | 0 .../{keyboards => bots_and_keyboards}/game_high_score.py | 0 .../inline_keyboard_button.py | 0 .../inline_keyboard_markup.py | 0 .../{keyboards => bots_and_keyboards}/keyboard_button.py | 0 .../reply_keyboard_markup.py | 0 .../reply_keyboard_remove.py | 0 13 files changed, 5 insertions(+), 5 deletions(-) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/__init__.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/callback_game.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/callback_query.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/force_reply.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/game_high_score.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/inline_keyboard_button.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/inline_keyboard_markup.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/keyboard_button.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/reply_keyboard_markup.py (100%) rename pyrogram/client/types/{keyboards => bots_and_keyboards}/reply_keyboard_remove.py (100%) diff --git a/docs/source/api/types.rst b/docs/source/api/types.rst index 118c4261..644f8bb2 100644 --- a/docs/source/api/types.rst +++ b/docs/source/api/types.rst @@ -57,8 +57,8 @@ Messages & Media - :class:`Poll` - :class:`PollOption` -Keyboards -^^^^^^^^^ +Bots & Keyboards +^^^^^^^^^^^^^^^^ .. hlist:: :columns: 4 @@ -140,7 +140,7 @@ Details .. autoclass:: Poll() .. autoclass:: PollOption() -.. Keyboards +.. Bots & Keyboards .. autoclass:: ReplyKeyboardMarkup() .. autoclass:: KeyboardButton() .. autoclass:: ReplyKeyboardRemove() diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 1d962e85..fb0a3615 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -19,7 +19,7 @@ import re from .filter import Filter -from ..types.keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup +from ..types.bots_and_keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup def create(name: str, func: callable, **kwargs) -> type: diff --git a/pyrogram/client/types/__init__.py b/pyrogram/client/types/__init__.py index 8a725a9e..8fa55482 100644 --- a/pyrogram/client/types/__init__.py +++ b/pyrogram/client/types/__init__.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .keyboards import * +from .bots_and_keyboards import * from .inline_mode import * from .input_media import * from .input_message_content import * diff --git a/pyrogram/client/types/keyboards/__init__.py b/pyrogram/client/types/bots_and_keyboards/__init__.py similarity index 100% rename from pyrogram/client/types/keyboards/__init__.py rename to pyrogram/client/types/bots_and_keyboards/__init__.py diff --git a/pyrogram/client/types/keyboards/callback_game.py b/pyrogram/client/types/bots_and_keyboards/callback_game.py similarity index 100% rename from pyrogram/client/types/keyboards/callback_game.py rename to pyrogram/client/types/bots_and_keyboards/callback_game.py diff --git a/pyrogram/client/types/keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py similarity index 100% rename from pyrogram/client/types/keyboards/callback_query.py rename to pyrogram/client/types/bots_and_keyboards/callback_query.py diff --git a/pyrogram/client/types/keyboards/force_reply.py b/pyrogram/client/types/bots_and_keyboards/force_reply.py similarity index 100% rename from pyrogram/client/types/keyboards/force_reply.py rename to pyrogram/client/types/bots_and_keyboards/force_reply.py diff --git a/pyrogram/client/types/keyboards/game_high_score.py b/pyrogram/client/types/bots_and_keyboards/game_high_score.py similarity index 100% rename from pyrogram/client/types/keyboards/game_high_score.py rename to pyrogram/client/types/bots_and_keyboards/game_high_score.py diff --git a/pyrogram/client/types/keyboards/inline_keyboard_button.py b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py similarity index 100% rename from pyrogram/client/types/keyboards/inline_keyboard_button.py rename to pyrogram/client/types/bots_and_keyboards/inline_keyboard_button.py diff --git a/pyrogram/client/types/keyboards/inline_keyboard_markup.py b/pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py similarity index 100% rename from pyrogram/client/types/keyboards/inline_keyboard_markup.py rename to pyrogram/client/types/bots_and_keyboards/inline_keyboard_markup.py diff --git a/pyrogram/client/types/keyboards/keyboard_button.py b/pyrogram/client/types/bots_and_keyboards/keyboard_button.py similarity index 100% rename from pyrogram/client/types/keyboards/keyboard_button.py rename to pyrogram/client/types/bots_and_keyboards/keyboard_button.py diff --git a/pyrogram/client/types/keyboards/reply_keyboard_markup.py b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py similarity index 100% rename from pyrogram/client/types/keyboards/reply_keyboard_markup.py rename to pyrogram/client/types/bots_and_keyboards/reply_keyboard_markup.py diff --git a/pyrogram/client/types/keyboards/reply_keyboard_remove.py b/pyrogram/client/types/bots_and_keyboards/reply_keyboard_remove.py similarity index 100% rename from pyrogram/client/types/keyboards/reply_keyboard_remove.py rename to pyrogram/client/types/bots_and_keyboards/reply_keyboard_remove.py From 43493733c93eed960354f036f0c981baf54de360 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 15:28:03 +0200 Subject: [PATCH 165/202] Rearrange code --- pyrogram/client/ext/__init__.py | 3 +-- pyrogram/client/ext/dispatcher.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/ext/__init__.py b/pyrogram/client/ext/__init__.py index 58897c55..dde1952e 100644 --- a/pyrogram/client/ext/__init__.py +++ b/pyrogram/client/ext/__init__.py @@ -19,6 +19,5 @@ from .base_client import BaseClient from .dispatcher import Dispatcher from .emoji import Emoji -from .syncer import Syncer from .file_data import FileData - +from .syncer import Syncer diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 12d5a5de..b6760345 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -21,10 +21,10 @@ import threading from collections import OrderedDict from queue import Queue from threading import Thread -from . import utils import pyrogram from pyrogram.api import types +from . import utils from ..handlers import ( CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler From 5a0bcdaf425cbef9d13f63c9c02cbd95ae8e8f9e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 16:51:03 +0200 Subject: [PATCH 166/202] Update robots.txt --- docs/robots.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/robots.txt b/docs/robots.txt index 0ecbac7b..1b9e8da6 100644 --- a/docs/robots.txt +++ b/docs/robots.txt @@ -1,3 +1,8 @@ User-agent: * + Allow: / + +Disallow: /dev/* +Disallow: /old/* + Sitemap: https://docs.pyrogram.org/sitemap.xml \ No newline at end of file From 3ab624c7060dbdbbc4cc4ff1b33075a55a53bf58 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 18:54:33 +0200 Subject: [PATCH 167/202] Add FOLDER_ID_INVALID error --- compiler/error/source/400_BAD_REQUEST.tsv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index fa6ff67e..815ce3fb 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -99,4 +99,5 @@ RESULT_ID_DUPLICATE The result contains items with duplicated identifiers ACCESS_TOKEN_INVALID The bot access token is invalid INVITE_HASH_EXPIRED The chat invite link is no longer valid USER_BANNED_IN_CHANNEL You are limited, check @SpamBot for details -MESSAGE_EDIT_TIME_EXPIRED You can no longer edit this message \ No newline at end of file +MESSAGE_EDIT_TIME_EXPIRED You can no longer edit this message +FOLDER_ID_INVALID The folder id is invalid \ No newline at end of file From 00755347533c03f33f315aa8db5b8b1af615a61c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 19:13:27 +0200 Subject: [PATCH 168/202] Add a bunch of new errors - MEGAGROUP_PREHISTORY_HIDDEN - CHAT_LINK_EXISTS - LINK_NOT_MODIFIED - BROADCAST_ID_INVALID - MEGAGROUP_ID_INVALID --- compiler/error/source/400_BAD_REQUEST.tsv | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index 815ce3fb..8e82c9f6 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -100,4 +100,9 @@ ACCESS_TOKEN_INVALID The bot access token is invalid INVITE_HASH_EXPIRED The chat invite link is no longer valid USER_BANNED_IN_CHANNEL You are limited, check @SpamBot for details MESSAGE_EDIT_TIME_EXPIRED You can no longer edit this message -FOLDER_ID_INVALID The folder id is invalid \ No newline at end of file +FOLDER_ID_INVALID The folder id is invalid +MEGAGROUP_PREHISTORY_HIDDEN The action failed because the supergroup has the pre-history hidden +CHAT_LINK_EXISTS The action failed because the supergroup is linked to a channel +LINK_NOT_MODIFIED The chat link was not modified because you tried to link to the same target +BROADCAST_ID_INVALID The channel is invalid +MEGAGROUP_ID_INVALID The supergroup is invalid \ No newline at end of file From 5f3b7b97aaa5ca8a1b8f302051a949de9823eb01 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 19:15:19 +0200 Subject: [PATCH 169/202] Add archive_chats and unarchive_chats methods --- docs/source/api/methods.rst | 4 ++ pyrogram/client/methods/chats/__init__.py | 6 +- .../client/methods/chats/archive_chats.py | 58 +++++++++++++++++++ .../client/methods/chats/unarchive_chats.py | 58 +++++++++++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 pyrogram/client/methods/chats/archive_chats.py create mode 100644 pyrogram/client/methods/chats/unarchive_chats.py diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index ed150e4c..e688903f 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -104,6 +104,8 @@ Chats - :meth:`~Client.get_dialogs_count` - :meth:`~Client.restrict_chat` - :meth:`~Client.update_chat_username` + - :meth:`~Client.archive_chats` + - :meth:`~Client.unarchive_chats` Users ^^^^^ @@ -233,6 +235,8 @@ Details .. automethod:: Client.get_dialogs_count() .. automethod:: Client.restrict_chat() .. automethod:: Client.update_chat_username() +.. automethod:: Client.archive_chats() +.. automethod:: Client.unarchive_chats() .. Users .. automethod:: Client.get_me() diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index c0176939..969628ee 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from .archive_chats import ArchiveChats from .delete_chat_photo import DeleteChatPhoto from .export_chat_invite_link import ExportChatInviteLink from .get_chat import GetChat @@ -36,6 +37,7 @@ from .restrict_chat_member import RestrictChatMember from .set_chat_description import SetChatDescription from .set_chat_photo import SetChatPhoto from .set_chat_title import SetChatTitle +from .unarchive_chats import UnarchiveChats from .unban_chat_member import UnbanChatMember from .unpin_chat_message import UnpinChatMessage from .update_chat_username import UpdateChatUsername @@ -64,6 +66,8 @@ class Chats( IterChatMembers, UpdateChatUsername, RestrictChat, - GetDialogsCount + GetDialogsCount, + ArchiveChats, + UnarchiveChats ): pass diff --git a/pyrogram/client/methods/chats/archive_chats.py b/pyrogram/client/methods/chats/archive_chats.py new file mode 100644 index 00000000..3c929983 --- /dev/null +++ b/pyrogram/client/methods/chats/archive_chats.py @@ -0,0 +1,58 @@ +# 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 typing import Union, List + +from pyrogram.api import functions, types +from ...ext import BaseClient + + +class ArchiveChats(BaseClient): + def archive_chats( + self, + chat_ids: Union[int, str, List[Union[int, str]]], + ) -> bool: + """Archive one or more chats. + + Parameters: + chat_ids (``int`` | ``str`` | List[``int``, ``str``]): + Unique identifier (int) or username (str) of the target chat. + You can also pass a list of ids (int) or usernames (str). + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + if not isinstance(chat_ids, list): + chat_ids = [chat_ids] + + self.send( + functions.folders.EditPeerFolders( + folder_peers=[ + types.InputFolderPeer( + peer=self.resolve_peer(chat), + folder_id=1 + ) for chat in chat_ids + ] + ) + ) + + return True diff --git a/pyrogram/client/methods/chats/unarchive_chats.py b/pyrogram/client/methods/chats/unarchive_chats.py new file mode 100644 index 00000000..56bcc6f8 --- /dev/null +++ b/pyrogram/client/methods/chats/unarchive_chats.py @@ -0,0 +1,58 @@ +# 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 typing import Union, List + +from pyrogram.api import functions, types +from ...ext import BaseClient + + +class UnarchiveChats(BaseClient): + def unarchive_chats( + self, + chat_ids: Union[int, str, List[Union[int, str]]], + ) -> bool: + """Unarchive one or more chats. + + Parameters: + chat_ids (``int`` | ``str`` | List[``int``, ``str``]): + Unique identifier (int) or username (str) of the target chat. + You can also pass a list of ids (int) or usernames (str). + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + if not isinstance(chat_ids, list): + chat_ids = [chat_ids] + + self.send( + functions.folders.EditPeerFolders( + folder_peers=[ + types.InputFolderPeer( + peer=self.resolve_peer(chat), + folder_id=0 + ) for chat in chat_ids + ] + ) + ) + + return True From 9b12e823b43427bc3a33809ea4cffdc4f9d6f1a2 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 19:25:12 +0200 Subject: [PATCH 170/202] Fix Message bound methods' docstrings --- .../types/messages_and_media/message.py | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index f7dff7b5..78165e78 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -661,7 +661,7 @@ class Message(Object, Update): reply_to_message_id: int = None, reply_markup=None ) -> "Message": - """Bound method *reply* :obj:`Message `. + """Bound method *reply* of :obj:`Message`. Use as a shortcut for: @@ -748,7 +748,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_animation* :obj:`Message `. + """Bound method *reply_animation* :obj:`Message`. Use as a shortcut for: @@ -882,7 +882,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_audio* :obj:`Message `. + """Bound method *reply_audio* of :obj:`Message`. Use as a shortcut for: @@ -1010,7 +1010,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_cached_media* :obj:`Message `. + """Bound method *reply_cached_media* of :obj:`Message`. Use as a shortcut for: @@ -1077,7 +1077,7 @@ class Message(Object, Update): ) def reply_chat_action(self, action: str) -> bool: - """Bound method *reply_chat_action* :obj:`Message `. + """Bound method *reply_chat_action* of :obj:`Message`. Use as a shortcut for: @@ -1130,7 +1130,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_contact* :obj:`Message `. + """Bound method *reply_contact* of :obj:`Message`. Use as a shortcut for: @@ -1217,7 +1217,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_document* :obj:`Message `. + """Bound method *reply_document* of :obj:`Message`. Use as a shortcut for: @@ -1331,7 +1331,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_game* :obj:`Message `. + """Bound method *reply_game* of :obj:`Message`. Use as a shortcut for: @@ -1396,7 +1396,7 @@ class Message(Object, Update): reply_to_message_id: int = None, hide_via: bool = None ) -> "Message": - """Bound method *reply_inline_bot_result* :obj:`Message `. + """Bound method *reply_inline_bot_result* of :obj:`Message`. Use as a shortcut for: @@ -1470,7 +1470,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_location* :obj:`Message `. + """Bound method *reply_location* of :obj:`Message`. Use as a shortcut for: @@ -1538,7 +1538,7 @@ class Message(Object, Update): disable_notification: bool = None, reply_to_message_id: int = None ) -> "Message": - """Bound method *reply_media_group* :obj:`Message `. + """Bound method *reply_media_group* of :obj:`Message`. Use as a shortcut for: @@ -1610,7 +1610,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_photo* :obj:`Message `. + """Bound method *reply_photo* of :obj:`Message`. Use as a shortcut for: @@ -1724,7 +1724,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_poll* :obj:`Message `. + """Bound method *reply_poll* of :obj:`Message`. Use as a shortcut for: @@ -1800,7 +1800,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_sticker* :obj:`Message `. + """Bound method *reply_sticker* of :obj:`Message`. Use as a shortcut for: @@ -1903,7 +1903,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *reply_venue* :obj:`Message `. + """Bound method *reply_venue* of :obj:`Message`. Use as a shortcut for: @@ -2005,7 +2005,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video* :obj:`Message `. + """Bound method *reply_video* of :obj:`Message`. Use as a shortcut for: @@ -2140,7 +2140,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_video_note* :obj:`Message `. + """Bound method *reply_video_note* of :obj:`Message`. Use as a shortcut for: @@ -2258,7 +2258,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> "Message": - """Bound method *reply_voice* :obj:`Message `. + """Bound method *reply_voice* of :obj:`Message`. Use as a shortcut for: @@ -2368,7 +2368,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit* :obj:`Message `. + """Bound method *edit* of :obj:`Message`. Use as a shortcut for: @@ -2425,7 +2425,7 @@ class Message(Object, Update): "pyrogram.ForceReply" ] = None ) -> "Message": - """Bound method *edit_caption* :obj:`Message `. + """Bound method *edit_caption* of :obj:`Message`. Use as a shortcut for: @@ -2468,7 +2468,7 @@ class Message(Object, Update): ) def edit_media(self, media: InputMedia, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_media* :obj:`Message `. + """Bound method *edit_media* of :obj:`Message`. Use as a shortcut for: @@ -2506,7 +2506,7 @@ class Message(Object, Update): ) def edit_reply_markup(self, reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "Message": - """Bound method *edit_reply_markup* :obj:`Message `. + """Bound method *edit_reply_markup* of :obj:`Message`. Use as a shortcut for: @@ -2547,7 +2547,7 @@ class Message(Object, Update): as_copy: bool = False, remove_caption: bool = False ) -> "Message": - """Bound method *forward* :obj:`Message `. + """Bound method *forward* of :obj:`Message`. Use as a shortcut for: @@ -2690,7 +2690,7 @@ class Message(Object, Update): ) def delete(self, revoke: bool = True): - """Bound method *delete* :obj:`Message `. + """Bound method *delete* of :obj:`Message`. Use as a shortcut for: @@ -2726,7 +2726,7 @@ class Message(Object, Update): ) def click(self, x: int or str, y: int = 0, quote: bool = None, timeout: int = 10): - """Bound method *click* :obj:`Message `. + """Bound method *click* of :obj:`Message`. Use as a shortcut for clicking a button attached to the message instead of: @@ -2853,7 +2853,7 @@ class Message(Object, Update): progress: callable = None, progress_args: tuple = () ) -> str: - """Bound method *download* :obj:`Message `. + """Bound method *download* of :obj:`Message`. Use as a shortcut for: @@ -2902,7 +2902,7 @@ class Message(Object, Update): ) def pin(self, disable_notification: bool = None) -> "Message": - """Bound method *pin* :obj:`Message `. + """Bound method *pin* of :obj:`Message`. Use as a shortcut for: From 6e3d8ca20b25ee90ff3b9a6caa0494b6d16c89a2 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 19:25:57 +0200 Subject: [PATCH 171/202] Add .archive() and .unarchive() bound methods to Chat --- docs/source/api/bound-methods.rst | 13 ++++++ pyrogram/client/types/user_and_chats/chat.py | 46 ++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index 0622e6b8..ac348d03 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -59,6 +59,15 @@ Message - :meth:`~Message.reply_video_note` - :meth:`~Message.reply_voice` +Chat +^^^^ + +.. hlist:: + :columns: 2 + + - :meth:`~Chat.archive` + - :meth:`~Chat.unarchive` + CallbackQuery ^^^^^^^^^^^^^ @@ -109,6 +118,10 @@ Details .. automethod:: Message.reply_video_note() .. automethod:: Message.reply_voice() +.. Chat +.. automethod:: Chat.archive() +.. automethod:: Chat.unarchive() + .. CallbackQuery .. automethod:: CallbackQuery.answer() diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index ca9acd65..7296a903 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -257,3 +257,49 @@ class Chat(Object): return Chat._parse_user_chat(client, chat) else: return Chat._parse_channel_chat(client, chat) + + def archive(self): + """Bound method *archive* of :obj:`Chat`. + + Use as a shortcut for: + + .. code-block:: python + + client.archive_chats(-100123456789) + + Example: + .. code-block:: python + + chat.archive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.archive_chats(self.id) + + def unarchive(self): + """Bound method *unarchive* of :obj:`Chat`. + + Use as a shortcut for: + + .. code-block:: python + + client.unarchive_chats(-100123456789) + + Example: + .. code-block:: python + + chat.unarchive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.unarchive_chats(self.id) From 34616ebf613802c767e78a6b5404684e41060d00 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 19:29:55 +0200 Subject: [PATCH 172/202] Add .archive() and .unarchive() bound methods to User --- docs/source/api/bound-methods.rst | 13 ++++++ pyrogram/client/types/user_and_chats/user.py | 46 ++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index ac348d03..d01a4383 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -68,6 +68,15 @@ Chat - :meth:`~Chat.archive` - :meth:`~Chat.unarchive` +User +^^^^ + +.. hlist:: + :columns: 2 + + - :meth:`~User.archive` + - :meth:`~User.unarchive` + CallbackQuery ^^^^^^^^^^^^^ @@ -122,6 +131,10 @@ Details .. automethod:: Chat.archive() .. automethod:: Chat.unarchive() +.. User +.. automethod:: User.archive() +.. automethod:: User.unarchive() + .. CallbackQuery .. automethod:: CallbackQuery.answer() diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 50dd8361..05877b63 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -160,3 +160,49 @@ class User(Object): restriction_reason=user.restriction_reason, client=client ) + + def archive(self): + """Bound method *archive* of :obj:`User`. + + Use as a shortcut for: + + .. code-block:: python + + client.archive_chats(123456789) + + Example: + .. code-block:: python + + user.archive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.archive_chats(self.id) + + def unarchive(self): + """Bound method *unarchive* of :obj:`User`. + + Use as a shortcut for: + + .. code-block:: python + + client.unarchive_chats(123456789) + + Example: + .. code-block:: python + + user.unarchive() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return self._client.unarchive_chats(self.id) From 6e6dd54d4020248072053959b4120ba6d9ba4641 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 8 Jun 2019 19:55:40 +0200 Subject: [PATCH 173/202] Add missing attributes to the Chat type --- pyrogram/client/types/user_and_chats/chat.py | 19 ++++++++++++++----- pyrogram/client/types/user_and_chats/user.py | 14 +++++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/chat.py b/pyrogram/client/types/user_and_chats/chat.py index 7296a903..2d88d3ed 100644 --- a/pyrogram/client/types/user_and_chats/chat.py +++ b/pyrogram/client/types/user_and_chats/chat.py @@ -36,14 +36,17 @@ class Chat(Object): Type of chat, can be either "private", "bot", "group", "supergroup" or "channel". is_verified (``bool``, *optional*): - True, if this chat has been verified by Telegram. Supergroups and channels only. + True, if this chat has been verified by Telegram. Supergroups, channels and bots only. is_restricted (``bool``, *optional*): - True, if this chat has been restricted. Supergroups and channels only. + True, if this chat has been restricted. Supergroups, channels and bots only. See *restriction_reason* for details. is_scam (``bool``, *optional*): - True, if this chat has been flagged for scam. Supergroups and channels only. + True, if this chat has been flagged for scam. Supergroups, channels and bots only. + + is_support (``bool``): + True, if this chat is part of the Telegram support team. Users and bots only. title (``str``, *optional*): Title, for supergroups, channels and basic group chats. @@ -92,8 +95,8 @@ class Chat(Object): """ __slots__ = [ - "id", "type", "is_verified", "is_restricted", "is_scam", "title", "username", "first_name", "last_name", - "photo", "description", "invite_link", "pinned_message", "sticker_set_name", "can_set_sticker_set", + "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" ] @@ -106,6 +109,7 @@ class Chat(Object): is_verified: bool = None, is_restricted: bool = None, is_scam: bool = None, + is_support: bool = None, title: str = None, username: str = None, first_name: str = None, @@ -127,6 +131,7 @@ class Chat(Object): self.is_verified = is_verified self.is_restricted = is_restricted self.is_scam = is_scam + self.is_support = is_support self.title = title self.username = username self.first_name = first_name @@ -148,6 +153,10 @@ class Chat(Object): return Chat( id=peer_id, type="bot" if user.bot else "private", + is_verified=getattr(user, "verified", None), + is_restricted=getattr(user, "restricted", None), + is_scam=getattr(user, "scam", None), + is_support=getattr(user, "support", None), username=user.username, first_name=user.first_name, last_name=user.last_name, diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 05877b63..f47e8c42 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -52,12 +52,12 @@ class User(Object): True, if this user has been restricted. Bots only. See *restriction_reason* for details. - is_support (``bool``): - True, if this user is part of the Telegram support team. - is_scam (``bool``): True, if this user has been flagged for scam. + is_support (``bool``): + True, if this user is part of the Telegram support team. + first_name (``str``): User's or bot's first name. @@ -86,7 +86,7 @@ class User(Object): __slots__ = [ "id", "is_self", "is_contact", "is_mutual_contact", "is_deleted", "is_bot", "is_verified", "is_restricted", - "is_support", "is_scam", "first_name", "last_name", "status", "username", "language_code", "phone_number", + "is_scam", "is_support", "first_name", "last_name", "status", "username", "language_code", "phone_number", "photo", "restriction_reason" ] @@ -102,8 +102,8 @@ class User(Object): is_bot: bool, is_verified: bool, is_restricted: bool, - is_support: bool, is_scam: bool, + is_support: bool, first_name: str, last_name: str = None, status: UserStatus = None, @@ -123,8 +123,8 @@ class User(Object): self.is_bot = is_bot self.is_verified = is_verified self.is_restricted = is_restricted - self.is_support = is_support self.is_scam = is_scam + self.is_support = is_support self.first_name = first_name self.last_name = last_name self.status = status @@ -148,8 +148,8 @@ class User(Object): is_bot=user.bot, is_verified=user.verified, is_restricted=user.restricted, - is_support=user.support, is_scam=user.scam, + is_support=user.support, first_name=user.first_name, last_name=user.last_name, status=UserStatus._parse(client, user.status, user.id, user.bot), From af08606087548943bd1bf891a35d1d11a494ba2d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 9 Jun 2019 13:01:24 +0200 Subject: [PATCH 174/202] Fix get_profile_photos not working when passing "me"/"self" as argument --- pyrogram/client/methods/users/get_profile_photos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/methods/users/get_profile_photos.py b/pyrogram/client/methods/users/get_profile_photos.py index e4e202e0..2b1d0c54 100644 --- a/pyrogram/client/methods/users/get_profile_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -54,7 +54,7 @@ class GetProfilePhotos(BaseClient): """ peer_id = self.resolve_peer(chat_id) - if isinstance(peer_id, types.InputPeerUser): + if isinstance(peer_id, (types.InputPeerUser, types.InputPeerSelf)): return pyrogram.ProfilePhotos._parse( self, self.send( From 6ddb28c3e4b3dbec4a0e7431983c4bdcba4a3874 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 10 Jun 2019 17:41:55 +0200 Subject: [PATCH 175/202] Small docs layout fixup --- docs/source/api/client.rst | 3 +++ docs/source/api/filters.rst | 3 +++ docs/source/license.rst | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/source/api/client.rst b/docs/source/api/client.rst index 9527ca73..d1b8c4b0 100644 --- a/docs/source/api/client.rst +++ b/docs/source/api/client.rst @@ -13,4 +13,7 @@ This is the Client class. It exposes high-level methods for an easy access to th with app: app.send_message("me", "Hi!") +Details +------- + .. autoclass:: pyrogram.Client() diff --git a/docs/source/api/filters.rst b/docs/source/api/filters.rst index 87faa801..6cb01cda 100644 --- a/docs/source/api/filters.rst +++ b/docs/source/api/filters.rst @@ -1,5 +1,8 @@ Update Filters ============== +Details +------- + .. autoclass:: pyrogram.Filters :members: diff --git a/docs/source/license.rst b/docs/source/license.rst index 43f59d73..38302bdc 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -2,7 +2,7 @@ About the License ================= .. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png - :align: left + :align: right Pyrogram is free software and is currently licensed under the terms of the `GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it From 10e5dbb6e87941ce52fb7e9d546448e09cbdd232 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 14:44:30 +0200 Subject: [PATCH 176/202] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- .github/ISSUE_TEMPLATE/question.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e0556d54..59410e25 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,7 +4,7 @@ about: Create a bug report affecting the library labels: "bug" --- - + ## Checklist - [ ] I am sure the error is coming from Pyrogram's code and not elsewhere. @@ -15,7 +15,7 @@ labels: "bug" A clear and concise description of the problem. ## Steps to Reproduce -[A minimal, complete and verifiable example](https://stackoverflow.com/help/mcve). +[A minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). ## Traceback The full traceback (if applicable). \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 70a39192..4d2f447c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -4,7 +4,7 @@ about: Suggest ideas, new features or enhancements labels: "enhancement" --- - + ## Checklist - [ ] I believe the idea is awesome and would benefit the library. diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 737304d9..88d91ecd 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -5,11 +5,11 @@ title: For Q&A purposes, please read this template body labels: "question" --- - + # Important This place is for issues about Pyrogram, it's **not a forum**. -If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community by following the description in https://t.me/pyrogram. +If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community at https://t.me/pyrogram. Thanks. \ No newline at end of file From c8b757aceeee047a3847d808995b156f8a3afb00 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 15:59:15 +0200 Subject: [PATCH 177/202] Move advanced utility methods somewhere else in the docs index --- docs/source/api/methods.rst | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index e688903f..58836efa 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -31,9 +31,6 @@ Utilities - :meth:`~Client.run` - :meth:`~Client.add_handler` - :meth:`~Client.remove_handler` - - :meth:`~Client.send` - - :meth:`~Client.resolve_peer` - - :meth:`~Client.save_file` - :meth:`~Client.stop_transmission` Messages @@ -159,6 +156,16 @@ Bots - :meth:`~Client.set_game_score` - :meth:`~Client.get_game_high_scores` +Advanced Usage (Raw API) +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. hlist:: + :columns: 4 + + - :meth:`~Client.send` + - :meth:`~Client.resolve_peer` + - :meth:`~Client.save_file` + ----- Details @@ -172,9 +179,6 @@ Details .. automethod:: Client.run() .. automethod:: Client.add_handler() .. automethod:: Client.remove_handler() -.. automethod:: Client.send() -.. automethod:: Client.resolve_peer() -.. automethod:: Client.save_file() .. automethod:: Client.stop_transmission() .. Messages @@ -269,3 +273,8 @@ Details .. automethod:: Client.send_game() .. automethod:: Client.set_game_score() .. automethod:: Client.get_game_high_scores() + +.. Advanced Usage +.. automethod:: Client.send() +.. automethod:: Client.resolve_peer() +.. automethod:: Client.save_file() \ No newline at end of file From 7baa00353d7a9f755203a32bae1f77394bf32121 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 15:59:39 +0200 Subject: [PATCH 178/202] Add a FAQ about DC migration --- docs/source/faq.rst | 23 ++++++++++++++++---- pyrogram/client/methods/users/get_user_dc.py | 9 ++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 6ff16559..f08da03f 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -152,11 +152,26 @@ kept as aliases. ***** Alias DC -I keep getting PEER_ID_INVALID error! -------------------------------------------- +I want to migrate my account from DCX to DCY. +--------------------------------------------- -The error in question is ``[400 PEER_ID_INVALID]``, and could mean several -things: +This question is often asked by people who find their account(s) always being connected to DC1 - USA (for example), but +are connecting from a place far away (e.g DC4 - Europe), thus resulting in slower interactions when using the API +because of the great physical distance between the user and its associated DC. + +When registering an account for the first time, is up to Telegram to decide which DC the new user is going to be created +in, based on the phone number origin. + +Even though Telegram `documentations `_ state the server might +decide to automatically migrate a user in case of prolonged usages from a distant, unusual location and albeit this +mechanism is also `confirmed `_ to exist by Telegram itself, +it's currently not possible to have your account migrated, in any way, simply because the feature was once planned but +not yet implemented. + +I keep getting PEER_ID_INVALID error! +------------------------------------- + +The error in question is ``[400 PEER_ID_INVALID]``, and could mean several things: - 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. diff --git a/pyrogram/client/methods/users/get_user_dc.py b/pyrogram/client/methods/users/get_user_dc.py index 7cb43d83..718f4c44 100644 --- a/pyrogram/client/methods/users/get_user_dc.py +++ b/pyrogram/client/methods/users/get_user_dc.py @@ -28,9 +28,9 @@ class GetUserDC(BaseClient): .. note:: - This information is approximate: it is based on where the user stores their profile pictures and does not by - any means tell you the user location. More info at - `FAQs <../faq#what-are-the-ip-addresses-of-telegram-data-centers>`_. + This information is approximate: it is based on where Telegram stores a user profile pictures and does not + by any means tell you the user location (i.e. a user might travel far away, but will still connect to its + assigned DC). More info at `FAQs <../faq#what-are-the-ip-addresses-of-telegram-data-centers>`_. Parameters: user_id (``int`` | ``str``): @@ -39,7 +39,8 @@ class GetUserDC(BaseClient): For a contact that exists in your Telegram address book you can use his phone number (str). Returns: - ``int`` | ``None``: The DC identifier as integer, or None in case it wasn't possible to get it. + ``int`` | ``None``: The DC identifier as integer, or None in case it wasn't possible to get it (i.e. the + user has no profile picture or has the privacy setting enabled). Raises: RPCError: In case of a Telegram RPC error. From b9b50bad94afe50073e0b85677538f0bcdaf74b3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 16:46:10 +0200 Subject: [PATCH 179/202] Fix get_users and get_contacts not returning pretty-printable lists --- pyrogram/client/methods/contacts/get_contacts.py | 2 +- pyrogram/client/methods/users/get_users.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/methods/contacts/get_contacts.py b/pyrogram/client/methods/contacts/get_contacts.py index 0c231670..8ca321dc 100644 --- a/pyrogram/client/methods/contacts/get_contacts.py +++ b/pyrogram/client/methods/contacts/get_contacts.py @@ -47,4 +47,4 @@ class GetContacts(BaseClient): time.sleep(e.x) else: log.info("Total contacts: {}".format(len(self.peers_by_phone))) - return [pyrogram.User._parse(self, user) for user in contacts.users] + return pyrogram.List(pyrogram.User._parse(self, user) for user in contacts.users) diff --git a/pyrogram/client/methods/users/get_users.py b/pyrogram/client/methods/users/get_users.py index 4ec0e893..f76e6802 100644 --- a/pyrogram/client/methods/users/get_users.py +++ b/pyrogram/client/methods/users/get_users.py @@ -56,7 +56,7 @@ class GetUsers(BaseClient): ) ) - users = [] + users = pyrogram.List() for i in r: users.append(pyrogram.User._parse(self, i)) From fd0a40442a9745d77c8252ea72d82dcfe1d70dd0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 18:31:38 +0200 Subject: [PATCH 180/202] Fix plugins not getting reloaded properly when restarting a client --- pyrogram/client/client.py | 59 ++++++++++++++++++++----------- pyrogram/client/ext/dispatcher.py | 1 + 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 6dc8ce97..fd5db423 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -1085,29 +1085,34 @@ class Client(Methods, BaseClient): self._proxy["password"] = parser.get("proxy", "password", fallback=None) or None if self.plugins: - self.plugins["enabled"] = bool(self.plugins.get("enabled", True)) - self.plugins["include"] = "\n".join(self.plugins.get("include", [])) or None - self.plugins["exclude"] = "\n".join(self.plugins.get("exclude", [])) or None + self.plugins = { + "enabled": bool(self.plugins.get("enabled", True)), + "root": self.plugins.get("root", None), + "include": self.plugins.get("include", []), + "exclude": self.plugins.get("exclude", []) + } else: try: section = parser["plugins"] self.plugins = { "enabled": section.getboolean("enabled", True), - "root": section.get("root"), - "include": section.get("include") or None, - "exclude": section.get("exclude") or None + "root": section.get("root", None), + "include": section.get("include", []), + "exclude": section.get("exclude", []) } - except KeyError: - self.plugins = {} - if self.plugins: - for option in ["include", "exclude"]: - if self.plugins[option] is not None: - self.plugins[option] = [ - (i.split()[0], i.split()[1:] or None) - for i in self.plugins[option].strip().split("\n") - ] + include = self.plugins["include"] + exclude = self.plugins["exclude"] + + if include: + self.plugins["include"] = include.strip().split("\n") + + if exclude: + self.plugins["exclude"] = exclude.strip().split("\n") + + except KeyError: + self.plugins = None def load_session(self): try: @@ -1142,14 +1147,26 @@ class Client(Methods, BaseClient): self.peers_by_phone[k] = peer def load_plugins(self): - if self.plugins.get("enabled", False): - root = self.plugins["root"] - include = self.plugins["include"] - exclude = self.plugins["exclude"] + if self.plugins: + plugins = self.plugins.copy() + + for option in ["include", "exclude"]: + if plugins[option]: + plugins[option] = [ + (i.split()[0], i.split()[1:] or None) + for i in self.plugins[option] + ] + else: + return + + if plugins.get("enabled", False): + root = plugins["root"] + include = plugins["include"] + exclude = plugins["exclude"] count = 0 - if include is None: + if not include: for path in sorted(Path(root).rglob("*.py")): module_path = '.'.join(path.parent.parts + (path.stem,)) module = import_module(module_path) @@ -1206,7 +1223,7 @@ class Client(Methods, BaseClient): log.warning('[{}] [LOAD] Ignoring non-existent function "{}" from "{}"'.format( self.session_name, name, module_path)) - if exclude is not None: + if exclude: for path, handlers in exclude: module_path = root + "." + path warn_non_existent_functions = True diff --git a/pyrogram/client/ext/dispatcher.py b/pyrogram/client/ext/dispatcher.py index 2f1ec2b9..a15cb299 100644 --- a/pyrogram/client/ext/dispatcher.py +++ b/pyrogram/client/ext/dispatcher.py @@ -106,6 +106,7 @@ class Dispatcher: worker.join() self.workers_list.clear() + self.groups.clear() def add_handler(self, handler, group: int): if group not in self.groups: From 83af58258c2b6343f8684fb5bbaf80f05bf33a21 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 20:36:09 +0200 Subject: [PATCH 181/202] Fix download_media ignoring the file_name argument --- pyrogram/client/methods/messages/download_media.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index d822a88b..bd8de2d6 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -86,6 +86,7 @@ class DownloadMedia(BaseClient): error_message = "This message doesn't contain any downloadable media" available_media = ("audio", "document", "photo", "sticker", "animation", "video", "voice", "video_note") + media_file_name = None file_size = None mime_type = None date = None @@ -105,13 +106,13 @@ class DownloadMedia(BaseClient): file_id_str = media else: file_id_str = media.file_id - file_name = getattr(media, "file_name", "") + media_file_name = getattr(media, "file_name", "") file_size = getattr(media, "file_size", None) mime_type = getattr(media, "mime_type", None) date = getattr(media, "date", None) data = FileData( - file_name=file_name, + file_name=media_file_name, file_size=file_size, mime_type=mime_type, date=date From 92625795ef8ea2968097c7fb388b84ad5fa63830 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 20:50:36 +0200 Subject: [PATCH 182/202] Update develop version --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index b15bd0c5..ac184844 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -24,7 +24,7 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]: # Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one. sys.modules["typing"] = typing -__version__ = "0.14.1" +__version__ = "0.15.0-develop" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __copyright__ = "Copyright (C) 2017-2019 Dan " From 684aef3ded762805a04874cf4fd55a6ce757cfab Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 11 Jun 2019 21:12:00 +0200 Subject: [PATCH 183/202] Fix files downloaded with no file name --- pyrogram/client/client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index fd5db423..1106a416 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -849,7 +849,9 @@ class Client(Methods, BaseClient): media_type_str = Client.MEDIA_TYPE_ID[data.media_type] - if not data.file_name: + file_name = file_name or data.file_name + + if not file_name: guessed_extension = self.guess_extension(data.mime_type) if data.media_type in (0, 1, 2, 14): From 4f2928e7b564b7b31e48099aa4b9154ef1de6fd6 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 11:37:43 +0200 Subject: [PATCH 184/202] Improve get_profile_photos and get_profile_photos_count --- .../methods/users/get_profile_photos.py | 25 +++++++++-------- .../methods/users/get_profile_photos_count.py | 28 ++++++++++++++++++- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/pyrogram/client/methods/users/get_profile_photos.py b/pyrogram/client/methods/users/get_profile_photos.py index e2845c8d..3ffeae39 100644 --- a/pyrogram/client/methods/users/get_profile_photos.py +++ b/pyrogram/client/methods/users/get_profile_photos.py @@ -21,6 +21,7 @@ from typing import Union, List import pyrogram from pyrogram.api import functions, types from pyrogram.client.ext import utils + from ...ext import BaseClient @@ -55,18 +56,7 @@ class GetProfilePhotos(BaseClient): """ peer_id = self.resolve_peer(chat_id) - if isinstance(peer_id, (types.InputPeerUser, types.InputPeerSelf)): - r = self.send( - functions.photos.GetUserPhotos( - user_id=peer_id, - offset=offset, - max_id=0, - limit=limit - ) - ) - - return pyrogram.List(pyrogram.Photo._parse(self, photo) for photo in r.photos) - else: + if isinstance(peer_id, types.InputPeerChannel): r = utils.parse_messages( self, self.send( @@ -87,3 +77,14 @@ class GetProfilePhotos(BaseClient): ) return pyrogram.List([message.new_chat_photo for message in r][:limit]) + else: + r = self.send( + functions.photos.GetUserPhotos( + user_id=peer_id, + offset=offset, + max_id=0, + limit=limit + ) + ) + + return pyrogram.List(pyrogram.Photo._parse(self, photo) for photo in r.photos) diff --git a/pyrogram/client/methods/users/get_profile_photos_count.py b/pyrogram/client/methods/users/get_profile_photos_count.py index a65e0ada..bf00a10b 100644 --- a/pyrogram/client/methods/users/get_profile_photos_count.py +++ b/pyrogram/client/methods/users/get_profile_photos_count.py @@ -18,6 +18,8 @@ from typing import Union +from pyrogram.api import functions, types + from ...ext import BaseClient @@ -38,4 +40,28 @@ class GetProfilePhotosCount(BaseClient): RPCError: In case of a Telegram RPC error. """ - return self.get_profile_photos(chat_id, limit=1).total_count + peer_id = self.resolve_peer(chat_id) + + if isinstance(peer_id, types.InputPeerChannel): + r = self.send( + functions.messages.GetSearchCounters( + peer=peer_id, + filters=[types.InputMessagesFilterChatPhotos()], + ) + ) + + return r[0].count + else: + r = self.send( + functions.photos.GetUserPhotos( + user_id=peer_id, + offset=0, + max_id=0, + limit=1 + ) + ) + + if isinstance(r, types.photos.Photos): + return len(r.photos) + else: + return r.count From df6e174b5521629dd8b6f1d7d4c33b25fc7db32d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 11:38:06 +0200 Subject: [PATCH 185/202] Fix InputPhoneContact docstring --- pyrogram/client/types/input_media/input_phone_contact.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/types/input_media/input_phone_contact.py b/pyrogram/client/types/input_media/input_phone_contact.py index f60dd39d..9c03694d 100644 --- a/pyrogram/client/types/input_media/input_phone_contact.py +++ b/pyrogram/client/types/input_media/input_phone_contact.py @@ -24,7 +24,7 @@ from ..object import Object class InputPhoneContact(Object): """A Phone Contact to be added in your Telegram address book. - It is intended to be used with :meth:`~Client.add_contacts() ` + It is intended to be used with :meth:`~pyrogram.Client.add_contacts()` Parameters: phone (``str``): From b86373d28c0de0a905132a7cb48ba6c792fb8ea1 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 11:43:24 +0200 Subject: [PATCH 186/202] Improve get_history_count --- .../methods/messages/get_history_count.py | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/pyrogram/client/methods/messages/get_history_count.py b/pyrogram/client/methods/messages/get_history_count.py index 48614030..9f3e2637 100644 --- a/pyrogram/client/methods/messages/get_history_count.py +++ b/pyrogram/client/methods/messages/get_history_count.py @@ -17,12 +17,10 @@ # along with Pyrogram. If not, see . import logging -import time from typing import Union from pyrogram.api import types, functions from pyrogram.client.ext import BaseClient -from pyrogram.errors import FloodWait log = logging.getLogger(__name__) @@ -51,34 +49,20 @@ class GetHistoryCount(BaseClient): RPCError: In case of a Telegram RPC error. """ - peer = self.resolve_peer(chat_id) + r = self.send( + functions.messages.GetHistory( + peer=self.resolve_peer(chat_id), + offset_id=0, + offset_date=0, + add_offset=0, + limit=1, + max_id=0, + min_id=0, + hash=0 + ) + ) - if not isinstance(peer, types.InputPeerChannel): - offset = 0 - limit = 100 - - while True: - try: - r = self.send( - functions.messages.GetHistory( - peer=peer, - offset_id=1, - offset_date=0, - add_offset=-offset - limit, - limit=limit, - max_id=0, - min_id=0, - hash=0 - ) - ) - except FloodWait as e: - log.warning("Sleeping for {}s".format(e.x)) - time.sleep(e.x) - continue - - if not r.messages: - return offset - - offset += len(r.messages) - - return self.get_history(chat_id=chat_id, limit=1).total_count + if isinstance(r, types.messages.Messages): + return len(r.messages) + else: + return r.count From aaaa119318294fc531755c388589850f3f935b17 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 12:41:55 +0200 Subject: [PATCH 187/202] Hint about which DC exactly is having problems. --- compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv index c85fe7e0..446fe908 100644 --- a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv +++ b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv @@ -7,6 +7,6 @@ HISTORY_GET_FAILED Telegram is having internal problems. Please try again later REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later WORKER_BUSY_TOO_LONG_RETRY Telegram is having internal problems. Please try again later -INTERDC_X_CALL_ERROR Telegram is having internal problems. Please try again later -INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems. Please try again later +INTERDC_X_CALL_ERROR Telegram is having internal problems at DC{x}. Please try again later +INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems at DC{x}. Please try again later FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later \ No newline at end of file From 1ce749a562250fd002e2fb24c3a5aee85e1d5e10 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 12:42:39 +0200 Subject: [PATCH 188/202] Hint about the Advanced Usage page in the method index --- docs/source/api/methods.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index 58836efa..ac515f6e 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -159,6 +159,8 @@ Bots Advanced Usage (Raw API) ^^^^^^^^^^^^^^^^^^^^^^^^ +Learn more about these methods at :doc:`Advanced Usage <../topics/advanced-usage>`. + .. hlist:: :columns: 4 From 93082ce8941f90a91fd11470d55e5f80f29634b5 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 13:43:28 +0200 Subject: [PATCH 189/202] Reword get_user_dc docstrings --- pyrogram/client/methods/users/get_user_dc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/methods/users/get_user_dc.py b/pyrogram/client/methods/users/get_user_dc.py index 718f4c44..75587884 100644 --- a/pyrogram/client/methods/users/get_user_dc.py +++ b/pyrogram/client/methods/users/get_user_dc.py @@ -24,7 +24,7 @@ from ...ext import BaseClient class GetUserDC(BaseClient): def get_user_dc(self, user_id: Union[int, str]) -> Union[int, None]: - """Get the assigned data center (DC) of a user. + """Get the assigned DC (data center) of a user. .. note:: From c8b4f3dac9b6c23cdb9814150c44c82120b54863 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 14:05:59 +0200 Subject: [PATCH 190/202] Add FAQ about Pyrogram stability and reliability --- docs/source/faq.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index f08da03f..0d56451a 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -53,6 +53,22 @@ Why Pyrogram? .. _TgCrypto: https://github.com/pyrogram/tgcrypto +How stable and reliable is Pyrogram? +------------------------------------ + +So far, since its first public release, Pyrogram has always shown itself to be quite reliable in handling client-server +interconnections and just as stable when keeping long running applications online. The only annoying issues faced are +actually coming from Telegram servers internal errors and down times, from which Pyrogram is able to recover itself +automatically. + +To challenge the framework, the creator is constantly keeping a public +`welcome bot `_ online 24/7 on his own, +relatively-busy account for well over a year now. + +In addition to that, about six months ago, one of the most popular Telegram bot has been rewritten +:doc:`using Pyrogram ` and is serving more than 200,000 Monthly Active Users since +then, uninterruptedly and without any need for restarting it. + What can MTProto do more than the Bot API? ------------------------------------------ From a2d1752e89336b7de31b698d03be3a96f8f0cfd9 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 12 Jun 2019 22:26:41 +0200 Subject: [PATCH 191/202] Update information about Telegram DCs. Also add IPv6 addresses Thanks Fela for pointing it out that only DC3 is an alias, DC2 and DC4 are both functioning independently, as per latest information. --- docs/source/faq.rst | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 0d56451a..449076af 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -156,18 +156,34 @@ fails or not. What are the IP addresses of Telegram Data Centers? --------------------------------------------------- -Telegram is currently composed by a decentralized, multi-DC infrastructure (each of which can work independently) spread -in 5 different locations. However, two of the less busy DCs have been lately dismissed and their IP addresses are now -kept as aliases. +The Telegram cloud is currently composed by a decentralized, multi-DC infrastructure (each of which can work +independently) spread in 5 different locations. However, some of the less busy DCs have been lately dismissed and their +IP addresses are now kept as aliases. -- **DC1** - MIA, Miami FL, USA: ``149.154.175.50`` -- **DC2** - AMS, Amsterdam, NL: ``149.154.167.51`` -- **DC3*** - MIA, Miami FL, USA: ``149.154.175.100`` -- **DC4*** - AMS, Amsterdam, NL: ``149.154.167.91`` -- **DC5** - SIN, Singapore, SG: ``91.108.56.149`` +.. csv-table:: Production Environment + :header: ID, Location, IPv4, IPv6 + :widths: auto + :align: center + + DC1, "MIA, Miami FL, USA", ``149.154.175.50``, ``2001:b28:f23d:f001::a`` + DC2, "AMS, Amsterdam, NL", ``149.154.167.51``, ``2001:67c:4e8:f002::a`` + DC3*, "MIA, Miami FL, USA", ``149.154.175.100``, ``2001:b28:f23d:f003::a`` + DC4, "AMS, Amsterdam, NL", ``149.154.167.91``, ``2001:67c:4e8:f004::a`` + DC5, "SIN, Singapore, SG", ``91.108.56.149``, ``2001:b28:f23f:f005::a`` + +.. csv-table:: Test Environment + :header: ID, Location, IPv4, IPv6 + :widths: auto + :align: center + + DC1, "MIA, Miami FL, USA", ``149.154.175.10``, ``2001:b28:f23d:f001::e`` + DC2, "AMS, Amsterdam, NL", ``149.154.167.40``, ``2001:67c:4e8:f002::e`` + DC3*, "MIA, Miami FL, USA", ``149.154.175.117``, ``2001:b28:f23d:f003::e`` ***** Alias DC +More info about the Test Environment can be found :doc:`here `. + I want to migrate my account from DCX to DCY. --------------------------------------------- From 22199b0fe54fadefeac2b4b56e5e2f5b81f1b8b0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 14 Jun 2019 02:12:06 +0200 Subject: [PATCH 192/202] Implement editing of messages sent via inline bots - edit_message_text - edit_message_caption - edit_message_media - edit_message_reply_markup --- pyrogram/client/ext/base_client.py | 3 ++ pyrogram/client/ext/utils.py | 12 +++++ .../methods/messages/edit_message_caption.py | 51 +++++++++---------- .../methods/messages/edit_message_media.py | 51 ++++++++++++------- .../messages/edit_message_reply_markup.py | 36 +++++++++---- .../methods/messages/edit_message_text.py | 34 ++++++++++--- 6 files changed, 122 insertions(+), 65 deletions(-) diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index 9e7cd677..b4c16666 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -156,3 +156,6 @@ class BaseClient: def get_profile_photos(self, *args, **kwargs): pass + + def edit_message_text(self, *args, **kwargs): + pass diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 41270d39..fa107fab 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +import base64 import struct from base64 import b64decode, b64encode from typing import Union, List @@ -191,3 +192,14 @@ def parse_deleted_messages(client, update) -> List["pyrogram.Message"]: ) return pyrogram.List(parsed_messages) + + +def unpack_inline_message_id(inline_message_id: str) -> types.InputBotInlineMessageID: + r = inline_message_id + "=" * (-len(inline_message_id) % 4) + r = struct.unpack(" "pyrogram.Message": - """Edit captions of messages. + """Edit caption of media messages. Parameters: - chat_id (``int`` | ``str``): + caption (``str``): + New caption of the media message. + + chat_id (``int`` | ``str``, *optional*): + Required if *inline_message_id* is not specified. Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``): + message_id (``int``, *optional*): + Required if *inline_message_id* is not specified. Message identifier in the chat specified in chat_id. - caption (``str``): - New caption of the message. + inline_message_id (``str``, *optional*): + Required if *chat_id* and *message_id* are not specified. + Identifier of the inline message. parse_mode (``str``, *optional*): Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline - URLs in your caption. Defaults to "markdown". + URLs in your message. Defaults to "markdown". reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. Returns: - :obj:`Message`: On success, the edited message is returned. + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). Raises: RPCError: In case of a Telegram RPC error. """ - style = self.html if parse_mode.lower() == "html" else self.markdown - - r = self.send( - functions.messages.EditMessage( - peer=self.resolve_peer(chat_id), - id=message_id, - reply_markup=reply_markup.write() if reply_markup else None, - **style.parse(caption) - ) + return self.edit_message_text( + text=caption, + chat_id=chat_id, + message_id=message_id, + inline_message_id=inline_message_id, + parse_mode=parse_mode, + reply_markup=reply_markup ) - - for i in r.updates: - if isinstance(i, (types.UpdateEditMessage, types.UpdateEditChannelMessage)): - return pyrogram.Message._parse( - self, i.message, - {i.id: i for i in r.users}, - {i.id: i for i in r.chats} - ) diff --git a/pyrogram/client/methods/messages/edit_message_media.py b/pyrogram/client/methods/messages/edit_message_media.py index 3793c693..2b3ca5d5 100644 --- a/pyrogram/client/methods/messages/edit_message_media.py +++ b/pyrogram/client/methods/messages/edit_message_media.py @@ -32,35 +32,42 @@ from pyrogram.client.types.input_media import InputMedia class EditMessageMedia(BaseClient): def edit_message_media( self, - chat_id: Union[int, str], - message_id: int, media: InputMedia, + chat_id: Union[int, str] = None, + message_id: int = None, + inline_message_id: str = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": - """Edit audio, document, photo, or video messages. + """Edit animation, audio, document, photo or video messages. If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. - Use previously uploaded file via its file_id or specify a URL. On success, if the edited message was sent - by the bot, the edited Message is returned, otherwise True is returned. + Use previously uploaded file via its file_id or specify a URL. Parameters: - chat_id (``int`` | ``str``): + media (:obj:`InputMedia`) + One of the InputMedia objects describing an animation, audio, document, photo or video. + + chat_id (``int`` | ``str``, *optional*): + Required if *inline_message_id* is not specified. Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``): + message_id (``int``, *optional*): + Required if *inline_message_id* is not specified. Message identifier in the chat specified in chat_id. - media (:obj:`InputMedia`) - One of the InputMedia objects describing an animation, audio, document, photo or video. + inline_message_id (``str``, *optional*): + Required if *chat_id* and *message_id* are not specified. + Identifier of the inline message. reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. Returns: - :obj:`Message`: On success, the edited message is returned. + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). Raises: RPCError: In case of a Telegram RPC error. @@ -92,8 +99,7 @@ class EditMessageMedia(BaseClient): ) else: media = utils.get_input_media_from_file_id(media.media, 2) - - if isinstance(media, InputMediaVideo): + elif isinstance(media, InputMediaVideo): if os.path.exists(media.media): media = self.send( functions.messages.UploadMedia( @@ -130,8 +136,7 @@ class EditMessageMedia(BaseClient): ) else: media = utils.get_input_media_from_file_id(media.media, 4) - - if isinstance(media, InputMediaAudio): + elif isinstance(media, InputMediaAudio): if os.path.exists(media.media): media = self.send( functions.messages.UploadMedia( @@ -167,8 +172,7 @@ class EditMessageMedia(BaseClient): ) else: media = utils.get_input_media_from_file_id(media.media, 9) - - if isinstance(media, InputMediaAnimation): + elif isinstance(media, InputMediaAnimation): if os.path.exists(media.media): media = self.send( functions.messages.UploadMedia( @@ -206,8 +210,7 @@ class EditMessageMedia(BaseClient): ) else: media = utils.get_input_media_from_file_id(media.media, 10) - - if isinstance(media, InputMediaDocument): + elif isinstance(media, InputMediaDocument): if os.path.exists(media.media): media = self.send( functions.messages.UploadMedia( @@ -239,12 +242,22 @@ class EditMessageMedia(BaseClient): else: media = utils.get_input_media_from_file_id(media.media, 5) + if inline_message_id is not None: + return self.send( + functions.messages.EditInlineBotMessage( + id=utils.unpack_inline_message_id(inline_message_id), + media=media, + reply_markup=reply_markup.write() if reply_markup else None, + **style.parse(caption) + ) + ) + r = self.send( functions.messages.EditMessage( peer=self.resolve_peer(chat_id), id=message_id, - reply_markup=reply_markup.write() if reply_markup else None, media=media, + reply_markup=reply_markup.write() if reply_markup else None, **style.parse(caption) ) ) diff --git a/pyrogram/client/methods/messages/edit_message_reply_markup.py b/pyrogram/client/methods/messages/edit_message_reply_markup.py index a058646f..516d7b9c 100644 --- a/pyrogram/client/methods/messages/edit_message_reply_markup.py +++ b/pyrogram/client/methods/messages/edit_message_reply_markup.py @@ -20,43 +20,57 @@ from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.client.ext import BaseClient +from pyrogram.client.ext import BaseClient, utils class EditMessageReplyMarkup(BaseClient): def edit_message_reply_markup( self, - chat_id: Union[int, str], - message_id: int, - reply_markup: "pyrogram.InlineKeyboardMarkup" = None + reply_markup: "pyrogram.InlineKeyboardMarkup" = None, + chat_id: Union[int, str] = None, + message_id: int = None, + inline_message_id: str = None ) -> "pyrogram.Message": """Edit only the reply markup of messages sent by the bot or via the bot (for inline bots). Parameters: - chat_id (``int`` | ``str``): + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + chat_id (``int`` | ``str``, *optional*): + Required if *inline_message_id* is not specified. Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``): + message_id (``int``, *optional*): + Required if *inline_message_id* is not specified. Message identifier in the chat specified in chat_id. - reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): - An InlineKeyboardMarkup object. + inline_message_id (``str``, *optional*): + Required if *chat_id* and *message_id* are not specified. + Identifier of the inline message. Returns: - :obj:`Message` | ``bool``: In case the edited message is sent by the bot, the edited message is returned, - otherwise, True is returned in case the edited message is send by the user. + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). Raises: RPCError: In case of a Telegram RPC error. """ + if inline_message_id is not None: + return self.send( + functions.messages.EditInlineBotMessage( + id=utils.unpack_inline_message_id(inline_message_id), + reply_markup=reply_markup.write() if reply_markup else None, + ) + ) r = self.send( functions.messages.EditMessage( peer=self.resolve_peer(chat_id), id=message_id, - reply_markup=reply_markup.write() if reply_markup else None + reply_markup=reply_markup.write() if reply_markup else None, ) ) diff --git a/pyrogram/client/methods/messages/edit_message_text.py b/pyrogram/client/methods/messages/edit_message_text.py index 69283e89..919e5dc1 100644 --- a/pyrogram/client/methods/messages/edit_message_text.py +++ b/pyrogram/client/methods/messages/edit_message_text.py @@ -20,15 +20,16 @@ from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.client.ext import BaseClient +from pyrogram.client.ext import BaseClient, utils class EditMessageText(BaseClient): def edit_message_text( self, - chat_id: Union[int, str], - message_id: int, text: str, + chat_id: Union[int, str] = None, + message_id: int = None, + inline_message_id: str = None, parse_mode: str = "", disable_web_page_preview: bool = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None @@ -36,16 +37,22 @@ class EditMessageText(BaseClient): """Edit text messages. Parameters: - chat_id (``int`` | ``str``): + text (``str``): + New text of the message. + + chat_id (``int`` | ``str``, *optional*): + Required if *inline_message_id* is not specified. Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``): + message_id (``int``, *optional*): + Required if *inline_message_id* is not specified. Message identifier in the chat specified in chat_id. - text (``str``): - New text of the message. + inline_message_id (``str``, *optional*): + Required if *chat_id* and *message_id* are not specified. + Identifier of the inline message. parse_mode (``str``, *optional*): Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline @@ -58,13 +65,24 @@ class EditMessageText(BaseClient): An InlineKeyboardMarkup object. Returns: - :obj:`Message`: On success, the edited message is returned. + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). Raises: RPCError: In case of a Telegram RPC error. """ style = self.html if parse_mode.lower() == "html" else self.markdown + if inline_message_id is not None: + return self.send( + functions.messages.EditInlineBotMessage( + id=utils.unpack_inline_message_id(inline_message_id), + no_webpage=disable_web_page_preview or None, + reply_markup=reply_markup.write() if reply_markup else None, + **style.parse(text) + ) + ) + r = self.send( functions.messages.EditMessage( peer=self.resolve_peer(chat_id), From da4ff268a41073e0767373532f69c58ac8394333 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 14 Jun 2019 02:46:27 +0200 Subject: [PATCH 193/202] Add edit, edit_caption, edit_media and edit_reply_markup bound methods to the CallbackQuery type --- docs/source/api/bound-methods.rst | 10 +- pyrogram/client/ext/base_client.py | 6 + .../bots_and_keyboards/callback_query.py | 172 ++++++++++++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index d01a4383..38389ae6 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -81,9 +81,13 @@ CallbackQuery ^^^^^^^^^^^^^ .. hlist:: - :columns: 2 + :columns: 5 - :meth:`~CallbackQuery.answer` + - :meth:`~CallbackQuery.edit` + - :meth:`~CallbackQuery.edit_caption` + - :meth:`~CallbackQuery.edit_media` + - :meth:`~CallbackQuery.edit_reply_markup` InlineQuery ^^^^^^^^^^^ @@ -137,6 +141,10 @@ Details .. CallbackQuery .. automethod:: CallbackQuery.answer() +.. automethod:: CallbackQuery.edit() +.. automethod:: CallbackQuery.edit_caption() +.. automethod:: CallbackQuery.edit_media() +.. automethod:: CallbackQuery.edit_reply_markup() .. InlineQuery .. automethod:: InlineQuery.answer() diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index b4c16666..e584c743 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -159,3 +159,9 @@ class BaseClient: def edit_message_text(self, *args, **kwargs): pass + + def edit_message_media(self, *args, **kwargs): + pass + + def edit_message_reply_markup(self, *args, **kwargs): + pass diff --git a/pyrogram/client/types/bots_and_keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py index fa0d8be2..df0f6d33 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_query.py @@ -172,3 +172,175 @@ class CallbackQuery(Object, Update): url=url, cache_time=cache_time ) + + def edit( + self, + text: str, + parse_mode: str = "", + disable_web_page_preview: bool = None, + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> Union["pyrogram.Message", bool]: + """Bound method *edit* of :obj:`CallbackQuery`. + + Parameters: + text (``str``): + New text of the message. + + parse_mode (``str``, *optional*): + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". + + disable_web_page_preview (``bool``, *optional*): + Disables link previews for links in this message. + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). + + Raises: + RPCError: In case of a Telegram RPC error. + """ + chat_id = None + message_id = None + inline_message_id = None + + if self.message is not None: + chat_id = self.message.chat.id + message_id = self.message.message_id + + if self.inline_message_id is not None: + inline_message_id = self.inline_message_id + + return self._client.edit_message_text( + text=text, + chat_id=chat_id, + message_id=message_id, + inline_message_id=inline_message_id, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup + ) + + def edit_caption( + self, + caption: str, + parse_mode: str = "", + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> Union["pyrogram.Message", bool]: + """Bound method *edit_caption* of :obj:`Message`. + + Parameters: + caption (``str``): + New caption of the message. + + parse_mode (``str``, *optional*): + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). + + Raises: + RPCError: In case of a Telegram RPC error. + """ + chat_id = None + message_id = None + inline_message_id = None + + if self.message is not None: + chat_id = self.message.chat.id + message_id = self.message.message_id + + if self.inline_message_id is not None: + inline_message_id = self.inline_message_id + + return self._client.edit_message_text( + text=caption, + chat_id=chat_id, + message_id=message_id, + inline_message_id=inline_message_id, + parse_mode=parse_mode, + reply_markup=reply_markup + ) + + def edit_media( + self, + media: "pyrogram.InputMedia", + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> Union["pyrogram.Message", bool]: + """Bound method *edit_media* of :obj:`Message`. + + Parameters: + media (:obj:`InputMedia`): + One of the InputMedia objects describing an animation, audio, document, photo or video. + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). + + Raises: + RPCError: In case of a Telegram RPC error. + """ + chat_id = None + message_id = None + inline_message_id = None + + if self.message is not None: + chat_id = self.message.chat.id + message_id = self.message.message_id + + if self.inline_message_id is not None: + inline_message_id = self.inline_message_id + + return self._client.edit_message_media( + media=media, + chat_id=chat_id, + message_id=message_id, + inline_message_id=inline_message_id, + reply_markup=reply_markup + ) + + def edit_reply_markup( + self, + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> Union["pyrogram.Message", bool]: + """Bound method *edit_reply_markup* of :obj:`Message`. + + Parameters: + reply_markup (:obj:`InlineKeyboardMarkup`): + An InlineKeyboardMarkup object. + + Returns: + :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is + returned, otherwise True is returned (message sent via the bot, as inline query result). + + Raises: + RPCError: In case of a Telegram RPC error. + """ + chat_id = None + message_id = None + inline_message_id = None + + if self.message is not None: + chat_id = self.message.chat.id + message_id = self.message.message_id + + if self.inline_message_id is not None: + inline_message_id = self.inline_message_id + + return self._client.edit_message_reply_markup( + reply_markup=reply_markup, + chat_id=chat_id, + message_id=message_id, + inline_message_id=inline_message_id + ) From c485715db1b3ea9578d334624113b8a7f563912f Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 14 Jun 2019 02:47:17 +0200 Subject: [PATCH 194/202] Small docstrings fixup --- .../methods/messages/edit_message_media.py | 2 +- .../client/types/messages_and_media/message.py | 16 +++------------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/pyrogram/client/methods/messages/edit_message_media.py b/pyrogram/client/methods/messages/edit_message_media.py index 2b3ca5d5..d74e2b56 100644 --- a/pyrogram/client/methods/messages/edit_message_media.py +++ b/pyrogram/client/methods/messages/edit_message_media.py @@ -45,7 +45,7 @@ class EditMessageMedia(BaseClient): Use previously uploaded file via its file_id or specify a URL. Parameters: - media (:obj:`InputMedia`) + media (:obj:`InputMedia`): One of the InputMedia objects describing an animation, audio, document, photo or video. chat_id (``int`` | ``str``, *optional*): diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index c6f3cc77..2a1ba2c8 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -2361,12 +2361,7 @@ class Message(Object, Update): text: str, parse_mode: str = "", disable_web_page_preview: bool = None, - reply_markup: Union[ - "pyrogram.InlineKeyboardMarkup", - "pyrogram.ReplyKeyboardMarkup", - "pyrogram.ReplyKeyboardRemove", - "pyrogram.ForceReply" - ] = None + reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "Message": """Bound method *edit* of :obj:`Message`. @@ -2418,12 +2413,7 @@ class Message(Object, Update): self, caption: str, parse_mode: str = "", - reply_markup: Union[ - "pyrogram.InlineKeyboardMarkup", - "pyrogram.ReplyKeyboardMarkup", - "pyrogram.ReplyKeyboardRemove", - "pyrogram.ForceReply" - ] = None + reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "Message": """Bound method *edit_caption* of :obj:`Message`. @@ -2486,7 +2476,7 @@ class Message(Object, Update): message.edit_media(media) Parameters: - media (:obj:`InputMediaAnimation` | :obj:`InputMediaAudio` | :obj:`InputMediaDocument` | :obj:`InputMediaPhoto` | :obj:`InputMediaVideo`) + media (:obj:`InputMedia`): One of the InputMedia objects describing an animation, audio, document, photo or video. reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): From 3ae77d55c758f91346ad8a122d0da2a3d65fd545 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 14 Jun 2019 02:52:01 +0200 Subject: [PATCH 195/202] Rename edit -> edit_text and reply -> reply_text bound methods --- docs/source/api/bound-methods.rst | 20 +++++++++---------- .../bots_and_keyboards/callback_query.py | 4 ++-- .../types/messages_and_media/message.py | 12 +++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index 38389ae6..2f2200ab 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -34,13 +34,13 @@ Message - :meth:`~Message.click` - :meth:`~Message.delete` - :meth:`~Message.download` - - :meth:`~Message.edit` + - :meth:`~Message.forward` + - :meth:`~Message.pin` + - :meth:`~Message.edit_text` - :meth:`~Message.edit_caption` - :meth:`~Message.edit_media` - :meth:`~Message.edit_reply_markup` - - :meth:`~Message.forward` - - :meth:`~Message.pin` - - :meth:`~Message.reply` + - :meth:`~Message.reply_text` - :meth:`~Message.reply_animation` - :meth:`~Message.reply_audio` - :meth:`~Message.reply_cached_media` @@ -84,7 +84,7 @@ CallbackQuery :columns: 5 - :meth:`~CallbackQuery.answer` - - :meth:`~CallbackQuery.edit` + - :meth:`~CallbackQuery.edit_text` - :meth:`~CallbackQuery.edit_caption` - :meth:`~CallbackQuery.edit_media` - :meth:`~CallbackQuery.edit_reply_markup` @@ -106,13 +106,13 @@ Details .. automethod:: Message.click() .. automethod:: Message.delete() .. automethod:: Message.download() -.. automethod:: Message.edit() +.. automethod:: Message.forward() +.. automethod:: Message.pin() +.. automethod:: Message.edit_text() .. automethod:: Message.edit_caption() .. automethod:: Message.edit_media() .. automethod:: Message.edit_reply_markup() -.. automethod:: Message.forward() -.. automethod:: Message.pin() -.. automethod:: Message.reply() +.. automethod:: Message.reply_text() .. automethod:: Message.reply_animation() .. automethod:: Message.reply_audio() .. automethod:: Message.reply_cached_media() @@ -141,7 +141,7 @@ Details .. CallbackQuery .. automethod:: CallbackQuery.answer() -.. automethod:: CallbackQuery.edit() +.. automethod:: CallbackQuery.edit_text() .. automethod:: CallbackQuery.edit_caption() .. automethod:: CallbackQuery.edit_media() .. automethod:: CallbackQuery.edit_reply_markup() diff --git a/pyrogram/client/types/bots_and_keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py index df0f6d33..4bb4a7e4 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_query.py @@ -173,14 +173,14 @@ class CallbackQuery(Object, Update): cache_time=cache_time ) - def edit( + def edit_text( self, text: str, parse_mode: str = "", disable_web_page_preview: bool = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit* of :obj:`CallbackQuery`. + """Bound method *edit_text* of :obj:`CallbackQuery`. Parameters: text (``str``): diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 2a1ba2c8..cd59b5eb 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -651,7 +651,7 @@ class Message(Object, Update): return parsed_message - def reply( + def reply_text( self, text: str, quote: bool = None, @@ -661,7 +661,7 @@ class Message(Object, Update): reply_to_message_id: int = None, reply_markup=None ) -> "Message": - """Bound method *reply* of :obj:`Message`. + """Bound method *reply_text* of :obj:`Message`. Use as a shortcut for: @@ -676,7 +676,7 @@ class Message(Object, Update): Example: .. code-block:: python - message.reply("hello", quote=True) + message.reply_text("hello", quote=True) Parameters: text (``str``): @@ -2356,14 +2356,14 @@ class Message(Object, Update): progress_args=progress_args ) - def edit( + def edit_text( self, text: str, parse_mode: str = "", disable_web_page_preview: bool = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "Message": - """Bound method *edit* of :obj:`Message`. + """Bound method *edit_text* of :obj:`Message`. Use as a shortcut for: @@ -2378,7 +2378,7 @@ class Message(Object, Update): Example: .. code-block:: python - message.edit("hello") + message.edit_text("hello") Parameters: text (``str``): From 3ed1bb0d86e604d75a809468f3395cd401d060a6 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 14 Jun 2019 03:57:12 +0200 Subject: [PATCH 196/202] Rename CallbackQuery edit_* bound methods to edit_message_* We are editing the message the callback query comes from, not the callback query itself. --- docs/source/api/bound-methods.rst | 18 +++++++++--------- .../types/bots_and_keyboards/callback_query.py | 16 ++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index 2f2200ab..83b3dbbe 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -81,13 +81,13 @@ CallbackQuery ^^^^^^^^^^^^^ .. hlist:: - :columns: 5 + :columns: 3 - :meth:`~CallbackQuery.answer` - - :meth:`~CallbackQuery.edit_text` - - :meth:`~CallbackQuery.edit_caption` - - :meth:`~CallbackQuery.edit_media` - - :meth:`~CallbackQuery.edit_reply_markup` + - :meth:`~CallbackQuery.edit_message_text` + - :meth:`~CallbackQuery.edit_message_caption` + - :meth:`~CallbackQuery.edit_message_media` + - :meth:`~CallbackQuery.edit_message_reply_markup` InlineQuery ^^^^^^^^^^^ @@ -141,10 +141,10 @@ Details .. CallbackQuery .. automethod:: CallbackQuery.answer() -.. automethod:: CallbackQuery.edit_text() -.. automethod:: CallbackQuery.edit_caption() -.. automethod:: CallbackQuery.edit_media() -.. automethod:: CallbackQuery.edit_reply_markup() +.. automethod:: CallbackQuery.edit_message_text() +.. automethod:: CallbackQuery.edit_message_caption() +.. automethod:: CallbackQuery.edit_message_media() +.. automethod:: CallbackQuery.edit_message_reply_markup() .. InlineQuery .. automethod:: InlineQuery.answer() diff --git a/pyrogram/client/types/bots_and_keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py index 4bb4a7e4..6872d65b 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_query.py @@ -173,14 +173,14 @@ class CallbackQuery(Object, Update): cache_time=cache_time ) - def edit_text( + def edit_message_text( self, text: str, parse_mode: str = "", disable_web_page_preview: bool = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_text* of :obj:`CallbackQuery`. + """Bound method *edit_message_text* of :obj:`CallbackQuery`. Parameters: text (``str``): @@ -224,13 +224,13 @@ class CallbackQuery(Object, Update): reply_markup=reply_markup ) - def edit_caption( + def edit_message_caption( self, caption: str, parse_mode: str = "", reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_caption* of :obj:`Message`. + """Bound method *edit_message_caption* of :obj:`CallbackQuery`. Parameters: caption (``str``): @@ -270,12 +270,12 @@ class CallbackQuery(Object, Update): reply_markup=reply_markup ) - def edit_media( + def edit_message_media( self, media: "pyrogram.InputMedia", reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_media* of :obj:`Message`. + """Bound method *edit_message_media* of :obj:`CallbackQuery`. Parameters: media (:obj:`InputMedia`): @@ -310,11 +310,11 @@ class CallbackQuery(Object, Update): reply_markup=reply_markup ) - def edit_reply_markup( + def edit_message_reply_markup( self, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_reply_markup* of :obj:`Message`. + """Bound method *edit_message_reply_markup* of :obj:`CallbackQuery`. Parameters: reply_markup (:obj:`InlineKeyboardMarkup`): From 61ed44ff5f1c2dee91da309ce24f6b2b5884be13 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 14 Jun 2019 04:52:05 +0200 Subject: [PATCH 197/202] Add edit_inline_* methods to deal with inline messages only --- docs/source/api/methods.rst | 14 ++- pyrogram/client/ext/base_client.py | 9 ++ pyrogram/client/methods/messages/__init__.py | 10 +- .../methods/messages/edit_inline_caption.py | 58 ++++++++++ .../methods/messages/edit_inline_media.py | 104 ++++++++++++++++++ .../messages/edit_inline_reply_markup.py | 50 +++++++++ .../methods/messages/edit_inline_text.py | 67 +++++++++++ .../methods/messages/edit_message_caption.py | 27 ++--- .../methods/messages/edit_message_media.py | 37 ++----- .../messages/edit_message_reply_markup.py | 34 ++---- .../methods/messages/edit_message_text.py | 36 ++---- 11 files changed, 344 insertions(+), 102 deletions(-) create mode 100644 pyrogram/client/methods/messages/edit_inline_caption.py create mode 100644 pyrogram/client/methods/messages/edit_inline_media.py create mode 100644 pyrogram/client/methods/messages/edit_inline_reply_markup.py create mode 100644 pyrogram/client/methods/messages/edit_inline_text.py diff --git a/docs/source/api/methods.rst b/docs/source/api/methods.rst index ac515f6e..4a3eefd8 100644 --- a/docs/source/api/methods.rst +++ b/docs/source/api/methods.rst @@ -55,11 +55,15 @@ Messages - :meth:`~Client.send_venue` - :meth:`~Client.send_contact` - :meth:`~Client.send_cached_media` - - :meth:`~Client.send_chat_action` - :meth:`~Client.edit_message_text` - :meth:`~Client.edit_message_caption` - - :meth:`~Client.edit_message_reply_markup` - :meth:`~Client.edit_message_media` + - :meth:`~Client.edit_message_reply_markup` + - :meth:`~Client.edit_inline_text` + - :meth:`~Client.edit_inline_caption` + - :meth:`~Client.edit_inline_media` + - :meth:`~Client.edit_inline_reply_markup` + - :meth:`~Client.send_chat_action` - :meth:`~Client.delete_messages` - :meth:`~Client.get_messages` - :meth:`~Client.get_history` @@ -203,8 +207,12 @@ Details .. automethod:: Client.send_chat_action() .. automethod:: Client.edit_message_text() .. automethod:: Client.edit_message_caption() -.. automethod:: Client.edit_message_reply_markup() .. automethod:: Client.edit_message_media() +.. automethod:: Client.edit_message_reply_markup() +.. automethod:: Client.edit_inline_text() +.. automethod:: Client.edit_inline_caption() +.. automethod:: Client.edit_inline_media() +.. automethod:: Client.edit_inline_reply_markup() .. automethod:: Client.delete_messages() .. automethod:: Client.get_messages() .. automethod:: Client.get_history() diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index e584c743..c8d1beab 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -160,8 +160,17 @@ class BaseClient: def edit_message_text(self, *args, **kwargs): pass + def edit_inline_text(self, *args, **kwargs): + pass + def edit_message_media(self, *args, **kwargs): pass + def edit_inline_media(self, *args, **kwargs): + pass + def edit_message_reply_markup(self, *args, **kwargs): pass + + def edit_inline_reply_markup(self, *args, **kwargs): + pass diff --git a/pyrogram/client/methods/messages/__init__.py b/pyrogram/client/methods/messages/__init__.py index 07df7a64..aa0b0c94 100644 --- a/pyrogram/client/methods/messages/__init__.py +++ b/pyrogram/client/methods/messages/__init__.py @@ -18,6 +18,10 @@ from .delete_messages import DeleteMessages from .download_media import DownloadMedia +from .edit_inline_caption import EditInlineCaption +from .edit_inline_media import EditInlineMedia +from .edit_inline_reply_markup import EditInlineReplyMarkup +from .edit_inline_text import EditInlineText from .edit_message_caption import EditMessageCaption from .edit_message_media import EditMessageMedia from .edit_message_reply_markup import EditMessageReplyMarkup @@ -82,6 +86,10 @@ class Messages( SendCachedMedia, GetHistoryCount, SendAnimatedSticker, - ReadHistory + ReadHistory, + EditInlineText, + EditInlineCaption, + EditInlineMedia, + EditInlineReplyMarkup ): pass diff --git a/pyrogram/client/methods/messages/edit_inline_caption.py b/pyrogram/client/methods/messages/edit_inline_caption.py new file mode 100644 index 00000000..a9bbc551 --- /dev/null +++ b/pyrogram/client/methods/messages/edit_inline_caption.py @@ -0,0 +1,58 @@ +# 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 . + +import pyrogram +from pyrogram.client.ext import BaseClient + + +class EditInlineCaption(BaseClient): + def edit_inline_caption( + self, + inline_message_id: str, + caption: str, + parse_mode: str = "", + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> bool: + """Edit the caption of **inline** media messages. + + Parameters: + inline_message_id (``str``): + Identifier of the inline message. + + caption (``str``): + New caption of the media message. + + parse_mode (``str``, *optional*): + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + return self.edit_inline_text( + inline_message_id=inline_message_id, + text=caption, + parse_mode=parse_mode, + reply_markup=reply_markup + ) diff --git a/pyrogram/client/methods/messages/edit_inline_media.py b/pyrogram/client/methods/messages/edit_inline_media.py new file mode 100644 index 00000000..87e692fd --- /dev/null +++ b/pyrogram/client/methods/messages/edit_inline_media.py @@ -0,0 +1,104 @@ +# 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 . + +import pyrogram +from pyrogram.api import functions, types +from pyrogram.client.ext import BaseClient, utils +from pyrogram.client.types import ( + InputMediaPhoto, InputMediaVideo, InputMediaAudio, + InputMediaAnimation, InputMediaDocument +) +from pyrogram.client.types.input_media import InputMedia + + +class EditInlineMedia(BaseClient): + def edit_inline_media( + self, + inline_message_id: str, + media: InputMedia, + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> bool: + """Edit **inline** animation, audio, document, photo or video messages. + + When the inline message is edited, a new file can't be uploaded. Use a previously uploaded file via its file_id + or specify a URL. + + Parameters: + inline_message_id (``str``): + Required if *chat_id* and *message_id* are not specified. + Identifier of the inline message. + + media (:obj:`InputMedia`): + One of the InputMedia objects describing an animation, audio, document, photo or video. + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + style = self.html if media.parse_mode.lower() == "html" else self.markdown + caption = media.caption + + if isinstance(media, InputMediaPhoto): + if media.media.startswith("http"): + media = types.InputMediaPhotoExternal( + url=media.media + ) + else: + media = utils.get_input_media_from_file_id(media.media, 2) + elif isinstance(media, InputMediaVideo): + if media.media.startswith("http"): + media = types.InputMediaDocumentExternal( + url=media.media + ) + else: + media = utils.get_input_media_from_file_id(media.media, 4) + elif isinstance(media, InputMediaAudio): + if media.media.startswith("http"): + media = types.InputMediaDocumentExternal( + url=media.media + ) + else: + media = utils.get_input_media_from_file_id(media.media, 9) + elif isinstance(media, InputMediaAnimation): + if media.media.startswith("http"): + media = types.InputMediaDocumentExternal( + url=media.media + ) + else: + media = utils.get_input_media_from_file_id(media.media, 10) + elif isinstance(media, InputMediaDocument): + if media.media.startswith("http"): + media = types.InputMediaDocumentExternal( + url=media.media + ) + else: + media = utils.get_input_media_from_file_id(media.media, 5) + + return self.send( + functions.messages.EditInlineBotMessage( + id=utils.unpack_inline_message_id(inline_message_id), + media=media, + reply_markup=reply_markup.write() if reply_markup else None, + **style.parse(caption) + ) + ) diff --git a/pyrogram/client/methods/messages/edit_inline_reply_markup.py b/pyrogram/client/methods/messages/edit_inline_reply_markup.py new file mode 100644 index 00000000..0326ed72 --- /dev/null +++ b/pyrogram/client/methods/messages/edit_inline_reply_markup.py @@ -0,0 +1,50 @@ +# 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 . + +import pyrogram +from pyrogram.api import functions +from pyrogram.client.ext import BaseClient, utils + + +class EditInlineReplyMarkup(BaseClient): + def edit_inline_reply_markup( + self, + inline_message_id: str, + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> bool: + """Edit only the reply markup of **inline** messages sent via the bot (for inline bots). + + Parameters: + inline_message_id (``str``): + Identifier of the inline message. + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + return self.send( + functions.messages.EditInlineBotMessage( + id=utils.unpack_inline_message_id(inline_message_id), + reply_markup=reply_markup.write() if reply_markup else None, + ) + ) diff --git a/pyrogram/client/methods/messages/edit_inline_text.py b/pyrogram/client/methods/messages/edit_inline_text.py new file mode 100644 index 00000000..927fd80f --- /dev/null +++ b/pyrogram/client/methods/messages/edit_inline_text.py @@ -0,0 +1,67 @@ +# 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 . + +import pyrogram +from pyrogram.api import functions +from pyrogram.client.ext import BaseClient, utils + + +class EditInlineText(BaseClient): + def edit_inline_text( + self, + inline_message_id: str, + text: str, + parse_mode: str = "", + disable_web_page_preview: bool = None, + reply_markup: "pyrogram.InlineKeyboardMarkup" = None + ) -> bool: + """Edit the text of **inline** messages. + + Parameters: + inline_message_id (``str``): + Identifier of the inline message. + + text (``str``): + New text of the message. + + parse_mode (``str``, *optional*): + Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline + URLs in your message. Defaults to "markdown". + + disable_web_page_preview (``bool``, *optional*): + Disables link previews for links in this message. + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + ``bool``: On success, True is returned. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + style = self.html if parse_mode.lower() == "html" else self.markdown + + return self.send( + functions.messages.EditInlineBotMessage( + id=utils.unpack_inline_message_id(inline_message_id), + no_webpage=disable_web_page_preview or None, + reply_markup=reply_markup.write() if reply_markup else None, + **style.parse(text) + ) + ) diff --git a/pyrogram/client/methods/messages/edit_message_caption.py b/pyrogram/client/methods/messages/edit_message_caption.py index e9866573..52c22726 100644 --- a/pyrogram/client/methods/messages/edit_message_caption.py +++ b/pyrogram/client/methods/messages/edit_message_caption.py @@ -25,32 +25,25 @@ from pyrogram.client.ext import BaseClient class EditMessageCaption(BaseClient): def edit_message_caption( self, + chat_id: Union[int, str], + message_id: int, caption: str, - chat_id: Union[int, str] = None, - message_id: int = None, - inline_message_id: str = None, parse_mode: str = "", reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": - """Edit caption of media messages. + """Edit the caption of media messages. Parameters: - caption (``str``): - New caption of the media message. - - chat_id (``int`` | ``str``, *optional*): - Required if *inline_message_id* is not specified. + chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``, *optional*): - Required if *inline_message_id* is not specified. + message_id (``int``): Message identifier in the chat specified in chat_id. - inline_message_id (``str``, *optional*): - Required if *chat_id* and *message_id* are not specified. - Identifier of the inline message. + caption (``str``): + New caption of the media message. parse_mode (``str``, *optional*): Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline @@ -60,17 +53,15 @@ class EditMessageCaption(BaseClient): An InlineKeyboardMarkup object. Returns: - :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is - returned, otherwise True is returned (message sent via the bot, as inline query result). + :obj:`Message`: On success, the edited message is returned. Raises: RPCError: In case of a Telegram RPC error. """ return self.edit_message_text( - text=caption, chat_id=chat_id, message_id=message_id, - inline_message_id=inline_message_id, + text=caption, parse_mode=parse_mode, reply_markup=reply_markup ) diff --git a/pyrogram/client/methods/messages/edit_message_media.py b/pyrogram/client/methods/messages/edit_message_media.py index d74e2b56..b65804fd 100644 --- a/pyrogram/client/methods/messages/edit_message_media.py +++ b/pyrogram/client/methods/messages/edit_message_media.py @@ -32,42 +32,33 @@ from pyrogram.client.types.input_media import InputMedia class EditMessageMedia(BaseClient): def edit_message_media( self, + chat_id: Union[int, str], + message_id: int, media: InputMedia, - chat_id: Union[int, str] = None, - message_id: int = None, - inline_message_id: str = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": """Edit animation, audio, document, photo or video messages. - If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, - message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. - Use previously uploaded file via its file_id or specify a URL. + If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, the + message type can be changed arbitrarily. Parameters: - media (:obj:`InputMedia`): - One of the InputMedia objects describing an animation, audio, document, photo or video. - - chat_id (``int`` | ``str``, *optional*): - Required if *inline_message_id* is not specified. + chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``, *optional*): - Required if *inline_message_id* is not specified. + message_id (``int``): Message identifier in the chat specified in chat_id. - inline_message_id (``str``, *optional*): - Required if *chat_id* and *message_id* are not specified. - Identifier of the inline message. + media (:obj:`InputMedia`): + One of the InputMedia objects describing an animation, audio, document, photo or video. reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. Returns: - :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is - returned, otherwise True is returned (message sent via the bot, as inline query result). + :obj:`Message`: On success, the edited message is returned. Raises: RPCError: In case of a Telegram RPC error. @@ -242,16 +233,6 @@ class EditMessageMedia(BaseClient): else: media = utils.get_input_media_from_file_id(media.media, 5) - if inline_message_id is not None: - return self.send( - functions.messages.EditInlineBotMessage( - id=utils.unpack_inline_message_id(inline_message_id), - media=media, - reply_markup=reply_markup.write() if reply_markup else None, - **style.parse(caption) - ) - ) - r = self.send( functions.messages.EditMessage( peer=self.resolve_peer(chat_id), diff --git a/pyrogram/client/methods/messages/edit_message_reply_markup.py b/pyrogram/client/methods/messages/edit_message_reply_markup.py index 516d7b9c..51b77a6a 100644 --- a/pyrogram/client/methods/messages/edit_message_reply_markup.py +++ b/pyrogram/client/methods/messages/edit_message_reply_markup.py @@ -20,52 +20,36 @@ from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.client.ext import BaseClient, utils +from pyrogram.client.ext import BaseClient class EditMessageReplyMarkup(BaseClient): def edit_message_reply_markup( self, + chat_id: Union[int, str], + message_id: int, reply_markup: "pyrogram.InlineKeyboardMarkup" = None, - chat_id: Union[int, str] = None, - message_id: int = None, - inline_message_id: str = None ) -> "pyrogram.Message": - """Edit only the reply markup of messages sent by the bot or via the bot (for inline bots). + """Edit only the reply markup of messages sent by the bot. Parameters: - reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): - An InlineKeyboardMarkup object. - - chat_id (``int`` | ``str``, *optional*): - Required if *inline_message_id* is not specified. + chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``, *optional*): - Required if *inline_message_id* is not specified. + message_id (``int``): Message identifier in the chat specified in chat_id. - inline_message_id (``str``, *optional*): - Required if *chat_id* and *message_id* are not specified. - Identifier of the inline message. + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. Returns: - :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is - returned, otherwise True is returned (message sent via the bot, as inline query result). + :obj:`Message`: On success, the edited message is returned. Raises: RPCError: In case of a Telegram RPC error. """ - if inline_message_id is not None: - return self.send( - functions.messages.EditInlineBotMessage( - id=utils.unpack_inline_message_id(inline_message_id), - reply_markup=reply_markup.write() if reply_markup else None, - ) - ) - r = self.send( functions.messages.EditMessage( peer=self.resolve_peer(chat_id), diff --git a/pyrogram/client/methods/messages/edit_message_text.py b/pyrogram/client/methods/messages/edit_message_text.py index 919e5dc1..7e4345c6 100644 --- a/pyrogram/client/methods/messages/edit_message_text.py +++ b/pyrogram/client/methods/messages/edit_message_text.py @@ -20,39 +20,32 @@ from typing import Union import pyrogram from pyrogram.api import functions, types -from pyrogram.client.ext import BaseClient, utils +from pyrogram.client.ext import BaseClient class EditMessageText(BaseClient): def edit_message_text( self, + chat_id: Union[int, str], + message_id: int, text: str, - chat_id: Union[int, str] = None, - message_id: int = None, - inline_message_id: str = None, parse_mode: str = "", disable_web_page_preview: bool = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> "pyrogram.Message": - """Edit text messages. + """Edit the text of messages. Parameters: - text (``str``): - New text of the message. - - chat_id (``int`` | ``str``, *optional*): - Required if *inline_message_id* is not specified. + chat_id (``int`` | ``str``): Unique identifier (int) or username (str) of the target chat. For your personal cloud (Saved Messages) you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). - message_id (``int``, *optional*): - Required if *inline_message_id* is not specified. + message_id (``int``): Message identifier in the chat specified in chat_id. - inline_message_id (``str``, *optional*): - Required if *chat_id* and *message_id* are not specified. - Identifier of the inline message. + text (``str``): + New text of the message. parse_mode (``str``, *optional*): Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline @@ -65,24 +58,13 @@ class EditMessageText(BaseClient): An InlineKeyboardMarkup object. Returns: - :obj:`Message` | ``bool``: On success, if the edited message was sent by the bot, the edited message is - returned, otherwise True is returned (message sent via the bot, as inline query result). + :obj:`Message`: On success, the edited message is returned. Raises: RPCError: In case of a Telegram RPC error. """ style = self.html if parse_mode.lower() == "html" else self.markdown - if inline_message_id is not None: - return self.send( - functions.messages.EditInlineBotMessage( - id=utils.unpack_inline_message_id(inline_message_id), - no_webpage=disable_web_page_preview or None, - reply_markup=reply_markup.write() if reply_markup else None, - **style.parse(text) - ) - ) - r = self.send( functions.messages.EditMessage( peer=self.resolve_peer(chat_id), From ef8f3bd6e15b2d7da57d20939cf3bba03642edc5 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 14 Jun 2019 04:53:04 +0200 Subject: [PATCH 198/202] Revert: CallbackQuery edit_* bound methods renamed to edit_message_* --- docs/source/api/bound-methods.rst | 18 +-- .../bots_and_keyboards/callback_query.py | 140 ++++++++---------- 2 files changed, 67 insertions(+), 91 deletions(-) diff --git a/docs/source/api/bound-methods.rst b/docs/source/api/bound-methods.rst index 83b3dbbe..e6729da6 100644 --- a/docs/source/api/bound-methods.rst +++ b/docs/source/api/bound-methods.rst @@ -81,13 +81,13 @@ CallbackQuery ^^^^^^^^^^^^^ .. hlist:: - :columns: 3 + :columns: 4 - :meth:`~CallbackQuery.answer` - - :meth:`~CallbackQuery.edit_message_text` - - :meth:`~CallbackQuery.edit_message_caption` - - :meth:`~CallbackQuery.edit_message_media` - - :meth:`~CallbackQuery.edit_message_reply_markup` + - :meth:`~CallbackQuery.edit_text` + - :meth:`~CallbackQuery.edit_caption` + - :meth:`~CallbackQuery.edit_media` + - :meth:`~CallbackQuery.edit_reply_markup` InlineQuery ^^^^^^^^^^^ @@ -141,10 +141,10 @@ Details .. CallbackQuery .. automethod:: CallbackQuery.answer() -.. automethod:: CallbackQuery.edit_message_text() -.. automethod:: CallbackQuery.edit_message_caption() -.. automethod:: CallbackQuery.edit_message_media() -.. automethod:: CallbackQuery.edit_message_reply_markup() +.. automethod:: CallbackQuery.edit_text() +.. automethod:: CallbackQuery.edit_caption() +.. automethod:: CallbackQuery.edit_media() +.. automethod:: CallbackQuery.edit_reply_markup() .. InlineQuery .. automethod:: InlineQuery.answer() diff --git a/pyrogram/client/types/bots_and_keyboards/callback_query.py b/pyrogram/client/types/bots_and_keyboards/callback_query.py index 6872d65b..fcc90e57 100644 --- a/pyrogram/client/types/bots_and_keyboards/callback_query.py +++ b/pyrogram/client/types/bots_and_keyboards/callback_query.py @@ -173,14 +173,16 @@ class CallbackQuery(Object, Update): cache_time=cache_time ) - def edit_message_text( + def edit_text( self, text: str, parse_mode: str = "", disable_web_page_preview: bool = None, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_message_text* of :obj:`CallbackQuery`. + """Edit the text of messages attached to this callback query. + + Bound method *edit_message_text* of :obj:`CallbackQuery`. Parameters: text (``str``): @@ -203,34 +205,33 @@ class CallbackQuery(Object, Update): Raises: RPCError: In case of a Telegram RPC error. """ - chat_id = None - message_id = None - inline_message_id = None + if self.inline_message_id is None: + return self._client.edit_message_text( + chat_id=self.message.chat.id, + message_id=self.message.message_id, + text=text, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup + ) + else: + return self._client.edit_inline_text( + inline_message_id=self.inline_message_id, + text=text, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup + ) - if self.message is not None: - chat_id = self.message.chat.id - message_id = self.message.message_id - - if self.inline_message_id is not None: - inline_message_id = self.inline_message_id - - return self._client.edit_message_text( - text=text, - chat_id=chat_id, - message_id=message_id, - inline_message_id=inline_message_id, - parse_mode=parse_mode, - disable_web_page_preview=disable_web_page_preview, - reply_markup=reply_markup - ) - - def edit_message_caption( + def edit_caption( self, caption: str, parse_mode: str = "", reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_message_caption* of :obj:`CallbackQuery`. + """Edit the caption of media messages attached to this callback query. + + Bound method *edit_message_caption* of :obj:`CallbackQuery`. Parameters: caption (``str``): @@ -250,32 +251,16 @@ class CallbackQuery(Object, Update): Raises: RPCError: In case of a Telegram RPC error. """ - chat_id = None - message_id = None - inline_message_id = None + return self.edit_text(caption, parse_mode, reply_markup) - if self.message is not None: - chat_id = self.message.chat.id - message_id = self.message.message_id - - if self.inline_message_id is not None: - inline_message_id = self.inline_message_id - - return self._client.edit_message_text( - text=caption, - chat_id=chat_id, - message_id=message_id, - inline_message_id=inline_message_id, - parse_mode=parse_mode, - reply_markup=reply_markup - ) - - def edit_message_media( + def edit_media( self, media: "pyrogram.InputMedia", reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_message_media* of :obj:`CallbackQuery`. + """Edit animation, audio, document, photo or video messages attached to this callback query. + + Bound method *edit_message_media* of :obj:`CallbackQuery`. Parameters: media (:obj:`InputMedia`): @@ -291,30 +276,27 @@ class CallbackQuery(Object, Update): Raises: RPCError: In case of a Telegram RPC error. """ - chat_id = None - message_id = None - inline_message_id = None + if self.inline_message_id is None: + return self._client.edit_message_media( + chat_id=self.message.chat.id, + message_id=self.message.message_id, + media=media, + reply_markup=reply_markup + ) + else: + return self._client.edit_inline_media( + inline_message_id=self.inline_message_id, + media=media, + reply_markup=reply_markup + ) - if self.message is not None: - chat_id = self.message.chat.id - message_id = self.message.message_id - - if self.inline_message_id is not None: - inline_message_id = self.inline_message_id - - return self._client.edit_message_media( - media=media, - chat_id=chat_id, - message_id=message_id, - inline_message_id=inline_message_id, - reply_markup=reply_markup - ) - - def edit_message_reply_markup( + def edit_reply_markup( self, reply_markup: "pyrogram.InlineKeyboardMarkup" = None ) -> Union["pyrogram.Message", bool]: - """Bound method *edit_message_reply_markup* of :obj:`CallbackQuery`. + """Edit only the reply markup of messages attached to this callback query. + + Bound method *edit_message_reply_markup* of :obj:`CallbackQuery`. Parameters: reply_markup (:obj:`InlineKeyboardMarkup`): @@ -327,20 +309,14 @@ class CallbackQuery(Object, Update): Raises: RPCError: In case of a Telegram RPC error. """ - chat_id = None - message_id = None - inline_message_id = None - - if self.message is not None: - chat_id = self.message.chat.id - message_id = self.message.message_id - - if self.inline_message_id is not None: - inline_message_id = self.inline_message_id - - return self._client.edit_message_reply_markup( - reply_markup=reply_markup, - chat_id=chat_id, - message_id=message_id, - inline_message_id=inline_message_id - ) + if self.inline_message_id is None: + return self._client.edit_message_reply_markup( + chat_id=self.message.chat.id, + message_id=self.message.message_id, + reply_markup=reply_markup + ) + else: + return self._client.edit_inline_reply_markup( + inline_message_id=self.inline_message_id, + reply_markup=reply_markup + ) From 4492d9d20bc1f841f22cb42c7d9f1eca01d89a80 Mon Sep 17 00:00:00 2001 From: ColinShark Date: Sat, 15 Jun 2019 13:55:50 +0200 Subject: [PATCH 199/202] Put italic in quotes, adapt text_mention (#254) * Put italic in quotes, adapt text_mention * Update message_entity.py --- pyrogram/client/types/messages_and_media/message_entity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/message_entity.py b/pyrogram/client/types/messages_and_media/message_entity.py index 5f3483ee..420bd914 100644 --- a/pyrogram/client/types/messages_and_media/message_entity.py +++ b/pyrogram/client/types/messages_and_media/message_entity.py @@ -31,8 +31,8 @@ class MessageEntity(Object): type (``str``): Type of the entity. Can be "mention" (@username), "hashtag", "cashtag", "bot_command", "url", "email", "phone_number", "bold" - (bold text), italic (italic text), "code" (monowidth string), "pre" (monowidth block), "text_link" - (for clickable text URLs), "text_mention" (for users without usernames). + (bold text), "italic" (italic text), "code" (monowidth string), "pre" (monowidth block), "text_link" + (for clickable text URLs), "text_mention" (for custom text mentions based on users' identifiers). offset (``int``): Offset in UTF-16 code units to the start of the entity. From a1aef9cf251dd3083cfdd2a9eae70b846eeaea78 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 15 Jun 2019 15:57:00 +0200 Subject: [PATCH 200/202] Hint about how to ask good questions --- .github/ISSUE_TEMPLATE/question.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 88d91ecd..05f342bc 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -10,6 +10,6 @@ labels: "question" # Important This place is for issues about Pyrogram, it's **not a forum**. -If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community at https://t.me/pyrogram. +If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community at https://t.me/pyrogram. Useful information on how to ask good questions can be found here: https://stackoverflow.com/help/how-to-ask. -Thanks. \ No newline at end of file +Thanks. From abc0e992cf43ace3b32c6a6e87b90c59d1a89de2 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 15 Jun 2019 17:59:28 +0200 Subject: [PATCH 201/202] Fix Sticker.set_name being treated as tuple/list-like when should in fact be a string Yes, that little comma messed things up (again) --- pyrogram/client/types/messages_and_media/sticker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/types/messages_and_media/sticker.py b/pyrogram/client/types/messages_and_media/sticker.py index 3c171543..78fdda38 100644 --- a/pyrogram/client/types/messages_and_media/sticker.py +++ b/pyrogram/client/types/messages_and_media/sticker.py @@ -94,7 +94,7 @@ class Sticker(Object): self.width = width self.height = height self.emoji = emoji - self.set_name = set_name, + self.set_name = set_name self.thumbs = thumbs # self.mask_position = mask_position From 80d8443be4c11dd44d89184022599891d4f078b4 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 15 Jun 2019 23:02:31 +0200 Subject: [PATCH 202/202] Fix script executions not working outside the current directory Fixes #41 --- pyrogram/client/client.py | 35 +--------------- pyrogram/client/ext/base_client.py | 8 +++- .../client/methods/messages/download_media.py | 42 ++++++++++++++++++- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 1106a416..9001a37e 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -28,7 +28,6 @@ import tempfile import threading import time from configparser import ConfigParser -from datetime import datetime from hashlib import sha256, md5 from importlib import import_module from pathlib import Path @@ -842,39 +841,7 @@ class Client(Methods, BaseClient): final_file_path = "" try: - data, file_name, done, progress, progress_args, path = packet - - directory, file_name = os.path.split(file_name) - directory = directory or "downloads" - - media_type_str = Client.MEDIA_TYPE_ID[data.media_type] - - file_name = file_name or data.file_name - - if not file_name: - guessed_extension = self.guess_extension(data.mime_type) - - if data.media_type in (0, 1, 2, 14): - extension = ".jpg" - elif data.media_type == 3: - extension = guessed_extension or ".ogg" - elif data.media_type in (4, 10, 13): - extension = guessed_extension or ".mp4" - elif data.media_type == 5: - extension = guessed_extension or ".zip" - elif data.media_type == 8: - extension = guessed_extension or ".webp" - elif data.media_type == 9: - extension = guessed_extension or ".mp3" - else: - continue - - file_name = "{}_{}_{}{}".format( - media_type_str, - datetime.fromtimestamp(data.date or time.time()).strftime("%Y-%m-%d_%H-%M-%S"), - self.rnd_id(), - extension - ) + data, directory, file_name, done, progress, progress_args, path = packet temp_file_path = self.get_file( media_type=data.media_type, diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index c8d1beab..def290e6 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -19,6 +19,8 @@ import os import platform import re +import sys +from pathlib import Path from queue import Queue from threading import Lock @@ -45,6 +47,8 @@ class BaseClient: LANG_CODE = "en" + PARENT_DIR = Path(sys.argv[0]).parent + INVITE_LINK_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/joinchat/)([\w-]+)$") BOT_TOKEN_RE = re.compile(r"^\d+:[\w-]+$") DIALOGS_AT_ONCE = 100 @@ -52,8 +56,8 @@ class BaseClient: DOWNLOAD_WORKERS = 1 OFFLINE_SLEEP = 900 WORKERS = 4 - WORKDIR = "." - CONFIG_FILE = "./config.ini" + WORKDIR = PARENT_DIR + CONFIG_FILE = PARENT_DIR / "config.ini" MEDIA_TYPE_ID = { 0: "photo_thumbnail", diff --git a/pyrogram/client/methods/messages/download_media.py b/pyrogram/client/methods/messages/download_media.py index bd8de2d6..143349f7 100644 --- a/pyrogram/client/methods/messages/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -17,7 +17,10 @@ # along with Pyrogram. If not, see . import binascii +import os import struct +import time +from datetime import datetime from threading import Event from typing import Union @@ -25,12 +28,14 @@ import pyrogram from pyrogram.client.ext import BaseClient, FileData, utils from pyrogram.errors import FileIdInvalid +DEFAULT_DOWNLOAD_DIR = "downloads/" + class DownloadMedia(BaseClient): def download_media( self, message: Union["pyrogram.Message", str], - file_name: str = "", + file_name: str = DEFAULT_DOWNLOAD_DIR, block: bool = True, progress: callable = None, progress_args: tuple = () @@ -169,7 +174,40 @@ class DownloadMedia(BaseClient): done = Event() path = [None] - self.download_queue.put((data, file_name, done, progress, progress_args, path)) + directory, file_name = os.path.split(file_name) + file_name = file_name or data.file_name or "" + + if not os.path.isabs(file_name): + directory = self.PARENT_DIR / (directory or DEFAULT_DOWNLOAD_DIR) + + media_type_str = self.MEDIA_TYPE_ID[data.media_type] + + if not file_name: + guessed_extension = self.guess_extension(data.mime_type) + + if data.media_type in (0, 1, 2, 14): + extension = ".jpg" + elif data.media_type == 3: + extension = guessed_extension or ".ogg" + elif data.media_type in (4, 10, 13): + extension = guessed_extension or ".mp4" + elif data.media_type == 5: + extension = guessed_extension or ".zip" + elif data.media_type == 8: + extension = guessed_extension or ".webp" + elif data.media_type == 9: + extension = guessed_extension or ".mp3" + else: + extension = ".unknown" + + file_name = "{}_{}_{}{}".format( + media_type_str, + datetime.fromtimestamp(data.date or time.time()).strftime("%Y-%m-%d_%H-%M-%S"), + self.rnd_id(), + extension + ) + + self.download_queue.put((data, directory, file_name, done, progress, progress_args, path)) if block: done.wait()