mirror of
https://github.com/TeamPGM/pyrogram.git
synced 2024-11-16 12:51:18 +00:00
Revamp get_chat_members related methods
This commit is contained in:
parent
84f0b3a97a
commit
405528c74b
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user