Skip to content

Commit 405528c

Browse files
committed
Revamp get_chat_members related methods
1 parent 84f0b3a commit 405528c

2 files changed

Lines changed: 86 additions & 71 deletions

File tree

compiler/docs/compiler.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ def get_title_list(s: str) -> list:
209209
get_chat_member
210210
get_chat_members
211211
get_chat_members_count
212-
iter_chat_members
213212
get_dialogs
214213
iter_dialogs
215214
get_dialogs_count

pyrogram/methods/chats/get_chat_members.py

Lines changed: 86 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -25,69 +25,90 @@
2525
log = logging.getLogger(__name__)
2626

2727

28+
async def get_chunk(
29+
client: "pyrogram.Client",
30+
chat_id: Union[int, str],
31+
offset: int,
32+
filter: "enums.ChatMembersFilter",
33+
limit: int,
34+
query: str,
35+
):
36+
is_queryable = filter in [enums.ChatMembersFilter.SEARCH,
37+
enums.ChatMembersFilter.BANNED,
38+
enums.ChatMembersFilter.RESTRICTED]
39+
40+
filter = filter.value(q=query) if is_queryable else filter.value()
41+
42+
r = await client.invoke(
43+
raw.functions.channels.GetParticipants(
44+
channel=await client.resolve_peer(chat_id),
45+
filter=filter,
46+
offset=offset,
47+
limit=limit,
48+
hash=0
49+
),
50+
sleep_threshold=60
51+
)
52+
53+
members = r.participants
54+
users = {u.id: u for u in r.users}
55+
chats = {c.id: c for c in r.chats}
56+
57+
return [types.ChatMember._parse(client, member, users, chats) for member in members]
58+
59+
2860
class GetChatMembers:
2961
async def get_chat_members(
3062
self: "pyrogram.Client",
3163
chat_id: Union[int, str],
32-
offset: int = 0,
33-
limit: int = 200,
3464
query: str = "",
35-
filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.ANY
65+
limit: int = 0,
66+
filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.SEARCH
3667
) -> List["types.ChatMember"]:
37-
"""Get a chunk of the members list of a chat.
68+
"""Get the members list of a chat.
3869
39-
You can get up to 200 chat members at once.
4070
A chat can be either a basic group, a supergroup or a channel.
41-
You must be admin to retrieve the members list of a channel (also known as "subscribers").
42-
For a more convenient way of getting chat members see :meth:`~pyrogram.Client.iter_chat_members`.
71+
Requires administrator rights in channels.
4372
4473
Parameters:
4574
chat_id (``int`` | ``str``):
4675
Unique identifier (int) or username (str) of the target chat.
4776
48-
offset (``int``, *optional*):
49-
Sequential number of the first member to be returned.
50-
Only applicable to supergroups and channels. Defaults to 0.
51-
52-
limit (``int``, *optional*):
53-
Limits the number of members to be retrieved.
54-
Only applicable to supergroups and channels.
55-
Defaults to 200.
56-
5777
query (``str``, *optional*):
5878
Query string to filter members based on their display names and usernames.
5979
Only applicable to supergroups and channels. Defaults to "" (empty string).
60-
A query string is applicable only for *"all"*, *"banned"* and *"restricted"* filters only
80+
A query string is applicable only for :obj:`~pyrogram.enums.ChatMembersFilter.SEARCH`,
81+
:obj:`~pyrogram.enums.ChatMembersFilter.BANNED` and :obj:`~pyrogram.enums.ChatMembersFilter.RESTRICTED`
82+
filters only.
83+
84+
limit (``int``, *optional*):
85+
Limits the number of members to be retrieved.
6186
62-
filter (``str``, *optional*):
87+
filter (:obj:`~pyrogram.enums.ChatMembersFilter`, *optional*):
6388
Filter used to select the kind of members you want to retrieve. Only applicable for supergroups
64-
and channels. It can be any of the followings:
65-
*"all"* - all kind of members,
66-
*"banned"* - banned members only,
67-
*"restricted"* - restricted members only,
68-
*"bots"* - bots only,
69-
*"recent"* - recent members only,
70-
*"administrators"* - chat administrators only.
71-
Only applicable to supergroups and channels.
72-
Defaults to *"recent"*.
89+
and channels.
7390
7491
Returns:
75-
List of :obj:`~pyrogram.types.ChatMember`: On success, a list of chat members is returned.
76-
77-
Raises:
78-
ValueError: In case you used an invalid filter or a chat id that belongs to a user.
92+
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.ChatMember` objects is returned.
7993
8094
Example:
8195
.. code-block:: python
8296
83-
# Get first 200 recent members
84-
app.get_chat_members(chat_id)
97+
from pyrogram import enums
98+
99+
# Get members
100+
for member in app.get_chat_members(chat_id):
101+
print(member)
85102
86-
# Get all administrators
87-
app.get_chat_members(chat_id, filter="administrators")
103+
# Get administrators
104+
administrators = list(app.get_chat_members(
105+
chat_id,
106+
filter=enums.ChatMembersFilter.ADMINISTRATORS))
88107
89-
# Get all bots
90-
app.get_chat_members(chat_id, filter="bots")
108+
# Get bots
109+
bots = list(app.get_chat_members(
110+
chat_id,
111+
filter=enums.ChatMembersFilter.BOTS))
91112
"""
92113
peer = await self.resolve_peer(chat_id)
93114

@@ -101,40 +122,35 @@ async def get_chat_members(
101122
members = getattr(r.full_chat.participants, "participants", [])
102123
users = {i.id: i for i in r.users}
103124

104-
return types.List(types.ChatMember._parse(self, member, users, {}) for member in members)
105-
elif isinstance(peer, raw.types.InputPeerChannel):
106-
filter = filter.lower()
107-
108-
if filter == enums.ChatMembersFilter.ANY:
109-
filter = raw.types.ChannelParticipantsSearch(q=query)
110-
elif filter == enums.ChatMembersFilter.BANNED:
111-
filter = raw.types.ChannelParticipantsKicked(q=query)
112-
elif filter == enums.ChatMembersFilter.RESTRICTED:
113-
filter = raw.types.ChannelParticipantsBanned(q=query)
114-
elif filter == enums.ChatMembersFilter.BOTS:
115-
filter = raw.types.ChannelParticipantsBots()
116-
elif filter == enums.ChatMembersFilter.RECENT:
117-
filter = raw.types.ChannelParticipantsRecent()
118-
elif filter == enums.ChatMembersFilter.ADMINISTRATORS:
119-
filter = raw.types.ChannelParticipantsAdmins()
120-
else:
121-
raise ValueError(f'Invalid filter "{filter}"')
125+
for member in members:
126+
yield types.ChatMember._parse(self, member, users, {})
122127

123-
r = await self.invoke(
124-
raw.functions.channels.GetParticipants(
125-
channel=peer,
126-
filter=filter,
127-
offset=offset,
128-
limit=limit,
129-
hash=0
130-
),
131-
sleep_threshold=60
128+
return
129+
130+
current = 0
131+
offset = 0
132+
total = abs(limit) or (1 << 31) - 1
133+
limit = min(200, total)
134+
135+
while True:
136+
members = await get_chunk(
137+
client=self,
138+
chat_id=chat_id,
139+
offset=offset,
140+
filter=filter,
141+
limit=limit,
142+
query=query
132143
)
133144

134-
members = r.participants
135-
users = {i.id: i for i in r.users}
136-
chats = {i.id: i for i in r.chats}
145+
if not members:
146+
return
147+
148+
offset += len(members)
149+
150+
for member in members:
151+
yield member
152+
153+
current += 1
137154

138-
return types.List(types.ChatMember._parse(self, member, users, chats) for member in members)
139-
else:
140-
raise ValueError(f'The chat_id "{chat_id}" belongs to a user')
155+
if current >= total:
156+
return

0 commit comments

Comments
 (0)