Revamp get_chat_members related methods

This commit is contained in:
Dan 2022-04-24 11:56:07 +02:00
parent 84f0b3a97a
commit 405528c74b
2 changed files with 85 additions and 70 deletions

View File

@ -209,7 +209,6 @@ def pyrogram_api():
get_chat_member get_chat_member
get_chat_members get_chat_members
get_chat_members_count get_chat_members_count
iter_chat_members
get_dialogs get_dialogs
iter_dialogs iter_dialogs
get_dialogs_count get_dialogs_count

View File

@ -25,69 +25,90 @@ from pyrogram import raw, types, enums
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
async def get_chunk(
client: "pyrogram.Client",
chat_id: Union[int, str],
offset: int,
filter: "enums.ChatMembersFilter",
limit: int,
query: str,
):
is_queryable = filter in [enums.ChatMembersFilter.SEARCH,
enums.ChatMembersFilter.BANNED,
enums.ChatMembersFilter.RESTRICTED]
filter = filter.value(q=query) if is_queryable else filter.value()
r = await client.invoke(
raw.functions.channels.GetParticipants(
channel=await client.resolve_peer(chat_id),
filter=filter,
offset=offset,
limit=limit,
hash=0
),
sleep_threshold=60
)
members = r.participants
users = {u.id: u for u in r.users}
chats = {c.id: c for c in r.chats}
return [types.ChatMember._parse(client, member, users, chats) for member in members]
class GetChatMembers: class GetChatMembers:
async def get_chat_members( async def get_chat_members(
self: "pyrogram.Client", self: "pyrogram.Client",
chat_id: Union[int, str], chat_id: Union[int, str],
offset: int = 0,
limit: int = 200,
query: str = "", query: str = "",
filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.ANY limit: int = 0,
filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.SEARCH
) -> List["types.ChatMember"]: ) -> List["types.ChatMember"]:
"""Get a chunk of the members list of a chat. """Get the members list of a chat.
You can get up to 200 chat members at once.
A chat can be either a basic group, a supergroup or a channel. A chat can be either a basic group, a supergroup or a channel.
You must be admin to retrieve the members list of a channel (also known as "subscribers"). Requires administrator rights in channels.
For a more convenient way of getting chat members see :meth:`~pyrogram.Client.iter_chat_members`.
Parameters: Parameters:
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.
offset (``int``, *optional*):
Sequential number of the first member to be returned.
Only applicable to supergroups and channels. Defaults to 0.
limit (``int``, *optional*):
Limits the number of members to be retrieved.
Only applicable to supergroups and channels.
Defaults to 200.
query (``str``, *optional*): query (``str``, *optional*):
Query string to filter members based on their display names and usernames. Query string to filter members based on their display names and usernames.
Only applicable to supergroups and channels. Defaults to "" (empty string). Only applicable to supergroups and channels. Defaults to "" (empty string).
A query string is applicable only for *"all"*, *"banned"* and *"restricted"* filters only A query string is applicable only for :obj:`~pyrogram.enums.ChatMembersFilter.SEARCH`,
:obj:`~pyrogram.enums.ChatMembersFilter.BANNED` and :obj:`~pyrogram.enums.ChatMembersFilter.RESTRICTED`
filters only.
filter (``str``, *optional*): limit (``int``, *optional*):
Limits the number of members to be retrieved.
filter (:obj:`~pyrogram.enums.ChatMembersFilter`, *optional*):
Filter used to select the kind of members you want to retrieve. Only applicable for supergroups Filter used to select the kind of members you want to retrieve. Only applicable for supergroups
and channels. It can be any of the followings: and channels.
*"all"* - all kind of members,
*"banned"* - banned members only,
*"restricted"* - restricted members only,
*"bots"* - bots only,
*"recent"* - recent members only,
*"administrators"* - chat administrators only.
Only applicable to supergroups and channels.
Defaults to *"recent"*.
Returns: Returns:
List of :obj:`~pyrogram.types.ChatMember`: On success, a list of chat members is returned. ``Generator``: On success, a generator yielding :obj:`~pyrogram.types.ChatMember` objects is returned.
Raises:
ValueError: In case you used an invalid filter or a chat id that belongs to a user.
Example: Example:
.. code-block:: python .. code-block:: python
# Get first 200 recent members from pyrogram import enums
app.get_chat_members(chat_id)
# Get all administrators # Get members
app.get_chat_members(chat_id, filter="administrators") for member in app.get_chat_members(chat_id):
print(member)
# Get all bots # Get administrators
app.get_chat_members(chat_id, filter="bots") administrators = list(app.get_chat_members(
chat_id,
filter=enums.ChatMembersFilter.ADMINISTRATORS))
# Get bots
bots = list(app.get_chat_members(
chat_id,
filter=enums.ChatMembersFilter.BOTS))
""" """
peer = await self.resolve_peer(chat_id) peer = await self.resolve_peer(chat_id)
@ -101,40 +122,35 @@ class GetChatMembers:
members = getattr(r.full_chat.participants, "participants", []) members = getattr(r.full_chat.participants, "participants", [])
users = {i.id: i for i in r.users} users = {i.id: i for i in r.users}
return types.List(types.ChatMember._parse(self, member, users, {}) for member in members) for member in members:
elif isinstance(peer, raw.types.InputPeerChannel): yield types.ChatMember._parse(self, member, users, {})
filter = filter.lower()
if filter == enums.ChatMembersFilter.ANY: return
filter = raw.types.ChannelParticipantsSearch(q=query)
elif filter == enums.ChatMembersFilter.BANNED:
filter = raw.types.ChannelParticipantsKicked(q=query)
elif filter == enums.ChatMembersFilter.RESTRICTED:
filter = raw.types.ChannelParticipantsBanned(q=query)
elif filter == enums.ChatMembersFilter.BOTS:
filter = raw.types.ChannelParticipantsBots()
elif filter == enums.ChatMembersFilter.RECENT:
filter = raw.types.ChannelParticipantsRecent()
elif filter == enums.ChatMembersFilter.ADMINISTRATORS:
filter = raw.types.ChannelParticipantsAdmins()
else:
raise ValueError(f'Invalid filter "{filter}"')
r = await self.invoke( current = 0
raw.functions.channels.GetParticipants( offset = 0
channel=peer, total = abs(limit) or (1 << 31) - 1
filter=filter, limit = min(200, total)
offset=offset,
limit=limit, while True:
hash=0 members = await get_chunk(
), client=self,
sleep_threshold=60 chat_id=chat_id,
offset=offset,
filter=filter,
limit=limit,
query=query
) )
members = r.participants if not members:
users = {i.id: i for i in r.users} return
chats = {i.id: i for i in r.chats}
return types.List(types.ChatMember._parse(self, member, users, chats) for member in members) offset += len(members)
else:
raise ValueError(f'The chat_id "{chat_id}" belongs to a user') for member in members:
yield member
current += 1
if current >= total:
return