Remove remaining iter_* methods

This commit is contained in:
Dan 2022-04-24 11:56:07 +02:00
parent 6eadb75086
commit 4cb9dec35d
8 changed files with 112 additions and 297 deletions

View File

@ -213,7 +213,6 @@ def pyrogram_api():
get_chat_members
get_chat_members_count
get_dialogs
iter_dialogs
get_dialogs_count
set_chat_username
get_nearby_chats
@ -238,9 +237,8 @@ def pyrogram_api():
Users
get_me
get_users
get_profile_photos
get_profile_photos_count
iter_profile_photos
get_chat_photos
get_chat_photos_count
set_profile_photo
delete_profile_photos
set_username

View File

@ -36,7 +36,6 @@ from .get_dialogs import GetDialogs
from .get_dialogs_count import GetDialogsCount
from .get_nearby_chats import GetNearbyChats
from .get_send_as_chats import GetSendAsChats
from .iter_dialogs import IterDialogs
from .join_chat import JoinChat
from .leave_chat import LeaveChat
from .mark_chat_unread import MarkChatUnread
@ -76,7 +75,6 @@ class Chats(
UnpinChatMessage,
GetDialogs,
GetChatMembersCount,
IterDialogs,
SetChatUsername,
SetChatPermissions,
GetDialogsCount,

View File

@ -16,92 +16,87 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import logging
from datetime import datetime
from typing import List
from typing import AsyncGenerator, Optional
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
log = logging.getLogger(__name__)
from pyrogram import types, raw, utils
class GetDialogs:
async def get_dialogs(
self: "pyrogram.Client",
offset_date: datetime = datetime.fromtimestamp(0),
limit: int = 100,
pinned_only: bool = False
) -> List["types.Dialog"]:
"""Get a chunk of the user's dialogs.
You can get up to 100 dialogs at once.
For a more convenient way of getting a user's dialogs see :meth:`~pyrogram.Client.iter_dialogs`.
limit: int = 0
) -> Optional[AsyncGenerator["types.Dialog", None]]:
"""Get a user's dialogs sequentially.
Parameters:
offset_date (:py:obj:`~datetime.datetime`):
The offset date taken from the top message of a :obj:`~pyrogram.types.Dialog`.
Defaults to epoch. Valid for non-pinned dialogs only.
limit (``str``, *optional*):
limit (``int``, *optional*):
Limits the number of dialogs to be retrieved.
Defaults to 100. Valid for non-pinned dialogs only.
pinned_only (``bool``, *optional*):
Pass True if you want to get only pinned dialogs.
Defaults to False.
By default, no limit is applied and all dialogs are returned.
Returns:
List of :obj:`~pyrogram.types.Dialog`: On success, a list of dialogs is returned.
``Generator``: A generator yielding :obj:`~pyrogram.types.Dialog` objects.
Example:
.. code-block:: python
# Get first 100 dialogs
await app.get_dialogs()
# Get pinned dialogs
await app.get_dialogs(pinned_only=True)
# Iterate through all dialogs
async for dialog in app.get_dialogs():
print(dialog.chat.first_name or dialog.chat.title)
"""
current = 0
total = limit or (1 << 31) - 1
limit = min(100, total)
if pinned_only:
r = await self.invoke(
raw.functions.messages.GetPinnedDialogs(folder_id=0),
sleep_threshold=60
)
else:
offset_date = 0
offset_id = 0
offset_peer = raw.types.InputPeerEmpty()
while True:
r = await self.invoke(
raw.functions.messages.GetDialogs(
offset_date=utils.datetime_to_timestamp(offset_date),
offset_id=0,
offset_peer=raw.types.InputPeerEmpty(),
offset_date=offset_date,
offset_id=offset_id,
offset_peer=offset_peer,
limit=limit,
hash=0,
exclude_pinned=True
hash=0
),
sleep_threshold=60
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
messages = {}
messages = {}
for message in r.messages:
if isinstance(message, raw.types.MessageEmpty):
continue
for message in r.messages:
if isinstance(message, raw.types.MessageEmpty):
continue
chat_id = utils.get_peer_id(message.peer_id)
messages[chat_id] = await types.Message._parse(self, message, users, chats)
chat_id = utils.get_peer_id(message.peer_id)
messages[chat_id] = await types.Message._parse(self, message, users, chats)
parsed_dialogs = []
dialogs = []
for dialog in r.dialogs:
if not isinstance(dialog, raw.types.Dialog):
continue
for dialog in r.dialogs:
if not isinstance(dialog, raw.types.Dialog):
continue
parsed_dialogs.append(types.Dialog._parse(self, dialog, messages, users, chats))
dialogs.append(types.Dialog._parse(self, dialog, messages, users, chats))
return types.List(parsed_dialogs)
if not dialogs:
return
last = dialogs[-1]
offset_id = last.top_message.id
offset_date = utils.datetime_to_timestamp(last.top_message.date)
offset_peer = await self.resolve_peer(last.chat.id)
for dialog in dialogs:
yield dialog
current += 1
if current >= total:
return

View File

@ -1,106 +0,0 @@
# 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 AsyncGenerator, Optional
import pyrogram
from pyrogram import types, raw, utils
class IterDialogs:
async def iter_dialogs(
self: "pyrogram.Client",
limit: int = 0
) -> Optional[AsyncGenerator["types.Dialog", None]]:
"""Iterate through a user's dialogs sequentially.
This convenience method does the same as repeatedly calling :meth:`~pyrogram.Client.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.
Parameters:
limit (``int``, *optional*):
Limits the number of dialogs to be retrieved.
By default, no limit is applied and all dialogs are returned.
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Dialog` objects.
Example:
.. code-block:: python
# Iterate through all dialogs
async for dialog in app.iter_dialogs():
print(dialog.chat.first_name or dialog.chat.title)
"""
current = 0
total = limit or (1 << 31) - 1
limit = min(100, total)
offset_date = 0
offset_id = 0
offset_peer = raw.types.InputPeerEmpty()
while True:
r = (await self.invoke(
raw.functions.messages.GetDialogs(
offset_date=offset_date,
offset_id=offset_id,
offset_peer=offset_peer,
limit=limit,
hash=0
),
sleep_threshold=60
))
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
messages = {}
for message in r.messages:
if isinstance(message, raw.types.MessageEmpty):
continue
chat_id = utils.get_peer_id(message.peer_id)
messages[chat_id] = await types.Message._parse(self, message, users, chats)
dialogs = []
for dialog in r.dialogs:
if not isinstance(dialog, raw.types.Dialog):
continue
dialogs.append(types.Dialog._parse(self, dialog, messages, users, chats))
if not dialogs:
return
last = dialogs[-1]
offset_id = last.top_message.id
offset_date = last.top_message.date
offset_peer = await self.resolve_peer(last.chat.id)
for dialog in dialogs:
yield dialog
current += 1
if current >= total:
return

View File

@ -18,12 +18,11 @@
from .block_user import BlockUser
from .delete_profile_photos import DeleteProfilePhotos
from .get_chat_photos import GetChatPhotos
from .get_chat_photos_count import GetChatPhotosCount
from .get_common_chats import GetCommonChats
from .get_me import GetMe
from .get_profile_photos import GetProfilePhotos
from .get_profile_photos_count import GetProfilePhotosCount
from .get_users import GetUsers
from .iter_profile_photos import IterProfilePhotos
from .set_profile_photo import SetProfilePhoto
from .set_username import SetUsername
from .unblock_user import UnblockUser
@ -33,14 +32,13 @@ from .update_profile import UpdateProfile
class Users(
BlockUser,
GetCommonChats,
GetProfilePhotos,
GetChatPhotos,
SetProfilePhoto,
DeleteProfilePhotos,
GetUsers,
GetMe,
SetUsername,
GetProfilePhotosCount,
IterProfilePhotos,
GetChatPhotosCount,
UnblockUser,
UpdateProfile,
):

View File

@ -16,22 +16,19 @@
# 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, List
from typing import Union, AsyncGenerator, Optional
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
from pyrogram import types, raw, utils
class GetProfilePhotos:
async def get_profile_photos(
class GetChatPhotos:
async def get_chat_photos(
self: "pyrogram.Client",
chat_id: Union[int, str],
offset: int = 0,
limit: int = 100
) -> List["types.Photo"]:
"""Get a list of profile pictures for a user or a chat.
limit: int = 0,
) -> Optional[AsyncGenerator["types.Photo", None]]:
"""Get a chat or a user profile photos sequentially.
Parameters:
chat_id (``int`` | ``str``):
@ -39,28 +36,18 @@ class GetProfilePhotos:
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).
offset (``int``, *optional*):
Sequential number of the first photo to be returned.
By default, all photos are returned.
limit (``int``, *optional*):
Limits the number of photos to be retrieved.
Values between 1100 are accepted. Defaults to 100.
Limits the number of profile photos to be retrieved.
By default, no limit is applied and all profile photos are returned.
Returns:
List of :obj:`~pyrogram.types.Photo`: On success, a list of profile photos is returned.
``Generator``: A generator yielding :obj:`~pyrogram.types.Photo` objects.
Example:
.. code-block:: python
# Get the first 100 profile photos of a user
await app.get_profile_photos("me")
# Get only the first profile photo of a user
await app.get_profile_photos("me", limit=1)
# Get 3 profile photos of a user, skip the first 5
await app.get_profile_photos("me", limit=3, offset=5)
async for photo in app.get_chat_photos("me"):
print(photo)
"""
peer_id = await self.resolve_peer(chat_id)
@ -105,15 +92,42 @@ class GetProfilePhotos:
else:
photos = []
return types.List(photos[offset:limit])
else:
r = await self.invoke(
raw.functions.photos.GetUserPhotos(
user_id=peer_id,
offset=offset,
max_id=0,
limit=limit
)
)
current = 0
return types.List(types.Photo._parse(self, photo) for photo in r.photos)
for photo in photos:
yield photo
current += 1
if current >= limit:
return
else:
current = 0
total = limit or (1 << 31)
limit = min(100, total)
offset = 0
while True:
r = await self.invoke(
raw.functions.photos.GetUserPhotos(
user_id=peer_id,
offset=offset,
max_id=0,
limit=limit
)
)
photos = [types.Photo._parse(self, photo) for photo in r.photos]
if not photos:
return
offset += len(photos)
for photo in photos:
yield photo
current += 1
if current >= total:
return

