From 6ec6d68ee63d98fea5eea5de740793e4de3f6307 Mon Sep 17 00:00:00 2001 From: KurimuzonAkuma Date: Sat, 1 Jun 2024 21:14:36 +0300 Subject: [PATCH] Add entities to send_poll --- pyrogram/methods/messages/send_poll.py | 104 ++++++++++++------- pyrogram/types/messages_and_media/message.py | 32 +++++- pyrogram/types/messages_and_media/poll.py | 35 ++++++- 3 files changed, 130 insertions(+), 41 deletions(-) diff --git a/pyrogram/methods/messages/send_poll.py b/pyrogram/methods/messages/send_poll.py index bccf488c..05d5cb32 100644 --- a/pyrogram/methods/messages/send_poll.py +++ b/pyrogram/methods/messages/send_poll.py @@ -32,30 +32,36 @@ class SendPoll: options: List[str], is_anonymous: bool = True, type: "enums.PollType" = enums.PollType.REGULAR, - allows_multiple_answers: bool = None, - correct_option_id: int = None, - explanation: str = None, - explanation_entities: List["types.MessageEntity"] = None, - open_period: int = None, - close_date: datetime = None, - is_closed: bool = None, - disable_notification: bool = None, - protect_content: bool = None, - message_thread_id: int = None, - effect_id: int = None, - reply_to_message_id: int = None, - reply_to_chat_id: Union[int, str] = None, - parse_mode: Optional["enums.ParseMode"] = None, - quote_text: str = None, - quote_entities: List["types.MessageEntity"] = None, - quote_offset: int = None, - schedule_date: datetime = None, - business_connection_id: str = None, - reply_markup: Union[ - "types.InlineKeyboardMarkup", - "types.ReplyKeyboardMarkup", - "types.ReplyKeyboardRemove", - "types.ForceReply" + allows_multiple_answers: Optional[bool] = None, + correct_option_id: Optional[int] = None, + question_parse_mode: Optional["enums.ParseMode"] = None, + question_entities: Optional[List["types.MessageEntity"]] = None, + explanation: Optional[str] = None, + explanation_parse_mode: Optional["enums.ParseMode"] = None, + explanation_entities: Optional[List["types.MessageEntity"]] = None, + open_period: Optional[int] = None, + close_date: Optional[datetime] = None, + is_closed: Optional[bool] = None, + disable_notification: Optional[bool] = None, + protect_content: Optional[bool] = None, + message_thread_id: Optional[int] = None, + effect_id: Optional[int] = None, + reply_to_message_id: Optional[int] = None, + reply_to_chat_id: Optional[Union[int, str]] = None, + quote_text: Optional[str] = None, + quote_parse_mode: Optional["enums.ParseMode"] = None, + quote_entities: Optional[List["types.MessageEntity"]] = None, + quote_offset: Optional[int] = None, + schedule_date: Optional[datetime] = None, + business_connection_id: Optional[str] = None, + options_parse_mode: Optional["enums.ParseMode"] = None, + reply_markup: Optional[ + Union[ + "types.InlineKeyboardMarkup", + "types.ReplyKeyboardMarkup", + "types.ReplyKeyboardRemove", + "types.ForceReply" + ] ] = None ) -> "types.Message": """Send a new poll. @@ -89,10 +95,22 @@ class SendPoll: correct_option_id (``int``, *optional*): 0-based identifier of the correct answer option, required for polls in quiz mode. + question_parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + + question_entities (List of :obj:`~pyrogram.types.MessageEntity`): + List of special entities that appear in the poll question, which can be specified instead of + *parse_mode*. + explanation (``str``, *optional*): Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing. + explanation_parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + explanation_entities (List of :obj:`~pyrogram.types.MessageEntity`): List of special entities that appear in the poll explanation, which can be specified instead of *parse_mode*. @@ -134,7 +152,7 @@ class SendPoll: quote_text (``str``, *optional*): Text of the quote to be sent. - parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + quote_parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together. @@ -150,6 +168,10 @@ class SendPoll: business_connection_id (``str``, *optional*): Unique identifier of the business connection on behalf of which the message will be sent. + options_parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.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. @@ -162,14 +184,32 @@ class SendPoll: await app.send_poll(chat_id, "Is this a poll question?", ["Yes", "No", "Maybe"]) """ + question, question_entities = (await utils.parse_text_entities( + self, question, question_parse_mode, question_entities + )).values() + solution, solution_entities = (await utils.parse_text_entities( - self, explanation, parse_mode, explanation_entities + self, explanation, explanation_parse_mode, explanation_entities )).values() quote_text, quote_entities = (await utils.parse_text_entities( - self, quote_text, parse_mode, quote_entities + self, quote_text, quote_parse_mode, quote_entities )).values() + answers = [] + + for i, opt in enumerate(options): + option, option_entities = (await utils.parse_text_entities( + self, opt, options_parse_mode, None + )).values() + + answers.append( + raw.types.PollAnswer( + text=raw.types.TextWithEntities(text=option, entities=option_entities or []), + option=bytes([i]), + ) + ) + r = await self.invoke( raw.functions.messages.SendMedia( peer=await self.resolve_peer(chat_id), @@ -178,15 +218,9 @@ class SendPoll: id=self.rnd_id(), question=raw.types.TextWithEntities( text=question, - entities=[] + entities=question_entities or [] ), - answers=[ - raw.types.PollAnswer( - text=raw.types.TextWithEntities(text=text, entities=[]), - option=bytes([i]), - ) - for i, text in enumerate(options) - ], + answers=answers, closed=is_closed, public_voters=not is_anonymous, multiple_choice=allows_multiple_answers, diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index 0332d699..b86a96ba 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -2758,6 +2758,8 @@ class Message(Object, Update): type: "enums.PollType" = enums.PollType.REGULAR, allows_multiple_answers: bool = None, correct_option_id: int = None, + question_parse_mode: Optional["enums.ParseMode"] = None, + question_entities: Optional[List["types.MessageEntity"]] = None, explanation: str = None, explanation_parse_mode: "enums.ParseMode" = None, explanation_entities: List["types.MessageEntity"] = None, @@ -2771,10 +2773,12 @@ class Message(Object, Update): effect_id: int = None, reply_to_message_id: int = None, quote_text: str = None, - parse_mode: Optional["enums.ParseMode"] = None, + quote_parse_mode: Optional["enums.ParseMode"] = None, quote_entities: List["types.MessageEntity"] = None, + quote_offset: Optional[int] = None, schedule_date: datetime = None, business_connection_id: str = None, + options_parse_mode: List["types.MessageEntity"] = None, reply_markup: Union[ "types.InlineKeyboardMarkup", "types.ReplyKeyboardMarkup", @@ -2821,6 +2825,14 @@ class Message(Object, Update): correct_option_id (``int``, *optional*): 0-based identifier of the correct answer option, required for polls in quiz mode. + question_parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + + question_entities (List of :obj:`~pyrogram.types.MessageEntity`): + List of special entities that appear in the poll question, which can be specified instead of + *parse_mode*. + explanation (``str``, *optional*): Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing. @@ -2872,16 +2884,26 @@ class Message(Object, Update): quote_text (``str``): Text of the quote to be sent. - parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + quote_parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together. quote_entities (List of :obj:`~pyrogram.types.MessageEntity`): List of special entities that appear in quote text, which can be specified instead of *parse_mode*. + quote_offset (``int``, *optional*): + Offset for quote in original message. + schedule_date (:py:obj:`~datetime.datetime`, *optional*): Date when the message will be automatically sent. + business_connection_id (``str``, *optional*): + Unique identifier of the business connection on behalf of which the message will be sent. + + options_parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.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. @@ -2912,6 +2934,8 @@ class Message(Object, Update): type=type, allows_multiple_answers=allows_multiple_answers, correct_option_id=correct_option_id, + question_parse_mode=question_parse_mode, + question_entities=question_entities, explanation=explanation, explanation_parse_mode=explanation_parse_mode, explanation_entities=explanation_entities, @@ -2924,10 +2948,12 @@ class Message(Object, Update): effect_id=effect_id, reply_to_message_id=reply_to_message_id, quote_text=quote_text, - parse_mode=parse_mode, + quote_parse_mode=quote_parse_mode, quote_entities=quote_entities, + quote_offset=quote_offset, schedule_date=schedule_date, business_connection_id=business_connection_id, + options_parse_mode=options_parse_mode, reply_markup=reply_markup ) diff --git a/pyrogram/types/messages_and_media/poll.py b/pyrogram/types/messages_and_media/poll.py index d7f24b0a..b204ac5d 100644 --- a/pyrogram/types/messages_and_media/poll.py +++ b/pyrogram/types/messages_and_media/poll.py @@ -20,12 +20,12 @@ from datetime import datetime from typing import List, Union, Optional import pyrogram +from pyrogram.types.messages_and_media.message import Str from pyrogram import raw, enums, utils from pyrogram import types from ..object import Object from ..update import Update - class Poll(Object, Update): """A Poll. @@ -62,6 +62,9 @@ class Poll(Object, Update): Available only for polls in the quiz mode, which are closed, or was sent (not forwarded) by the bot or to the private chat with the bot. + question_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*): + Special entities like usernames, URLs, bot commands, etc. that appear in the question. + explanation (``str``, *optional*): Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters. @@ -90,6 +93,7 @@ class Poll(Object, Update): allows_multiple_answers: bool = None, chosen_option_id: Optional[int] = None, correct_option_id: Optional[int] = None, + question_entities: Optional[List["types.MessageEntity"]] = None, explanation: Optional[str] = None, explanation_entities: Optional[List["types.MessageEntity"]] = None, open_period: Optional[int] = None, @@ -107,6 +111,7 @@ class Poll(Object, Update): self.allows_multiple_answers = allows_multiple_answers self.chosen_option_id = chosen_option_id self.correct_option_id = correct_option_id + self.question_entities = question_entities self.explanation = explanation self.explanation_entities = explanation_entities self.open_period = open_period @@ -137,7 +142,17 @@ class Poll(Object, Update): options.append( types.PollOption( - text=answer.text.text, + text=Str(answer.text.text).init( + types.List( + filter( + lambda x: x is not None, + [ + types.MessageEntity._parse(client, entity, {}) + for entity in (answer.text.entities or []) + ] + ) + ) + ), voter_count=voter_count, data=answer.option, client=client @@ -146,7 +161,17 @@ class Poll(Object, Update): return Poll( id=str(poll.id), - question=poll.question.text, + question=Str(poll.question.text).init( + types.List( + filter( + lambda x: x is not None, + [ + types.MessageEntity._parse(client, entity, {}) + for entity in (poll.question.entities or []) + ] + ) + ) + ), options=options, total_voter_count=media_poll.results.total_voters, is_closed=poll.closed, @@ -155,6 +180,10 @@ class Poll(Object, Update): allows_multiple_answers=poll.multiple_choice, chosen_option_id=chosen_option_id, correct_option_id=correct_option_id, + question_entities=[ + types.MessageEntity._parse(client, i, {}) + for i in poll.question.entities + ] if poll.question.entities else None, explanation=poll_results.solution, explanation_entities=[ types.MessageEntity._parse(client, i, {})