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 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/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_animation.py b/pyrogram/client/methods/messages/send_animation.py index 2ef67a4e..e2335f72 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 ee9cd305..2f01396f 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 a71c79e6..596adeb1 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_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/send_video.py b/pyrogram/client/methods/messages/send_video.py index 0faf8e38..045c1cca 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 b2547d04..464f2711 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/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/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 727b6330..9234cb42 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*): @@ -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). @@ -267,7 +270,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 +289,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 +351,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 +490,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 +504,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 +610,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, @@ -795,7 +798,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 +933,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 +1260,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 +2067,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 +2192,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*): diff --git a/pyrogram/client/types/messages_and_media/poll.py b/pyrogram/client/types/messages_and_media/poll.py index 68667334..acaf8697 100644 --- a/pyrogram/client/types/messages_and_media/poll.py +++ b/pyrogram/client/types/messages_and_media/poll.py @@ -22,85 +22,88 @@ 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: - id (``int``): - The poll id in this chat. - - closed (``bool``): - Whether the poll is closed or not. + id (``str``): + 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, + id: str, 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, + id=str(poll.id), 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: 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 diff --git a/pyrogram/client/types/user_and_chats/chat_member.py b/pyrogram/client/types/user_and_chats/chat_member.py index 35911210..046d2ebc 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 @@ -123,12 +128,9 @@ class ChatMember(PyrogramType): if isinstance(member, types.ChannelParticipantBanned): return ChatMember( user=user, - status=( - "kicked" if member.banned_rights.view_messages - else "left" if member.left - else "restricted" - ), + status="kicked" if member.banned_rights.view_messages else "restricted", date=member.date, + is_member=not member.left, restricted_by=pyrogram.User._parse(client, users[member.kicked_by]), permissions=pyrogram.ChatPermissions._parse(member), client=client