From 1482f591e91734d83784764d5413671c7e4273b1 Mon Sep 17 00:00:00 2001 From: wulan17 Date: Wed, 31 Jul 2024 12:24:35 +0700 Subject: [PATCH] pyrofork: Refactor request_chat/channel/user Signed-off-by: wulan17 --- compiler/docs/compiler.py | 3 + pyrogram/enums/message_service_type.py | 7 +- pyrogram/types/bots_and_keyboards/__init__.py | 6 ++ .../bots_and_keyboards/keyboard_button.py | 42 +++++++--- .../request_peer_type_channel.py | 29 ++++++- .../request_peer_type_chat.py | 29 ++++++- .../request_peer_type_user.py | 29 ++++++- .../bots_and_keyboards/requested_chat.py | 82 ++++++++++++++++++ .../bots_and_keyboards/requested_chats.py | 77 +++++++++++++++++ .../bots_and_keyboards/requested_user.py | 84 +++++++++++++++++++ pyrogram/types/messages_and_media/message.py | 33 ++------ 11 files changed, 376 insertions(+), 45 deletions(-) create mode 100644 pyrogram/types/bots_and_keyboards/requested_chat.py create mode 100644 pyrogram/types/bots_and_keyboards/requested_chats.py create mode 100644 pyrogram/types/bots_and_keyboards/requested_user.py diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index 251c7593c..1730e6934 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -573,6 +573,9 @@ def get_title_list(s: str) -> list: RequestPeerTypeChannel RequestPeerTypeChat RequestPeerTypeUser + RequestedChats + RequestedChat + RequestedUser LoginUrl ForceReply CallbackQuery diff --git a/pyrogram/enums/message_service_type.py b/pyrogram/enums/message_service_type.py index 5c7b9942a..2ed3e5645 100644 --- a/pyrogram/enums/message_service_type.py +++ b/pyrogram/enums/message_service_type.py @@ -61,11 +61,8 @@ class MessageServiceType(AutoName): GAME_HIGH_SCORE = auto() "Game high score" - ChannelShared = auto() - "a shared chat/channel" - - UserShared = auto() - "a shared user" + ChatShared = auto() + "a shared chat/channel/user" FORUM_TOPIC_CREATED = auto() "a new forum topic created in the chat" diff --git a/pyrogram/types/bots_and_keyboards/__init__.py b/pyrogram/types/bots_and_keyboards/__init__.py index 5286ba285..dffa9fc28 100644 --- a/pyrogram/types/bots_and_keyboards/__init__.py +++ b/pyrogram/types/bots_and_keyboards/__init__.py @@ -52,6 +52,9 @@ from .request_peer_type_channel import RequestPeerTypeChannel from .request_peer_type_chat import RequestPeerTypeChat from .request_peer_type_user import RequestPeerTypeUser +from .requested_chat import RequestedChat +from .requested_chats import RequestedChats +from .requested_user import RequestedUser from .sent_web_app_message import SentWebAppMessage from .shipping_address import ShippingAddress from .shipping_option import ShippingOption @@ -77,6 +80,9 @@ "RequestPeerTypeChannel", "RequestPeerTypeChat", "RequestPeerTypeUser", + "RequestedChats", + "RequestedChat", + "RequestedUser", "LoginUrl", "BotCommand", "BotCommandScope", diff --git a/pyrogram/types/bots_and_keyboards/keyboard_button.py b/pyrogram/types/bots_and_keyboards/keyboard_button.py index 097c01f2d..db533f707 100644 --- a/pyrogram/types/bots_and_keyboards/keyboard_button.py +++ b/pyrogram/types/bots_and_keyboards/keyboard_button.py @@ -104,7 +104,10 @@ def read(b): request_chat=types.RequestPeerTypeChannel( is_creator=b.peer_type.creator, is_username=b.peer_type.has_username, - max=b.max_quantity + max=b.max_quantity, + is_name_requested=b.name_requested, + is_username_requested=b.username_requested, + is_photo_requested=b.photo_requested ) ) if isinstance(b.peer_type, raw.types.RequestPeerTypeChat): @@ -115,7 +118,10 @@ def read(b): is_bot_participant=b.peer_type.bot_participant, is_username=b.peer_type.has_username, is_forum=b.peer_type.forum, - max=b.max_quantity + max=b.max_quantity, + is_name_requested=b.name_requested, + is_username_requested=b.username_requested, + is_photo_requested=b.photo_requested ) ) @@ -125,7 +131,10 @@ def read(b): request_user=types.RequestPeerTypeUser( is_bot=b.peer_type.bot, is_premium=b.peer_type.premium, - max=b.max_quantity + max=b.max_quantity, + is_name_requested=b.name_requested, + is_username_requested=b.username_requested, + is_photo_requested=b.photo_requested ) ) @@ -136,35 +145,44 @@ def write(self): return raw.types.KeyboardButtonRequestGeoLocation(text=self.text) elif self.request_chat: if isinstance(self.request_chat, types.RequestPeerTypeChannel): - return raw.types.KeyboardButtonRequestPeer( + return raw.types.InputKeyboardButtonRequestPeer( text=self.text, - button_id=0, + button_id=self.request_chat.button_id, peer_type=raw.types.RequestPeerTypeBroadcast( creator=self.request_chat.is_creator, has_username=self.request_chat.is_username ), - max_quantity=self.request_chat.max + max_quantity=self.request_chat.max, + name_requested=self.request_chat.is_name_requested, + username_requested=self.request_chat.is_username_requested, + photo_requested=self.request_chat.is_photo_requested ) - return raw.types.KeyboardButtonRequestPeer( + return raw.types.InputKeyboardButtonRequestPeer( text=self.text, - button_id=0, + button_id=self.request_chat.button_id, peer_type=raw.types.RequestPeerTypeChat( creator=self.request_chat.is_creator, bot_participant=self.request_chat.is_bot_participant, has_username=self.request_chat.is_username, forum=self.request_chat.is_forum ), - max_quantity=self.request_chat.max + max_quantity=self.request_chat.max, + name_requested=self.request_chat.is_name_requested, + username_requested=self.request_chat.is_username_requested, + photo_requested=self.request_chat.is_photo_requested ) elif self.request_user: - return raw.types.KeyboardButtonRequestPeer( + return raw.types.InputKeyboardButtonRequestPeer( text=self.text, - button_id=0, + button_id=self.request_user.button_id, peer_type=raw.types.RequestPeerTypeUser( bot=self.request_user.is_bot, premium=self.request_user.is_premium ), - max_quantity=self.request_user.max + max_quantity=self.request_user.max, + name_requested=self.request_user.is_name_requested, + username_requested=self.request_user.is_username_requested, + photo_requested=self.request_user.is_photo_requested ) elif self.web_app: return raw.types.KeyboardButtonSimpleWebView(text=self.text, url=self.web_app.url) diff --git a/pyrogram/types/bots_and_keyboards/request_peer_type_channel.py b/pyrogram/types/bots_and_keyboards/request_peer_type_channel.py index 87a4dd45e..c7283ee79 100644 --- a/pyrogram/types/bots_and_keyboards/request_peer_type_channel.py +++ b/pyrogram/types/bots_and_keyboards/request_peer_type_channel.py @@ -23,21 +23,48 @@ class RequestPeerTypeChannel(Object): """Object used to request clients to send a channel identifier. Parameters: + button_id (``int``, *optional*): + Button identifier. + is_creator (``bool``, *optional*): If True, show only Channel which user is the owner. is_username (``bool``, *optional*): If True, show only Channel which has username. + + max (``int``, *optional*): + Maximum number of channels to be returned. + default 1. + + is_name_requested (``bool``, *optional*): + If True, Channel name is requested. + default True. + + is_username_requested (``bool``, *optional*): + If True, Channel username is requested. + default True. + + is_photo_requested (``bool``, *optional*): + If True, Channel photo is requested. + default True. """ # TODO user_admin_rights, bot_admin_rights def __init__( self, + button_id: int=0, is_creator: bool=None, is_username: bool=None, - max: int=1 + max: int=1, + is_name_requested: bool=True, + is_username_requested: bool=True, + is_photo_requested: bool=True ): super().__init__() + self.button_id = button_id self.is_creator = is_creator self.is_username = is_username self.max = max + self.is_name_requested = is_name_requested + self.is_username_requested = is_username_requested + self.is_photo_requested = is_photo_requested diff --git a/pyrogram/types/bots_and_keyboards/request_peer_type_chat.py b/pyrogram/types/bots_and_keyboards/request_peer_type_chat.py index 7249a9dc3..59d873007 100644 --- a/pyrogram/types/bots_and_keyboards/request_peer_type_chat.py +++ b/pyrogram/types/bots_and_keyboards/request_peer_type_chat.py @@ -23,6 +23,9 @@ class RequestPeerTypeChat(Object): """Object used to request clients to send a chat identifier. Parameters: + button_id (``int``, *optional*): + Button identifier. + is_creator (``bool``, *optional*): If True, show only Chat which user is the owner. @@ -34,20 +37,44 @@ class RequestPeerTypeChat(Object): is_forum (``bool``, *optional*): If True, show only Chat which is a forum. + + max (``int``, *optional*): + Maximum number of chats to be returned. + default 1. + + is_name_requested (``bool``, *optional*): + If True, Chat name is requested. + default True. + + is_username_requested (``bool``, *optional*): + If True, Chat username is requested. + default True. + + is_photo_requested (``bool``, *optional*): + If True, Chat photo is requested. + default True. """ # TODO user_admin_rights, bot_admin_rights def __init__( self, + button_id: int=0, is_creator: bool=None, is_bot_participant: bool=None, is_username: bool=None, is_forum: bool=None, - max: int=1 + max: int=1, + is_name_requested: bool=True, + is_username_requested: bool=True, + is_photo_requested: bool=True ): super().__init__() + self.button_id = button_id self.is_creator = is_creator self.is_bot_participant = is_bot_participant self.is_username = is_username self.is_forum = is_forum self.max = max + self.is_name_requested = is_name_requested + self.is_username_requested = is_username_requested + self.is_photo_requested = is_photo_requested diff --git a/pyrogram/types/bots_and_keyboards/request_peer_type_user.py b/pyrogram/types/bots_and_keyboards/request_peer_type_user.py index f11d35005..ef49d406e 100644 --- a/pyrogram/types/bots_and_keyboards/request_peer_type_user.py +++ b/pyrogram/types/bots_and_keyboards/request_peer_type_user.py @@ -23,21 +23,48 @@ class RequestPeerTypeUser(Object): """Object used to request clients to send a user identifier. Parameters: + button_id (``int``, *optional*): + Button identifier. + is_bot (``bool``, *optional*): If True, show only Bots. is_premium (``bool``, *optional*): If True, show only Premium Users. + + max (``int``, *optional*): + Maximum number of users to be returned. + default 1. + + is_name_requested (``bool``, *optional*): + If True, User name is requested. + default True. + + is_username_requested (``bool``, *optional*): + If True, User username is requested. + default True. + + is_photo_requested (``bool``, *optional*): + If True, User photo is requested. + default True. """ def __init__( self, + button_id: int=0, is_bot: bool=None, is_premium: bool=None, - max: int=1 + max: int=1, + is_name_requested: bool=True, + is_username_requested: bool=True, + is_photo_requested: bool=True ): super().__init__() + self.button_id = button_id self.is_bot = is_bot self.is_premium = is_premium self.max = max + self.is_name_requested = is_name_requested + self.is_username_requested = is_username_requested + self.is_photo_requested = is_photo_requested diff --git a/pyrogram/types/bots_and_keyboards/requested_chat.py b/pyrogram/types/bots_and_keyboards/requested_chat.py new file mode 100644 index 000000000..6ccefe876 --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/requested_chat.py @@ -0,0 +1,82 @@ +# Pyrofork - Telegram MTProto API Client Library for Python +# Copyright (C) 2022-present Mayuri-Chan +# +# This file is part of Pyrofork. +# +# Pyrofork 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. +# +# Pyrofork 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 Pyrofork. If not, see . + +from ..object import Object +from pyrogram import enums, raw, types, utils +from typing import Union + +class RequestedChat(Object): + """Contains information about a requested chat. + + Parameters: + chat_id (``int``): + Identifier of the chat. + + chat_type (``enums.ChatType``): + Type of the chat. + + name (``str``, *optional*): + Name of the chat. + + username (``str``, *optional*): + Username of the chat. + + photo (``types.ChatPhoto``, *optional*): + Chat photo. + """ + def __init__( + self, + chat_id: int, + chat_type: enums.ChatType, + name: str = None, + username: str = None, + photo: "types.ChatPhoto" = None, + ): + super().__init__() + + self.chat_id = chat_id + self.chat_type = chat_type + self.name = name + self.username = username + self.photo = photo + + @staticmethod + async def _parse( + client, + request: Union[ + "raw.types.RequestedPeerChat", + "raw.types.RequestedPeerChannel", + "raw.types.PeerChat", + "raw.types.PeerChannel" + ] + ) -> "RequestedChat": + if isinstance(request, raw.types.RequestedPeerChannel) or isinstance(request, raw.types.PeerChannel): + type = enums.ChatType.CHANNEL + else: + type = enums.ChatType.GROUP + photo = None + if getattr(request,"photo", None): + photo = types.Photo._parse(client, getattr(request,"photo", None), 0) + + return RequestedChat( + chat_id=utils.get_channel_id(utils.get_raw_peer_id(request)), + chat_type=type, + name=getattr(request, "title", None), + username=getattr(request, "username", None), + photo=photo, + ) diff --git a/pyrogram/types/bots_and_keyboards/requested_chats.py b/pyrogram/types/bots_and_keyboards/requested_chats.py new file mode 100644 index 000000000..b3ca39d69 --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/requested_chats.py @@ -0,0 +1,77 @@ +# Pyrofork - Telegram MTProto API Client Library for Python +# Copyright (C) 2022-present Mayuri-Chan +# +# This file is part of Pyrofork. +# +# Pyrofork 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. +# +# Pyrofork 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 Pyrofork. If not, see . + +from ..object import Object +from pyrogram import enums, raw, types +from typing import Union + +class RequestedChats(Object): + """Contains information about a requested chats. + + Parameters: + button_id (``int``): + Button identifier. + + chats (List of :obj:`~pyrogram.types.RequestedChat`, *optional*): + List of chats. + + users (List of :obj:`~pyrogram.types.RequestedUser` *optional*): + List of users. + """ + def __init__( + self, + button_id: int, + chats: list["types.RequestedChat"] = None, + users: list["types.RequestedUser"] = None + ): + super().__init__() + + self.button_id = button_id + self.chats = chats + self.users = users + + @staticmethod + async def _parse( + client, + request: Union[ + "raw.types.MessageActionRequestedPeer", + "raw.types.MessageActionRequestedPeerSentMe" + ] + ) -> "RequestedChats": + button_id = request.button_id + chats = [] + users = [] + for chat in request.peers: + if ( + isinstance(chat, raw.types.RequestedPeerChat) + or isinstance(chat, raw.types.RequestedPeerChannel) + or isinstance(chat, raw.types.PeerChat) + or isinstance(chat, raw.types.PeerChannel) + ): + chats.append(await types.RequestedChat._parse(client, chat)) + elif ( + isinstance(chat, raw.types.RequestedPeerUser) + or isinstance(chat, raw.types.PeerUser) + ): + users.append(await types.RequestedUser._parse(client, chat)) + + return RequestedChats( + button_id, + chats if len(chats) > 0 else None, + users if len(users) > 0 else None + ) diff --git a/pyrogram/types/bots_and_keyboards/requested_user.py b/pyrogram/types/bots_and_keyboards/requested_user.py new file mode 100644 index 000000000..6b4eb5d8e --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/requested_user.py @@ -0,0 +1,84 @@ +# Pyrofork - Telegram MTProto API Client Library for Python +# Copyright (C) 2022-present Mayuri-Chan +# +# This file is part of Pyrofork. +# +# Pyrofork 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. +# +# Pyrofork 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 Pyrofork. If not, see . + +from ..object import Object +from pyrogram import enums, raw, types +from typing import Union + +class RequestedUser(Object): + """Contains information about a requested user. + + Parameters: + user_id (``int``): + Identifier of the user. + + first_name (``str``, *optional*): + First name of the user. + + last_name (``str``, *optional*): + Last name of the user. + + username (``str``, *optional*): + Username of the user. + + photo (``types.UserProfilePhoto``, *optional*): + User photo. + + full_name (``str``, *optional*): + User's full name. + """ + def __init__( + self, + user_id: int, + first_name: str = None, + last_name: str = None, + username: str = None, + photo: "types.ChatPhoto" = None, + ): + super().__init__() + + self.user_id = user_id + self.first_name = first_name + self.last_name = last_name + self.username = username + self.photo = photo + + @staticmethod + async def _parse( + client, + request: Union[ + "raw.types.RequestedPeerUser", + "raw.types.PeerUser" + ] + ) -> "RequestedUser": + + photo = None + if getattr(request,"photo", None): + photo = types.Photo._parse(client, getattr(request,"photo", None), 0) + + return RequestedUser( + user_id=getattr(request,"user_id", None), + first_name=getattr(request,"first_name", None), + last_name=getattr(request,"last_name", None), + username=getattr(request,"username", None), + photo=photo + ) + + @property + def full_name(self) -> str: + return " ".join(filter(None, [self.first_name, self.last_name])) or None diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index 57a1dce34..4e237c5ee 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -347,11 +347,8 @@ class Message(Object, Update): bot_allowed (:obj:`~pyrogram.types.BotAllowed`, *optional*): Contains information about a allowed bot. - chat_shared (List of ``int``, *optional*): - Service message: chat/channel shared - - user_shared (List of ``int``, *optional*): - Service message: user shared + chats_shared (List of :obj:`~pyrogram.types.RequestedChats`, *optional*): + Service message: chats shared forum_topic_created (:obj:`~pyrogram.types.ForumTopicCreated`, *optional*): Service message: forum topic created @@ -517,8 +514,7 @@ def __init__( matches: List[Match] = None, command: List[str] = None, bot_allowed: "types.BotAllowed" = None, - chat_shared: List[int] = None, - user_shared: List[int] = None, + chats_shared: List["types.RequestedChats"] = None, forum_topic_created: "types.ForumTopicCreated" = None, forum_topic_closed: "types.ForumTopicClosed" = None, forum_topic_reopened: "types.ForumTopicReopened" = None, @@ -631,8 +627,7 @@ def __init__( self.command = command self.reply_markup = reply_markup self.bot_allowed = bot_allowed - self.chat_shared = chat_shared - self.user_shared = user_shared + self.chats_shared = chats_shared self.forum_topic_created = forum_topic_created self.forum_topic_closed = forum_topic_closed self.forum_topic_reopened = forum_topic_reopened @@ -736,8 +731,7 @@ async def _parse( channel_chat_created = None new_chat_photo = None bot_allowed = None - chat_shared = None - user_shared = None + chats_shared = None is_topic_message = None forum_topic_created = None forum_topic_closed = None @@ -799,18 +793,8 @@ async def _parse( bot_allowed = types.BotAllowed._parse(client, action) service_type = enums.MessageServiceType.BOT_ALLOWED elif isinstance(action, raw.types.MessageActionRequestedPeer) or isinstance(action, raw.types.MessageActionRequestedPeerSentMe): - chat_shared = [] - user_shared = [] - for peer in action.peers: - if isinstance(peer, raw.types.PeerChannel) or isinstance(peer, raw.types.RequestedPeerChannel): - chat_shared.append(utils.get_channel_id(utils.get_raw_peer_id(peer))) - service_type = enums.MessageServiceType.ChannelShared - elif isinstance(peer, raw.types.PeerChat) or isinstance(peer, raw.types.RequestedPeerChat): - chat_shared.append(utils.get_channel_id(utils.get_raw_peer_id(peer))) - service_type = enums.MessageServiceType.ChannelShared - elif isinstance(peer, raw.types.PeerUser) or isinstance(peer, raw.types.RequestedPeerUser): - user_shared.append(peer.user_id) - service_type = enums.MessageServiceType.UserShared + chats_shared = await types.RequestedChats._parse(client, action) + service_type = enums.MessageServiceType.ChatShared elif isinstance(action, raw.types.MessageActionTopicCreate): forum_topic_created = types.ForumTopicCreated._parse(message) service_type = enums.MessageServiceType.FORUM_TOPIC_CREATED @@ -885,8 +869,7 @@ async def _parse( group_chat_created=group_chat_created, bot_allowed=bot_allowed, channel_chat_created=channel_chat_created, - chat_shared=chat_shared if chat_shared is not None and len(chat_shared) > 0 else None, - user_shared=user_shared if user_shared is not None and len(user_shared) > 0 else None, + chats_shared=chats_shared, is_topic_message=is_topic_message, forum_topic_created=forum_topic_created, forum_topic_closed=forum_topic_closed,