mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-22 01:16:35 +03:00
Ignore aggressive parameter in iter_participants
It's broken (it causes flood wait immediately). Closes #3787.
This commit is contained in:
parent
e6ebe6b334
commit
d7424ccb90
|
@ -97,7 +97,7 @@ class _ChatAction:
|
||||||
|
|
||||||
|
|
||||||
class _ParticipantsIter(RequestIter):
|
class _ParticipantsIter(RequestIter):
|
||||||
async def _init(self, entity, filter, search, aggressive):
|
async def _init(self, entity, filter, search):
|
||||||
if isinstance(filter, type):
|
if isinstance(filter, type):
|
||||||
if filter in (types.ChannelParticipantsBanned,
|
if filter in (types.ChannelParticipantsBanned,
|
||||||
types.ChannelParticipantsKicked,
|
types.ChannelParticipantsKicked,
|
||||||
|
@ -122,7 +122,8 @@ class _ParticipantsIter(RequestIter):
|
||||||
self.filter_entity = lambda ent: True
|
self.filter_entity = lambda ent: True
|
||||||
|
|
||||||
# Only used for channels, but we should always set the attribute
|
# Only used for channels, but we should always set the attribute
|
||||||
self.requests = []
|
# Called `requests` even though it's just one for legacy purposes.
|
||||||
|
self.requests = None
|
||||||
|
|
||||||
if ty == helpers._EntityType.CHANNEL:
|
if ty == helpers._EntityType.CHANNEL:
|
||||||
if self.limit <= 0:
|
if self.limit <= 0:
|
||||||
|
@ -133,22 +134,13 @@ class _ParticipantsIter(RequestIter):
|
||||||
raise StopAsyncIteration
|
raise StopAsyncIteration
|
||||||
|
|
||||||
self.seen = set()
|
self.seen = set()
|
||||||
if aggressive and not filter:
|
self.requests = functions.channels.GetParticipantsRequest(
|
||||||
self.requests.extend(functions.channels.GetParticipantsRequest(
|
channel=entity,
|
||||||
channel=entity,
|
filter=filter or types.ChannelParticipantsSearch(search),
|
||||||
filter=types.ChannelParticipantsSearch(x),
|
offset=0,
|
||||||
offset=0,
|
limit=_MAX_PARTICIPANTS_CHUNK_SIZE,
|
||||||
limit=_MAX_PARTICIPANTS_CHUNK_SIZE,
|
hash=0
|
||||||
hash=0
|
)
|
||||||
) for x in (search or string.ascii_lowercase))
|
|
||||||
else:
|
|
||||||
self.requests.append(functions.channels.GetParticipantsRequest(
|
|
||||||
channel=entity,
|
|
||||||
filter=filter or types.ChannelParticipantsSearch(search),
|
|
||||||
offset=0,
|
|
||||||
limit=_MAX_PARTICIPANTS_CHUNK_SIZE,
|
|
||||||
hash=0
|
|
||||||
))
|
|
||||||
|
|
||||||
elif ty == helpers._EntityType.CHAT:
|
elif ty == helpers._EntityType.CHAT:
|
||||||
full = await self.client(
|
full = await self.client(
|
||||||
|
@ -190,21 +182,14 @@ class _ParticipantsIter(RequestIter):
|
||||||
if not self.requests:
|
if not self.requests:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Only care about the limit for the first request
|
self.requests.limit = min(self.limit - self.requests.offset, _MAX_PARTICIPANTS_CHUNK_SIZE)
|
||||||
# (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.
|
|
||||||
self.requests[0].limit = min(
|
|
||||||
self.limit - self.requests[0].offset, _MAX_PARTICIPANTS_CHUNK_SIZE)
|
|
||||||
|
|
||||||
if self.requests[0].offset > self.limit:
|
if self.requests.offset > self.limit:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if self.total is None:
|
if self.total is None:
|
||||||
f = self.requests[0].filter
|
f = self.requests.filter
|
||||||
if len(self.requests) > 1 or (
|
if (
|
||||||
not isinstance(f, types.ChannelParticipantsRecent)
|
not isinstance(f, types.ChannelParticipantsRecent)
|
||||||
and (not isinstance(f, types.ChannelParticipantsSearch) or f.q)
|
and (not isinstance(f, types.ChannelParticipantsSearch) or f.q)
|
||||||
):
|
):
|
||||||
|
@ -212,42 +197,40 @@ class _ParticipantsIter(RequestIter):
|
||||||
# if there's a filter which would reduce the real total number.
|
# if there's a filter which would reduce the real total number.
|
||||||
# getParticipants is cheaper than getFull.
|
# getParticipants is cheaper than getFull.
|
||||||
self.total = (await self.client(functions.channels.GetParticipantsRequest(
|
self.total = (await self.client(functions.channels.GetParticipantsRequest(
|
||||||
channel=self.requests[0].channel,
|
channel=self.requests.channel,
|
||||||
filter=types.ChannelParticipantsRecent(),
|
filter=types.ChannelParticipantsRecent(),
|
||||||
offset=0,
|
offset=0,
|
||||||
limit=1,
|
limit=1,
|
||||||
hash=0
|
hash=0
|
||||||
))).count
|
))).count
|
||||||
|
|
||||||
results = await self.client(self.requests)
|
participants = await self.client(self.requests)
|
||||||
for i in reversed(range(len(self.requests))):
|
if self.total is None:
|
||||||
participants = results[i]
|
# Will only get here if there was one request with a filter that matched all users.
|
||||||
if self.total is None:
|
self.total = participants.count
|
||||||
# Will only get here if there was one request with a filter that matched all users.
|
if not participants.users:
|
||||||
self.total = participants.count
|
self.requests = None
|
||||||
if not participants.users:
|
return
|
||||||
self.requests.pop(i)
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.requests[i].offset += len(participants.participants)
|
self.requests.offset += len(participants.participants)
|
||||||
users = {user.id: user for user in participants.users}
|
users = {user.id: user for user in participants.users}
|
||||||
for participant in participants.participants:
|
for participant in participants.participants:
|
||||||
|
|
||||||
if isinstance(participant, types.ChannelParticipantBanned):
|
if isinstance(participant, types.ChannelParticipantBanned):
|
||||||
if not isinstance(participant.peer, types.PeerUser):
|
if not isinstance(participant.peer, types.PeerUser):
|
||||||
# May have the entire channel banned. See #3105.
|
# May have the entire channel banned. See #3105.
|
||||||
continue
|
|
||||||
user_id = participant.peer.user_id
|
|
||||||
else:
|
|
||||||
user_id = participant.user_id
|
|
||||||
|
|
||||||
user = users[user_id]
|
|
||||||
if not self.filter_entity(user) or user.id in self.seen:
|
|
||||||
continue
|
continue
|
||||||
self.seen.add(user_id)
|
user_id = participant.peer.user_id
|
||||||
user = users[user_id]
|
else:
|
||||||
user.participant = participant
|
user_id = participant.user_id
|
||||||
self.buffer.append(user)
|
|
||||||
|
user = users[user_id]
|
||||||
|
if not self.filter_entity(user) or user.id in self.seen:
|
||||||
|
continue
|
||||||
|
self.seen.add(user_id)
|
||||||
|
user = users[user_id]
|
||||||
|
user.participant = participant
|
||||||
|
self.buffer.append(user)
|
||||||
|
|
||||||
|
|
||||||
class _AdminLogIter(RequestIter):
|
class _AdminLogIter(RequestIter):
|
||||||
|
@ -431,9 +414,6 @@ class ChatMethods:
|
||||||
search (`str`, optional):
|
search (`str`, optional):
|
||||||
Look for participants with this string in name/username.
|
Look for participants with this string in name/username.
|
||||||
|
|
||||||
If ``aggressive is True``, the symbols from this string will
|
|
||||||
be used.
|
|
||||||
|
|
||||||
filter (:tl:`ChannelParticipantsFilter`, optional):
|
filter (:tl:`ChannelParticipantsFilter`, optional):
|
||||||
The filter to be used, if you want e.g. only admins
|
The filter to be used, if you want e.g. only admins
|
||||||
Note that you might not have permissions for some filter.
|
Note that you might not have permissions for some filter.
|
||||||
|
@ -446,14 +426,11 @@ class ChatMethods:
|
||||||
use :tl:`ChannelParticipantsKicked` instead.
|
use :tl:`ChannelParticipantsKicked` instead.
|
||||||
|
|
||||||
aggressive (`bool`, optional):
|
aggressive (`bool`, optional):
|
||||||
Aggressively looks for all participants in the chat.
|
Does nothing. This is kept for backwards-compatibility.
|
||||||
|
|
||||||
This is useful for channels since 20 July 2018,
|
There have been several changes to Telegram's API that limits
|
||||||
Telegram added a server-side limit where only the
|
the amount of members that can be retrieved, and this was a
|
||||||
first 200 members can be retrieved. With this flag
|
hack that no longer works.
|
||||||
set, more than 200 will be often be retrieved.
|
|
||||||
|
|
||||||
This has no effect if a ``filter`` is given.
|
|
||||||
|
|
||||||
Yields
|
Yields
|
||||||
The :tl:`User` objects returned by :tl:`GetParticipantsRequest`
|
The :tl:`User` objects returned by :tl:`GetParticipantsRequest`
|
||||||
|
@ -482,8 +459,7 @@ class ChatMethods:
|
||||||
limit,
|
limit,
|
||||||
entity=entity,
|
entity=entity,
|
||||||
filter=filter,
|
filter=filter,
|
||||||
search=search,
|
search=search
|
||||||
aggressive=aggressive
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_participants(
|
async def get_participants(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user