View File

@ -22,12 +22,12 @@ import pyrogram
from pyrogram import raw
class GetProfilePhotosCount:
async def get_profile_photos_count(
class GetChatPhotosCount:
async def get_chat_photos_count(
self: "pyrogram.Client",
chat_id: Union[int, str]
) -> int:
"""Get the total count of profile pictures for a user.
"""Get the total count of photos for a chat.
Parameters:
chat_id (``int`` | ``str``):
@ -41,7 +41,7 @@ class GetProfilePhotosCount:
Example:
.. code-block:: python
count = await app.get_profile_photos_count("me")
count = await app.get_chat_photos_count("me")
print(count)
"""

View File

@ -1,82 +0,0 @@
# 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, AsyncGenerator, Optional
import pyrogram
from pyrogram import types
class IterProfilePhotos:
async def iter_profile_photos(
self: "pyrogram.Client",
chat_id: Union[int, str],
offset: int = 0,
limit: int = 0,
) -> Optional[AsyncGenerator["types.Photo", None]]:
"""Iterate through a chat or a user profile photos sequentially.
This convenience method does the same as repeatedly calling :meth:`~pyrogram.Client.get_profile_photos` in a
loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting all the profile
photos with a single call.
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).
limit (``int``, *optional*):
Limits the number of profile photos to be retrieved.
By default, no limit is applied and all profile photos are returned.
offset (``int``, *optional*):
Sequential number of the first profile photo to be returned.
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Photo` objects.
Example:
.. code-block:: python
async for photo in app.iter_profile_photos("me"):
print(photo)
"""
current = 0
total = limit or (1 << 31)
limit = min(100, total)
while True:
photos = await self.get_profile_photos(
chat_id=chat_id,
offset=offset,
limit=limit
)
if not photos:
return
offset += len(photos)
for photo in photos:
yield photo
current += 1
if current >= total:
return