Refactor stories methods

This commit is contained in:
KurimuzonAkuma 2024-10-29 13:17:35 +03:00
parent 57433be99b
commit 0cc1b82cdf
16 changed files with 230 additions and 88 deletions

View File

@ -408,7 +408,7 @@ def pyrogram_api():
""", """,
stories=""" stories="""
Stories Stories
can_send_story can_post_stories
copy_story copy_story
delete_stories delete_stories
edit_story_caption edit_story_caption
@ -418,12 +418,14 @@ def pyrogram_api():
get_all_stories get_all_stories
get_chat_stories get_chat_stories
get_pinned_stories get_pinned_stories
get_stories_archive get_archived_stories
get_stories get_stories
hide_stories hide_chat_stories
show_chat_stories
view_stories view_stories
pin_stories pin_chat_stories
read_stories unpin_chat_stories
read_chat_stories
send_story send_story
""", """,
premium=""" premium="""
@ -795,6 +797,7 @@ def pyrogram_api():
""", """,
story=""" story="""
Story Story
Story.reply
Story.reply_text Story.reply_text
Story.reply_animation Story.reply_animation
Story.reply_audio Story.reply_audio

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .can_send_story import CanSendStory from .can_post_stories import CanPostStories
from .copy_story import CopyStory from .copy_story import CopyStory
from .delete_stories import DeleteStories from .delete_stories import DeleteStories
from .edit_story_caption import EditStoryCaption from .edit_story_caption import EditStoryCaption
@ -24,18 +24,20 @@ from .edit_story_media import EditStoryMedia
from .edit_story_privacy import EditStoryPrivacy from .edit_story_privacy import EditStoryPrivacy
from .forward_story import ForwardStory from .forward_story import ForwardStory
from .get_all_stories import GetAllStories from .get_all_stories import GetAllStories
from .get_archived_stories import GetArchivedStories
from .get_chat_stories import GetChatStories from .get_chat_stories import GetChatStories
from .get_pinned_stories import GetPinnedStories from .get_pinned_stories import GetPinnedStories
from .get_stories import GetStories from .get_stories import GetStories
from .get_stories_archive import GetStoriesArchive from .hide_chat_stories import HideChatStories
from .hide_stories import HideStories from .pin_chat_stories import PinChatStories
from .view_stories import ViewStories from .read_chat_stories import ReadChatStories
from .pin_stories import PinStories
from .read_stories import ReadStories
from .send_story import SendStory from .send_story import SendStory
from .show_chat_stories import ShowChatStories
from .unpin_chat_stories import UnpinChatStories
from .view_stories import ViewStories
class Stories( class Stories(
CanSendStory, CanPostStories,
CopyStory, CopyStory,
DeleteStories, DeleteStories,
EditStoryCaption, EditStoryCaption,
@ -43,14 +45,16 @@ class Stories(
EditStoryPrivacy, EditStoryPrivacy,
ForwardStory, ForwardStory,
GetAllStories, GetAllStories,
GetArchivedStories,
GetChatStories, GetChatStories,
GetPinnedStories, GetPinnedStories,
GetStories, GetStories,
GetStoriesArchive, HideChatStories,
HideStories, PinChatStories,
ViewStories, ReadChatStories,
PinStories,
ReadStories,
SendStory, SendStory,
ShowChatStories,
UnpinChatStories,
ViewStories,
): ):
pass pass

View File

@ -22,12 +22,12 @@ import pyrogram
from pyrogram import raw from pyrogram import raw
class CanSendStory: class CanPostStories:
async def can_send_story( async def can_post_stories(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
) -> bool: ) -> bool:
"""Can send story """Check whether we can post stories as the specified chat.
.. include:: /_includes/usable-by/users.rst .. include:: /_includes/usable-by/users.rst
@ -36,13 +36,13 @@ class CanSendStory:
Unique identifier (int) or username (str) of the target chat. Unique identifier (int) or username (str) of the target chat.
Returns: Returns:
``str``: On success, a bool is returned. ``bool``: On success, True is returned.
Example: Example:
.. code-block:: python .. code-block:: python
# Check if you can send story to chat id # Check if you can send story to chat id
app.can_send_story(chat_id) app.can_post_stories(chat_id)
""" """
r = await self.invoke( r = await self.invoke(
raw.functions.stories.CanSendStory( raw.functions.stories.CanSendStory(

View File

@ -29,7 +29,7 @@ class DeleteStories:
chat_id: Union[int, str], chat_id: Union[int, str],
story_ids: Union[int, Iterable[int]], story_ids: Union[int, Iterable[int]],
) -> List[int]: ) -> List[int]:
"""Delete stories. """Delete posted stories.
.. include:: /_includes/usable-by/users.rst .. include:: /_includes/usable-by/users.rst
@ -37,13 +37,12 @@ class DeleteStories:
chat_id (``int`` | ``str``): chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat. Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self". 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).
story_ids (``int`` | Iterable of ``int``, *optional*): story_ids (``int`` | Iterable of ``int``, *optional*):
Unique identifier (int) or list of unique identifiers (list of int) for the target stories. Unique identifier (int) or list of unique identifiers (list of int) for the target stories.
Returns: Returns:
List of ``int``: List of deleted stories IDs List of ``int``: List of deleted stories IDs.
Example: Example:
.. code-block:: python .. code-block:: python

View File

@ -34,7 +34,7 @@ class ForwardStory:
message_thread_id: int = None, message_thread_id: int = None,
schedule_date: datetime = None, schedule_date: datetime = None,
) -> Optional["types.Message"]: ) -> Optional["types.Message"]:
"""Send story. """Forward story.
.. include:: /_includes/usable-by/users.rst .. include:: /_includes/usable-by/users.rst

View File

@ -30,10 +30,24 @@ class GetAllStories:
hidden: Optional[bool] = None, hidden: Optional[bool] = None,
state: Optional[str] = None, state: Optional[str] = None,
) -> AsyncGenerator["types.Story", None]: ) -> AsyncGenerator["types.Story", None]:
"""Get all active stories. """Get all active (or hidden stories that displayed on the action bar on the homescreen.
.. include:: /_includes/usable-by/users.rst .. include:: /_includes/usable-by/users.rst
Parameters
next (``bool``, *optional*):
If next and state are both set, uses the passed state to paginate to the next results.
If neither state nor next are set, fetches the initial page.
If state is set and next is not set, check for changes in the active/hidden peerset.
hidden (``bool``, *optional*):
If set, fetches the hidden active story list, otherwise fetches the active story list.
state (``str``, *optional*):
If next and state are both set, uses the passed state to paginate to the next results.
If neither state nor next are set, fetches the initial page.
If state is set and next is not set, check for changes in the active/hidden peerset.
Returns: Returns:
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.Story` objects is returned. ``Generator``: On success, a generator yielding :obj:`~pyrogram.types.Story` objects is returned.
@ -43,9 +57,6 @@ class GetAllStories:
# Get all active story # Get all active story
async for story in app.get_all_stories(): async for story in app.get_all_stories():
print(story) print(story)
Raises:
ValueError: In case of invalid arguments.
""" """
r = await self.invoke( r = await self.invoke(

View File

@ -23,8 +23,8 @@ from pyrogram import raw
from pyrogram import types from pyrogram import types
class GetStoriesArchive: class GetArchivedStories:
async def get_stories_archive( async def get_archived_stories(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
limit: int = 0, limit: int = 0,
@ -47,13 +47,13 @@ class GetStoriesArchive:
offset_id (``int``, *optional*): offset_id (``int``, *optional*):
Identifier of the first story to be returned. Identifier of the first story to be returned.
Yields: Returns:
:obj:`~pyrogram.types.Story` objects. ``Generator``: A generator yielding :obj:`~pyrogram.types.Story` objects.
Example: Example:
.. code-block:: python .. code-block:: python
# Get stories archive # Get archived stories from specific chat
async for story in app.get_stories_archive(chat_id): async for story in app.get_stories_archive(chat_id):
print(story) print(story)
""" """

View File

@ -44,7 +44,7 @@ class GetChatStories:
Example: Example:
.. code-block:: python .. code-block:: python
# Get all non expired stories from spesific chat # Get all non expired stories from specific chat
async for story in app.get_chat_stories(chat_id): async for story in app.get_chat_stories(chat_id):
print(story) print(story)

View File

@ -47,8 +47,8 @@ class GetPinnedStories:
Maximum amount of events to be returned. Maximum amount of events to be returned.
By default, all events will be returned. By default, all events will be returned.
Yields: Returns:
:obj:`~pyrogram.types.Story` objects. ``Generator``: On success, a generator yielding :obj:`~pyrogram.types.Story` objects is returned.
Example: Example:
.. code-block:: python .. code-block:: python

View File

@ -0,0 +1,56 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram
from pyrogram import raw
class HideChatStories:
async def hide_chat_stories(
self: "pyrogram.Client",
chat_id: Union[int, str],
) -> bool:
"""Hide the active stories of a user, preventing them from being displayed on the action bar on the homescreen.
.. include:: /_includes/usable-by/users.rst
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).
Returns:
``bool``: On success, a bool is returned.
Example:
.. code-block:: python
# Hide stories from specific chat
app.hide_chat_stories(chat_id)
"""
r = await self.invoke(
raw.functions.stories.TogglePeerStoriesHidden(
peer=await self.resolve_peer(chat_id),
hidden=True
)
)
return r

View File

@ -23,12 +23,11 @@ from pyrogram import raw
from pyrogram import types from pyrogram import types
class PinStories: class PinChatStories:
async def pin_stories( async def pin_chat_stories(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
stories_ids: Union[int, Iterable[int]], stories_ids: Union[int, Iterable[int]]
pinned: bool = False,
) -> List[int]: ) -> List[int]:
"""Pin one or more stories in a chat by using stories identifiers. """Pin one or more stories in a chat by using stories identifiers.
@ -42,9 +41,6 @@ class PinStories:
stories_ids (``int`` | Iterable of ``int``, *optional*): stories_ids (``int`` | Iterable of ``int``, *optional*):
List of unique identifiers of the target stories. List of unique identifiers of the target stories.
pinned (``bool``):
If set to ``True``, the stories will be pinned.
Returns: Returns:
List of ``int``: List of pinned stories IDs List of ``int``: List of pinned stories IDs
@ -52,7 +48,7 @@ class PinStories:
.. code-block:: python .. code-block:: python
# Pin a single story # Pin a single story
await app.pin_stories(chat_id, 123456789, True) await app.pin_chat_stories(chat_id, 123456789)
""" """
is_iterable = not isinstance(stories_ids, int) is_iterable = not isinstance(stories_ids, int)
@ -62,7 +58,7 @@ class PinStories:
raw.functions.stories.TogglePinned( raw.functions.stories.TogglePinned(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
id=stories_ids, id=stories_ids,
pinned=pinned pinned=True
) )
) )

View File

@ -22,13 +22,13 @@ import pyrogram
from pyrogram import raw, types from pyrogram import raw, types
class ReadStories: class ReadChatStories:
async def read_stories( async def read_chat_stories(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
max_id: int = 0, max_id: int = 0,
) -> List[int]: ) -> List[int]:
"""Read stories. """Mark all stories up to a certain identifier as read, for a given chat.
.. include:: /_includes/usable-by/users.rst .. include:: /_includes/usable-by/users.rst
@ -38,8 +38,9 @@ class ReadStories:
For a contact that exists in your Telegram address book you can use his phone number (str). For a contact that exists in your Telegram address book you can use his phone number (str).
max_id (``int``, *optional*): max_id (``int``, *optional*):
The id of the last story you want to mark as read; all the stories before this one will be marked as The id of the last story you want to mark as read.
read as well. Defaults to 0 (mark every unread message as read). All the stories before this one will be marked as read as well.
Defaults to 0 (mark every unread message as read).
Returns: Returns:
List of ``int``: On success, a list of read stories is returned. List of ``int``: On success, a list of read stories is returned.
@ -48,10 +49,10 @@ class ReadStories:
.. code-block:: python .. code-block:: python
# Read all stories # Read all stories
await app.read_stories(chat_id) await app.read_chat_stories(chat_id)
# Mark stories as read only up to the given story id # Mark stories as read only up to the given story id
await app.read_stories(chat_id, 123) await app.read_chat_stories(chat_id, 123)
""" """
r = await self.invoke( r = await self.invoke(
raw.functions.stories.ReadStories( raw.functions.stories.ReadStories(

View File

@ -46,7 +46,7 @@ class SendStory:
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Story": ) -> "types.Story":
"""Send new story. """Post new story.
.. include:: /_includes/usable-by/users.rst .. include:: /_includes/usable-by/users.rst

View File

@ -22,13 +22,12 @@ import pyrogram
from pyrogram import raw from pyrogram import raw
class HideStories: class ShowChatStories:
async def hide_stories( async def show_chat_stories(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
hidden: bool = None
) -> bool: ) -> bool:
"""Toggle peer stories hidden """Show the active stories of a user and display them in the action bar on the homescreen.
.. include:: /_includes/usable-by/users.rst .. include:: /_includes/usable-by/users.rst
@ -39,18 +38,18 @@ class HideStories:
For a contact that exists in your Telegram address book you can use his phone number (str). For a contact that exists in your Telegram address book you can use his phone number (str).
Returns: Returns:
``str``: On success, a bool is returned. ``bool``: On success, a bool is returned.
Example: Example:
.. code-block:: python .. code-block:: python
# Export a story link # Show stories from specific chat
link = app.hide_stories("me") app.show_chat_stories(chat_id)
""" """
r = await self.invoke( r = await self.invoke(
raw.functions.stories.TogglePeerStoriesHidden( raw.functions.stories.TogglePeerStoriesHidden(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
hidden=hidden hidden=False
) )
) )

View File

@ -0,0 +1,65 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# 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 <http://www.gnu.org/licenses/>.
from typing import List, Union, Iterable
import pyrogram
from pyrogram import raw
from pyrogram import types
class UnpinChatStories:
async def unpin_chat_stories(
self: "pyrogram.Client",
chat_id: Union[int, str],
stories_ids: Union[int, Iterable[int]]
) -> List[int]:
"""Unpin one or more stories in a chat by using stories identifiers.
.. include:: /_includes/usable-by/users.rst
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".
stories_ids (``int`` | Iterable of ``int``, *optional*):
List of unique identifiers of the target stories.
Returns:
List of ``int``: List of pinned stories identifiers.
Example:
.. code-block:: python
# Unpin a single story
await app.unpin_chat_stories(chat_id, 123456789)
"""
is_iterable = not isinstance(stories_ids, int)
stories_ids = list(stories_ids) if is_iterable else [stories_ids]
r = await self.invoke(
raw.functions.stories.TogglePinned(
peer=await self.resolve_peer(chat_id),
id=stories_ids,
pinned=False
)
)
return types.List(r)

View File

@ -350,7 +350,7 @@ class Story(Object, Update):
) )
@property @property
def link(self) -> str: def link(self) -> Optional[str]:
if not self.chat.username: if not self.chat.username:
return None return None
@ -433,6 +433,8 @@ class Story(Object, Update):
reply_markup=reply_markup reply_markup=reply_markup
) )
reply = reply_text
async def reply_animation( async def reply_animation(
self, self,
animation: Union[str, BinaryIO], animation: Union[str, BinaryIO],
@ -454,7 +456,7 @@ class Story(Object, Update):
] = None, ] = None,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_animation* :obj:`~pyrogram.types.Story`. """Bound method *reply_animation* :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -588,7 +590,7 @@ class Story(Object, Update):
] = None, ] = None,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_audio* of :obj:`~pyrogram.types.Story`. """Bound method *reply_audio* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -711,7 +713,7 @@ class Story(Object, Update):
"types.ReplyKeyboardRemove", "types.ReplyKeyboardRemove",
"types.ForceReply" "types.ForceReply"
] = None ] = None
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_cached_media* of :obj:`~pyrogram.types.Story`. """Bound method *reply_cached_media* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -838,7 +840,7 @@ class Story(Object, Update):
] = None, ] = None,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_photo* of :obj:`~pyrogram.types.Story`. """Bound method *reply_photo* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -951,7 +953,7 @@ class Story(Object, Update):
] = None, ] = None,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_sticker* of :obj:`~pyrogram.types.Story`. """Bound method *reply_sticker* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -1051,7 +1053,7 @@ class Story(Object, Update):
] = None, ] = None,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_video* of :obj:`~pyrogram.types.Story`. """Bound method *reply_video* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -1196,7 +1198,7 @@ class Story(Object, Update):
] = None, ] = None,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_video_note* of :obj:`~pyrogram.types.Story`. """Bound method *reply_video_note* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -1306,7 +1308,7 @@ class Story(Object, Update):
] = None, ] = None,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> "types.Message": ) -> Optional["types.Message"]:
"""Bound method *reply_voice* of :obj:`~pyrogram.types.Story`. """Bound method *reply_voice* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -1695,7 +1697,7 @@ class Story(Object, Update):
message_thread_id: int = None, message_thread_id: int = None,
disable_notification: bool = None, disable_notification: bool = None,
schedule_date: datetime = None schedule_date: datetime = None
) -> Union["types.Message", List["types.Message"]]: ) -> Optional["types.Message"]:
"""Bound method *forward* of :obj:`~pyrogram.types.Story`. """Bound method *forward* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -1752,7 +1754,7 @@ class Story(Object, Update):
block: bool = True, block: bool = True,
progress: Callable = None, progress: Callable = None,
progress_args: tuple = () progress_args: tuple = ()
) -> str: ) -> Optional[Union[str, BinaryIO]]:
"""Bound method *download* of :obj:`~pyrogram.types.Story`. """Bound method *download* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for: Use as a shortcut for:
@ -1823,6 +1825,15 @@ class Story(Object, Update):
async def read(self) -> List[int]: async def read(self) -> List[int]:
"""Bound method *read* of :obj:`~pyrogram.types.Story`. """Bound method *read* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for:
.. code-block:: python
await client.read_chat_stories(
chat_id=chat_id,
max_id=story_id
)
Example: Example:
.. code-block:: python .. code-block:: python
@ -1830,21 +1841,24 @@ class Story(Object, Update):
Returns: Returns:
List of ``int``: On success, a list of read stories is returned. List of ``int``: On success, a list of read stories is returned.
Example:
.. code-block:: python
# Read stories
await app.read_stories(chat_id)
""" """
return await self._client.read_stories( return await self._client.read_chat_stories(
chat_id=self.chat.id, chat_id=self.chat.id,
max_id=self.id max_id=self.id
) )
async def view(self) -> List[int]: async def view(self) -> bool:
"""Bound method *view* of :obj:`~pyrogram.types.Story`. """Bound method *view* of :obj:`~pyrogram.types.Story`.
Use as a shortcut for:
.. code-block:: python
await client.view_stories(
chat_id=chat_id,
story_id=story_id
)
Example: Example:
.. code-block:: python .. code-block:: python
@ -1852,12 +1866,6 @@ class Story(Object, Update):
Returns: Returns:
True on success, False otherwise. True on success, False otherwise.
Example:
.. code-block:: python
# Read stories
await app.view_stories(chat_id)
""" """
return await self._client.view_stories( return await self._client.view_stories(
chat_id=self.chat.id, chat_id=self.chat.id,