diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index 78b5a32b..ff45fad1 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -93,6 +93,7 @@ Chats get_chat_members get_chat_members_count get_dialogs + iter_dialogs Users ----- diff --git a/pyrogram/client/ext/base_client.py b/pyrogram/client/ext/base_client.py index 93d4e57e..5e03e100 100644 --- a/pyrogram/client/ext/base_client.py +++ b/pyrogram/client/ext/base_client.py @@ -117,3 +117,6 @@ class BaseClient: def get_history(self, *args, **kwargs): pass + + def get_dialogs(self, *args, **kwargs): + pass diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index 745678cc..7f7761c5 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -24,6 +24,7 @@ from .get_chat_members import GetChatMembers from .get_chat_members_count import GetChatMembersCount from .get_chat_preview import GetChatPreview from .get_dialogs import GetDialogs +from .iter_dialogs import IterDialogs from .join_chat import JoinChat from .kick_chat_member import KickChatMember from .leave_chat import LeaveChat @@ -56,6 +57,7 @@ class Chats( UnpinChatMessage, GetDialogs, GetChatMembersCount, - GetChatPreview + GetChatPreview, + IterDialogs ): pass diff --git a/pyrogram/client/methods/chats/iter_dialogs.py b/pyrogram/client/methods/chats/iter_dialogs.py new file mode 100644 index 00000000..6058cd17 --- /dev/null +++ b/pyrogram/client/methods/chats/iter_dialogs.py @@ -0,0 +1,82 @@ +# 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 Generator + +import pyrogram +from ...ext import BaseClient + + +class IterDialogs(BaseClient): + def iter_dialogs(self, + offset_date: int = 0, + limit: int = 0) -> Generator["pyrogram.Dialog", None, None]: + """Use this method to iterate through a user's dialogs sequentially. + + This convenience method does the same as repeatedly calling :meth:`get_dialogs` in a loop, thus saving you from + the hassle of setting up boilerplate code. It is useful for getting the whole dialogs list with a single call. + + Args: + offset_date (``int``): + The offset date in Unix time taken from the top message of a :obj:`Dialog`. + Defaults to 0 (most recent dialog). + + limit (``str``, *optional*): + Limits the number of dialogs to be retrieved. + By default, no limit is applied and all dialogs are returned. + + Returns: + A generator yielding :obj:`Dialog ` objects. + + Raises: + :class:`Error ` in case of a Telegram RPC error. + """ + current = 0 + total = limit or (1 << 31) - 1 + limit = min(100, total) + + pinned_dialogs = self.get_dialogs( + pinned_only=True + ).dialogs + + for dialog in pinned_dialogs: + yield dialog + + current += 1 + + if current >= total: + return + + while True: + dialogs = self.get_dialogs( + offset_date=offset_date, + limit=limit + ).dialogs + + if not dialogs: + return + + offset_date = dialogs[-1].top_message.date + + for dialog in dialogs: + yield dialog + + current += 1 + + if current >= total: + return