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_members
get_chat_members_count
iter_chat_members
get_dialogs
iter_dialogs
get_dialogs_count

View File

@ -25,69 +25,90 @@ from pyrogram import raw, types, enums
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:
async def get_chat_members(
self: "pyrogram.Client",
chat_id: Union[int, str],
offset: int = 0,
limit: int = 200,
query: str = "",
filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.ANY
limit: int = 0,
filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.SEARCH
) -> 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.
You must be admin to retrieve the members list of a channel (also known as "subscribers").
For a more convenient way of getting chat members see :meth:`~pyrogram.Client.iter_chat_members`.
Requires administrator rights in channels.
Parameters:
chat_id (``int`` | ``str``):
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 string to filter members based on their display names and usernames.
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
and channels. It can be any of the followings:
*"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"*.
and channels.
Returns:
List of :obj:`~pyrogram.types.ChatMember`: On success, a list of chat members is returned.
Raises:
ValueError: In case you used an invalid filter or a chat id that belongs to a user.
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.ChatMember` objects is returned.
Example:
.. code-block:: python
# Get first 200 recent members
app.get_chat_members(chat_id)
from pyrogram import enums
# Get all administrators
app.get_chat_members(chat_id, filter="administrators")
# Get members
for member in app.get_chat_members(chat_id):
print(member)
# Get all bots
app.get_chat_members(chat_id, filter="bots")
# Get administrators
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)
@ -101,40 +122,35 @@ class GetChatMembers:
members = getattr(r.full_chat.participants, "participants", [])
users = {i.id: i for i in r.users}
return types.List(types.ChatMember._parse(self, member, users, {}) for member in members)
elif isinstance(peer, raw.types.InputPeerChannel):
filter = filter.lower()
for member in members:
yield types.ChatMember._parse(self, member, users, {})
if filter == enums.ChatMembersFilter.ANY:
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}"')
return
r = await self.invoke(
raw.functions.channels.GetParticipants(
channel=peer,
filter=filter,
offset=offset,
limit=limit,
hash=0
),
sleep_threshold=60
current = 0
offset = 0
total = abs(limit) or (1 << 31) - 1
limit = min(200, total)
while True:
members = await get_chunk(
client=self,
chat_id=chat_id,
offset=offset,
filter=filter,
limit=limit,
query=query
)
members = r.participants
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
if not members:
return
return types.List(types.ChatMember._parse(self, member, users, chats) for member in members)
else:
raise ValueError(f'The chat_id "{chat_id}" belongs to a user')
offset += len(members)
for member in members:
yield member
current += 1
if current >= total:
return