mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-03-03 19:00:21 +03:00
Invoke multiple getParticipant's at the same time (#580)
This commit is contained in:
parent
057c6a0b12
commit
3afd7dca84
|
@ -1033,9 +1033,9 @@ class TelegramClient(TelegramBareClient):
|
||||||
aggressive (:obj:`bool`, optional):
|
aggressive (:obj:`bool`, optional):
|
||||||
Aggressively looks for all participants in the chat in
|
Aggressively looks for all participants in the chat in
|
||||||
order to get more than 10,000 members (a hard limit
|
order to get more than 10,000 members (a hard limit
|
||||||
imposed by Telegram). Note that this might make over
|
imposed by Telegram). Note that this might take a long
|
||||||
20 times more requests and take over 5 minutes in some
|
time (over 5 minutes), but is able to return over 90,000
|
||||||
cases, but often returns well over 10,000 members.
|
participants on groups with 100,000 members.
|
||||||
|
|
||||||
This has no effect for groups or channels with less than
|
This has no effect for groups or channels with less than
|
||||||
10,000 members.
|
10,000 members.
|
||||||
|
@ -1053,31 +1053,49 @@ class TelegramClient(TelegramBareClient):
|
||||||
|
|
||||||
all_participants = {}
|
all_participants = {}
|
||||||
if total > 10000 and aggressive:
|
if total > 10000 and aggressive:
|
||||||
searches = tuple(chr(x) for x in range(ord('a'), ord('z') + 1))
|
requests = [GetParticipantsRequest(
|
||||||
else:
|
|
||||||
searches = ('',)
|
|
||||||
|
|
||||||
for extra_search in searches:
|
|
||||||
req = GetParticipantsRequest(
|
|
||||||
channel=entity,
|
channel=entity,
|
||||||
filter=ChannelParticipantsSearch(search + extra_search),
|
filter=ChannelParticipantsSearch(search + chr(x)),
|
||||||
offset=0,
|
offset=0,
|
||||||
limit=0,
|
limit=200,
|
||||||
hash=0
|
hash=0
|
||||||
)
|
) for x in range(ord('a'), ord('z') + 1)]
|
||||||
while True:
|
else:
|
||||||
req.limit = min(limit - req.offset, 200)
|
requests = [GetParticipantsRequest(
|
||||||
participants = self(req)
|
channel=entity,
|
||||||
if not participants.users:
|
filter=ChannelParticipantsSearch(search),
|
||||||
|
offset=0,
|
||||||
|
limit=200,
|
||||||
|
hash=0
|
||||||
|
)]
|
||||||
|
|
||||||
|
while requests:
|
||||||
|
# Only care about the limit for the first request
|
||||||
|
# (small amount of people, won't be aggressive).
|
||||||
|
#
|
||||||
|
# Most people won't care about getting exactly 12,345
|
||||||
|
# members so it doesn't really matter not to be 100%
|
||||||
|
# precise with being out of the offset/limit here.
|
||||||
|
requests[0].limit = min(limit - requests[0].offset, 200)
|
||||||
|
if requests[0].offset > limit:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
results = self(*requests)
|
||||||
|
for i in reversed(range(len(requests))):
|
||||||
|
participants = results[i]
|
||||||
|
if not participants.users:
|
||||||
|
requests.pop(i)
|
||||||
|
else:
|
||||||
|
requests[i].offset += len(participants.users)
|
||||||
for user in participants.users:
|
for user in participants.users:
|
||||||
if len(all_participants) < limit:
|
if len(all_participants) < limit:
|
||||||
all_participants[user.id] = user
|
all_participants[user.id] = user
|
||||||
req.offset += len(participants.users)
|
if limit < float('inf'):
|
||||||
if req.offset > limit:
|
values = all_participants.values()
|
||||||
break
|
else:
|
||||||
|
values = itertools.islice(all_participants.values(), limit)
|
||||||
|
|
||||||
users = UserList(all_participants.values())
|
users = UserList(values)
|
||||||
users.total = total
|
users.total = total
|
||||||
elif isinstance(entity, InputPeerChat):
|
elif isinstance(entity, InputPeerChat):
|
||||||
users = self(GetFullChatRequest(entity.chat_id)).users
|
users = self(GetFullChatRequest(entity.chat_id)).users
|
||||||
|
|
Loading…
Reference in New Issue
Block a user