From b345bf887691a8a69aa6d766e2852e9a6ccd62df Mon Sep 17 00:00:00 2001 From: wulan17 Date: Fri, 22 Sep 2023 16:17:17 +0700 Subject: [PATCH] Pyrofork: Update some methods and types to layer 164 Signed-off-by: wulan17 --- compiler/docs/compiler.py | 2 +- pyrogram/methods/users/__init__.py | 4 +- pyrogram/methods/users/delete_stories.py | 11 +++- pyrogram/methods/users/edit_story.py | 12 +++- pyrogram/methods/users/export_story_link.py | 12 ++-- pyrogram/methods/users/get_all_stories.py | 7 +-- ...et_user_stories.py => get_peer_stories.py} | 22 +++---- pyrogram/methods/users/get_stories.py | 18 +++--- pyrogram/methods/users/get_stories_history.py | 13 +++- pyrogram/methods/users/send_story.py | 12 +++- pyrogram/types/messages_and_media/story.py | 59 +++++++++++++------ 11 files changed, 115 insertions(+), 57 deletions(-) rename pyrogram/methods/users/{get_user_stories.py => get_peer_stories.py} (77%) diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index de96a04b..406a6a5c 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -276,7 +276,7 @@ def pyrogram_api(): get_all_stories get_stories get_stories_history - get_user_stories + get_peer_stories send_story """, stickers=""" diff --git a/pyrogram/methods/users/__init__.py b/pyrogram/methods/users/__init__.py index 0f1bb167..0bcc8a97 100644 --- a/pyrogram/methods/users/__init__.py +++ b/pyrogram/methods/users/__init__.py @@ -29,7 +29,7 @@ from .get_me import GetMe from .get_all_stories import GetAllStories from .get_stories import GetStories from .get_stories_history import GetUserStoriesHistory -from .get_user_stories import GetUserStories +from .get_peer_stories import GetPeerStories from .get_users import GetUsers from .send_story import SendStory from .set_emoji_status import SetEmojiStatus @@ -53,7 +53,7 @@ class Users( GetAllStories, GetStories, GetUserStoriesHistory, - GetUserStories, + GetPeerStories, SetUsername, GetChatPhotosCount, UnblockUser, diff --git a/pyrogram/methods/users/delete_stories.py b/pyrogram/methods/users/delete_stories.py index aa1681d8..0bbee756 100644 --- a/pyrogram/methods/users/delete_stories.py +++ b/pyrogram/methods/users/delete_stories.py @@ -29,6 +29,7 @@ class DeleteStories: async def delete_stories( self: "pyrogram.Client", story_ids: Union[int, Iterable[int]], + channel_id: int = None ) -> bool: """Delete one or more story by using story identifiers. @@ -39,6 +40,9 @@ class DeleteStories: Pass a single story identifier or an iterable of story ids (as integers) to get the content of the story themselves. + channel_id (``int``, *optional*): + Unique identifier (int) of the target channel. + Returns: `bool`: On success, a True is returned. @@ -54,10 +58,15 @@ class DeleteStories: is_iterable = not isinstance(story_ids, int) ids = list(story_ids) if is_iterable else [story_ids] + + if channel_id: + peer = await self.resolve_peer(channel_id) + else: + peer = await self.resolve_peer("me") try: await self.invoke( - raw.functions.stories.DeleteStories(id=ids) + raw.functions.stories.DeleteStories(peer=peer,id=ids) ) except Exception as e: print(e) diff --git a/pyrogram/methods/users/edit_story.py b/pyrogram/methods/users/edit_story.py index fb9faab2..d810046c 100644 --- a/pyrogram/methods/users/edit_story.py +++ b/pyrogram/methods/users/edit_story.py @@ -31,6 +31,7 @@ class EditStory: async def edit_story( self: "pyrogram.Client", story_id: int, + channel_id: int = None, privacy: "enums.StoriesPrivacy" = None, allowed_users: List[int] = None, denied_users: List[int] = None, @@ -50,6 +51,9 @@ class EditStory: Parameters: story_id (``int``): Unique identifier (int) of the target story. + + channel_id (``int``, *optional*): + Unique identifier (int) of the target channel. animation (``str`` | ``BinaryIO``, *optional*): New story Animation. @@ -113,6 +117,11 @@ class EditStory: # TODO: MediaArea + if channel_id: + peer = await self.resolve_peer(channel_id) + else: + peer = await self.resolve_peer("me") + media = None privacy_rules = None @@ -232,10 +241,11 @@ class EditStory: r = await self.invoke( raw.functions.stories.EditStory( id=story_id, + peer=peer, media=media, privacy_rules=privacy_rules, caption=text, entities=entities ) ) - return await types.Story._parse(self, r.updates[0].story, r.updates[0].user_id) + return await types.Story._parse(self, r.updates[0].story, r.updates[0].peer) diff --git a/pyrogram/methods/users/export_story_link.py b/pyrogram/methods/users/export_story_link.py index c56036d5..bb737baf 100644 --- a/pyrogram/methods/users/export_story_link.py +++ b/pyrogram/methods/users/export_story_link.py @@ -28,7 +28,7 @@ log = logging.getLogger(__name__) class ExportStoryLink: async def export_story_link( self: "pyrogram.Client", - user_id: Union[int, str], + from_id: Union[int, str], story_id: int, ) -> types.ExportedStoryLink: """Get one story link from an user by using story identifiers. @@ -36,8 +36,8 @@ class ExportStoryLink: .. include:: /_includes/usable-by/users.rst Parameters: - user_id (``int`` | ``str``): - Unique identifier (int) or username (str) of the target user. + from_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target user/channel. For your personal story you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). @@ -51,15 +51,15 @@ class ExportStoryLink: .. code-block:: python # Get story link - await app.export_story_link(user_id, 12345) + await app.export_story_link(from_id, 12345) Raises: ValueError: In case of invalid arguments. """ - peer = await self.resolve_peer(user_id) + peer = await self.resolve_peer(from_id) - rpc = raw.functions.stories.ExportStoryLink(user_id=peer, story_id=story_id) + rpc = raw.functions.stories.ExportStoryLink(peer=peer, story_id=story_id) r = await self.invoke(rpc, sleep_threshold=-1) diff --git a/pyrogram/methods/users/get_all_stories.py b/pyrogram/methods/users/get_all_stories.py index 55e9b777..34372926 100644 --- a/pyrogram/methods/users/get_all_stories.py +++ b/pyrogram/methods/users/get_all_stories.py @@ -51,7 +51,6 @@ class GetAllStories: r = await self.invoke(rpc, sleep_threshold=-1) - for user_story in r.user_stories: - user_id = user_story.user_id - for story in user_story.stories: - yield await types.Story._parse(self, story, user_id) + for peer_story in r.peer_stories: + for story in peer_story.stories: + yield await types.Story._parse(self, story, peer_story.peer) diff --git a/pyrogram/methods/users/get_user_stories.py b/pyrogram/methods/users/get_peer_stories.py similarity index 77% rename from pyrogram/methods/users/get_user_stories.py rename to pyrogram/methods/users/get_peer_stories.py index bee290af..6bbf3508 100644 --- a/pyrogram/methods/users/get_user_stories.py +++ b/pyrogram/methods/users/get_peer_stories.py @@ -25,18 +25,18 @@ from pyrogram import types log = logging.getLogger(__name__) -class GetUserStories: - async def get_user_stories( +class GetPeerStories: + async def get_peer_stories( self: "pyrogram.Client", - user_id: Union[int, str] + from_id: Union[int, str] ) -> Optional[AsyncGenerator["types.Story", None]]: - """Get all active stories from an user by using user identifiers. + """Get all active stories from an user/channel by using user identifiers. .. include:: /_includes/usable-by/users.rst Parameters: - user_id (``int`` | ``str``): - Unique identifier (int) or username (str) of the target user. + from_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target user/channel. For your personal story you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). @@ -46,20 +46,20 @@ class GetUserStories: Example: .. code-block:: python - # Get all active story from spesific user - async for story in app.get_user_stories(user_id): + # Get all active story from spesific user/channel + async for story in app.get_peer_stories(from_id): print(story) Raises: ValueError: In case of invalid arguments. """ - peer = await self.resolve_peer(user_id) + peer = await self.resolve_peer(from_id) - rpc = raw.functions.stories.GetUserStories(user_id=peer) + rpc = raw.functions.stories.GetPeerStories(peer=peer) r = await self.invoke(rpc, sleep_threshold=-1) for story in r.stories.stories: - yield await types.Story._parse(self, story, user_id) + yield await types.Story._parse(self, story, peer) diff --git a/pyrogram/methods/users/get_stories.py b/pyrogram/methods/users/get_stories.py index b7e76f9a..7d1a2408 100644 --- a/pyrogram/methods/users/get_stories.py +++ b/pyrogram/methods/users/get_stories.py @@ -28,7 +28,7 @@ log = logging.getLogger(__name__) class GetStories: async def get_stories( self: "pyrogram.Client", - user_id: Union[int, str], + from_id: Union[int, str], story_ids: Union[int, Iterable[int]], ) -> Union["types.Story", List["types.Story"]]: """Get one or more story from an user by using story identifiers. @@ -36,8 +36,8 @@ class GetStories: .. include:: /_includes/usable-by/users.rst Parameters: - user_id (``int`` | ``str``): - Unique identifier (int) or username (str) of the target user. + from_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target user/channel. For your personal story you can simply use "me" or "self". For a contact that exists in your Telegram address book you can use his phone number (str). @@ -53,24 +53,24 @@ class GetStories: .. code-block:: python # Get one story - await app.get_stories(user_id, 12345) + await app.get_stories(from_id, 12345) # Get more than one story (list of stories) - await app.get_stories(user_id, [12345, 12346]) + await app.get_stories(from_id, [12345, 12346]) Raises: ValueError: In case of invalid arguments. """ - peer = await self.resolve_peer(user_id) + peer = await self.resolve_peer(from_id) is_iterable = not isinstance(story_ids, int) ids = list(story_ids) if is_iterable else [story_ids] - rpc = raw.functions.stories.GetStoriesByID(user_id=peer, id=ids) + rpc = raw.functions.stories.GetStoriesByID(peer=peer, id=ids) r = await self.invoke(rpc, sleep_threshold=-1) if is_iterable: - return types.List([await types.Story._parse(self, story, user_id) for story in r.stories]) - return await types.Story._parse(self, r.stories[0], user_id) + return types.List([await types.Story._parse(self, story, peer) for story in r.stories]) + return await types.Story._parse(self, r.stories[0], peer) diff --git a/pyrogram/methods/users/get_stories_history.py b/pyrogram/methods/users/get_stories_history.py index 44428829..aaf3267a 100644 --- a/pyrogram/methods/users/get_stories_history.py +++ b/pyrogram/methods/users/get_stories_history.py @@ -28,6 +28,7 @@ log = logging.getLogger(__name__) class GetUserStoriesHistory: async def get_stories_history( self: "pyrogram.Client", + channel_id: int = None, limit: int = 0, offset_id: int = 0 ) -> Optional[AsyncGenerator["types.Story", None]]: @@ -36,6 +37,9 @@ class GetUserStoriesHistory: .. include:: /_includes/usable-by/users.rst Parameters: + channel_id (``int``, *optional*): + Unique identifier (int) of the target channel. + limit (``int``, *optional*): Limits the number of stories to be retrieved. By default, no limit is applied and all stories are returned. @@ -56,10 +60,15 @@ class GetUserStoriesHistory: Raises: ValueError: In case of invalid arguments. """ + + if channel_id: + peer = await self.resolve_peer(channel_id) + else: + peer = await self.resolve_peer("me") - rpc = raw.functions.stories.GetStoriesArchive(offset_id=offset_id, limit=limit) + rpc = raw.functions.stories.GetStoriesArchive(peer=peer, offset_id=offset_id, limit=limit) r = await self.invoke(rpc, sleep_threshold=-1) for story in r.stories: - yield await types.Story._parse(self, story, self.me.id) + yield await types.Story._parse(self, story, peer) diff --git a/pyrogram/methods/users/send_story.py b/pyrogram/methods/users/send_story.py index c68d2f76..ac0880d0 100644 --- a/pyrogram/methods/users/send_story.py +++ b/pyrogram/methods/users/send_story.py @@ -30,6 +30,7 @@ class SendStory: async def send_story( self: "pyrogram.Client", + channel_id: int = None, privacy: "enums.StoriesPrivacy" = None, allowed_users: List[int] = None, denied_users: List[int] = None, @@ -52,6 +53,9 @@ class SendStory: Note: You must pass one of following paramater *animation*, *photo*, *video* Parameters: + channel_id (``int``, *optional*): + Unique identifier (int) of the target channel. + animation (``str`` | ``BinaryIO``, *optional*): Animation to send. Pass a file_id as string to send a animation that exists on the Telegram servers, @@ -126,6 +130,11 @@ class SendStory: """ # TODO: media_areas + if channel_id: + peer = await self.resolve_peer(channel_id) + else: + peer = await self.resolve_peer("me") + if privacy: privacy_rules = [types.StoriesPrivacy(type=privacy)] else: @@ -243,6 +252,7 @@ class SendStory: r = await self.invoke( raw.functions.stories.SendStory( + peer=peer, media=media, privacy_rules=privacy_rules, random_id=self.rnd_id(), @@ -253,4 +263,4 @@ class SendStory: period=period ) ) - return await types.Story._parse(self, r.updates[0].story, r.updates[0].user_id) + return await types.Story._parse(self, r.updates[0].story, r.updates[0].peer) diff --git a/pyrogram/types/messages_and_media/story.py b/pyrogram/types/messages_and_media/story.py index b238d292..29fc701e 100644 --- a/pyrogram/types/messages_and_media/story.py +++ b/pyrogram/types/messages_and_media/story.py @@ -33,6 +33,9 @@ class Story(Object, Update): from_user (:obj:`~pyrogram.types.User`, *optional*): Sender of the story. + + sender_chat (:obj:`~pyrogram.types.Chat`, *optional*): + Sender of the story. If the story is from channel. date (:py:obj:`~datetime.datetime`, *optional*): Date the story was sent. @@ -92,7 +95,8 @@ class Story(Object, Update): *, client: "pyrogram.Client" = None, id: int, - from_user: "types.User", + from_user: "types.User" = None, + sender_chat: "types.Chat" = None, date: datetime, expire_date: datetime, media: "enums.MessageMediaType", @@ -114,6 +118,7 @@ class Story(Object, Update): self.id = id self.from_user = from_user + self.sender_chat = sender_chat self.date = date self.expire_date = expire_date self.media = media @@ -135,13 +140,15 @@ class Story(Object, Update): async def _parse( client: "pyrogram.Client", stories: raw.base.StoryItem, - user_id: int + peer: Union["raw.types.PeerChannel", "raw.types.PeerUser"] ) -> "Story": entities = [types.MessageEntity._parse(client, entity, {}) for entity in stories.entities] entities = types.List(filter(lambda x: x is not None, entities)) animation = None photo = None video = None + from_user = None + sender_chat = None if stories.media: if isinstance(stories.media, raw.types.MessageMediaPhoto): photo = types.Photo._parse(client, stories.media.photo, stories.media.ttl_seconds) @@ -164,11 +171,17 @@ class Story(Object, Update): media_type = None else: media_type = None - from_user = await client.get_users(user_id) + if isinstance(peer, raw.types.PeerChannel): + sender_chat = await client.get_chat(peer.channel_id) + elif isinstance(peer, raw.types.InputPeerSelf): + from_user = client.me + else: + from_user = await client.get_users(peer.user_id) return Story( id=stories.id, from_user=from_user, + sender_chat=sender_chat, date=utils.timestamp_to_datetime(stories.date), expire_date=utils.timestamp_to_datetime(stories.expire_date), media=media_type, @@ -260,7 +273,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_message( - chat_id=self.from_user.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, text=text, parse_mode=parse_mode, entities=entities, @@ -399,7 +412,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_animation( - chat_id=self.from_user.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, animation=animation, caption=caption, parse_mode=parse_mode, @@ -538,7 +551,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_audio( - chat_id=self.from_user.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, audio=audio, caption=caption, parse_mode=parse_mode, @@ -623,7 +636,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_cached_media( - chat_id=self.from_user.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, file_id=file_id, caption=caption, parse_mode=parse_mode, @@ -685,7 +698,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_media_group( - chat_id=self.chat.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, media=media, disable_notification=disable_notification, reply_to_story_id=reply_to_story_id @@ -797,7 +810,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_photo( - chat_id=self.chat.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, photo=photo, caption=caption, parse_mode=parse_mode, @@ -895,7 +908,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_sticker( - chat_id=self.chat.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, sticker=sticker, disable_notification=disable_notification, reply_to_story_id=reply_to_story_id, @@ -1038,7 +1051,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_video( - chat_id=self.chat.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, video=video, caption=caption, parse_mode=parse_mode, @@ -1156,7 +1169,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_video_note( - chat_id=self.chat.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, video_note=video_note, duration=duration, length=length, @@ -1268,7 +1281,7 @@ class Story(Object, Update): reply_to_story_id = self.id return await self._client.send_voice( - chat_id=self.chat.id, + chat_id=self.from_user.id if self.from_user else self.sender_chat.id, voice=voice, caption=caption, parse_mode=parse_mode, @@ -1303,7 +1316,10 @@ class Story(Object, Update): Raises: RPCError: In case of a Telegram RPC error. """ - return await self._client.delete_stories(story_ids=self.id) + return await self._client.delete_stories( + channel_id=self.sender_chat.id if self.sender_chat else None, + story_ids=self.id + ) async def edit_animation( self, @@ -1336,6 +1352,7 @@ class Story(Object, Update): RPCError: In case of a Telegram RPC error. """ return await self._client.edit_story( + channel_id=self.sender_chat.id if self.sender_chat else None, story_id=self.id, animation=animation ) @@ -1392,7 +1409,8 @@ class Story(Object, Update): New story video. Pass a file_id as string to send a video that exists on the Telegram servers, pass an HTTP URL as a string for Telegram to get a video from the Internet, - pass a file path as string to upload a new video that exists on your local machine, or + pass a file path as string to upload a + channel=self.sender_chat.id if self.sender_chat else None,new video that exists on your local machine, or pass a binary file-like object with its attribute ".name" set for in-memory uploads. privacy (:obj:`~pyrogram.enums.StoriesPrivacy`, *optional*): @@ -1427,6 +1445,7 @@ class Story(Object, Update): RPCError: In case of a Telegram RPC error. """ return await self._client.edit_story( + channel_id=self.sender_chat.id if self.sender_chat else None, story_id=self.id, privacy=privacy, allowed_chats=allowed_chats, @@ -1452,9 +1471,7 @@ class Story(Object, Update): Use as a shortcut for: .. code-block:: python - - await client.edit_story( - story_id=story.id, + channel=self.sender_chat.id if self.sender_chat else None, caption="hello" ) @@ -1481,6 +1498,7 @@ class Story(Object, Update): RPCError: In case of a Telegram RPC error. """ return await self._client.edit_story( + channel_id=self.sender_chat.id if self.sender_chat else None, story_id=self.id, caption=caption, parse_mode=parse_mode, @@ -1518,6 +1536,7 @@ class Story(Object, Update): RPCError: In case of a Telegram RPC error. """ return await self._client.edit_story( + channel_id=self.sender_chat.id if self.sender_chat else None, story_id=self.id, photo=photo ) @@ -1569,6 +1588,7 @@ class Story(Object, Update): RPCError: In case of a Telegram RPC error. """ return await self._client.edit_story( + channel_id=self.sender_chat.id if self.sender_chat else None, story_id=self.id, privacy=privacy, allowed_chats=allowed_chats, @@ -1608,6 +1628,7 @@ class Story(Object, Update): RPCError: In case of a Telegram RPC error. """ return await self._client.edit_story( + channel_id=self.sender_chat.id if self.sender_chat else None, story_id=self.id, video=video ) @@ -1635,4 +1656,4 @@ class Story(Object, Update): Raises: RPCError: In case of a Telegram RPC error. """ - return await self._client.export_story_link(user_id=self.from_user.id, story_id=self.id) + return await self._client.export_story_link(from_id=self.from_user.id if self.from_user else self.sender_chat.id, story_id=self.id)