Add Guild.chunk and deprecated Client.request_offline_members
This commit is contained in:
parent
cb211c36bd
commit
009a961006
@ -379,6 +379,7 @@ class Client:
|
|||||||
print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
|
print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
@utils.deprecated('Guild.chunk')
|
||||||
async def request_offline_members(self, *guilds):
|
async def request_offline_members(self, *guilds):
|
||||||
r"""|coro|
|
r"""|coro|
|
||||||
|
|
||||||
@ -394,7 +395,7 @@ class Client:
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
This method is deprecated.
|
This method is deprecated. Use :meth:`Guild.chunk` instead.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
|
@ -2037,6 +2037,23 @@ class Guild(Hashable):
|
|||||||
|
|
||||||
return Widget(state=self._state, data=data)
|
return Widget(state=self._state, data=data)
|
||||||
|
|
||||||
|
async def chunk(self, *, cache=True):
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Requests all members that belong to this guild. In order to use this,
|
||||||
|
:meth:`Intents.members` must be enabled.
|
||||||
|
|
||||||
|
This is a websocket operation and can be slow.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
cache: :class:`bool`
|
||||||
|
Whether to cache the members as well.
|
||||||
|
"""
|
||||||
|
return await self._state.chunk_guild(self, cache=cache)
|
||||||
|
|
||||||
async def query_members(self, query=None, *, limit=5, user_ids=None, cache=True):
|
async def query_members(self, query=None, *, limit=5, user_ids=None, cache=True):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
@ -2049,16 +2066,15 @@ class Guild(Hashable):
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
query: :class:`str`
|
query: Optional[:class:`str`]
|
||||||
The string that the username's start with. An empty string
|
The string that the username's start with.
|
||||||
requests all members.
|
|
||||||
limit: :class:`int`
|
limit: :class:`int`
|
||||||
The maximum number of members to send back. This must be
|
The maximum number of members to send back. This must be
|
||||||
a number between 1 and 100.
|
a number between 5 and 100.
|
||||||
cache: :class:`bool`
|
cache: :class:`bool`
|
||||||
Whether to cache the members internally. This makes operations
|
Whether to cache the members internally. This makes operations
|
||||||
such as :meth:`get_member` work for those that matched.
|
such as :meth:`get_member` work for those that matched.
|
||||||
user_ids: List[:class:`int`]
|
user_ids: Optional[List[:class:`int`]]
|
||||||
List of user IDs to search for. If the user ID is not in the guild then it won't be returned.
|
List of user IDs to search for. If the user ID is not in the guild then it won't be returned.
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
|
@ -333,6 +333,7 @@ class AutoShardedClient(Client):
|
|||||||
"""Mapping[int, :class:`ShardInfo`]: Returns a mapping of shard IDs to their respective info object."""
|
"""Mapping[int, :class:`ShardInfo`]: Returns a mapping of shard IDs to their respective info object."""
|
||||||
return { shard_id: ShardInfo(parent, self.shard_count) for shard_id, parent in self.__shards.items() }
|
return { shard_id: ShardInfo(parent, self.shard_count) for shard_id, parent in self.__shards.items() }
|
||||||
|
|
||||||
|
@utils.deprecated('Guild.chunk')
|
||||||
async def request_offline_members(self, *guilds):
|
async def request_offline_members(self, *guilds):
|
||||||
r"""|coro|
|
r"""|coro|
|
||||||
|
|
||||||
@ -348,7 +349,7 @@ class AutoShardedClient(Client):
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
This method is deprecated.
|
This method is deprecated. Use :meth:`Guild.chunk` instead.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
|
@ -57,12 +57,28 @@ from .object import Object
|
|||||||
from .invite import Invite
|
from .invite import Invite
|
||||||
|
|
||||||
class ChunkRequest:
|
class ChunkRequest:
|
||||||
__slots__ = ('guild_id', 'nonce', 'future')
|
def __init__(self, guild_id, future, resolver, *, cache=True):
|
||||||
|
|
||||||
def __init__(self, guild_id, future):
|
|
||||||
self.guild_id = guild_id
|
self.guild_id = guild_id
|
||||||
|
self.resolver = resolver
|
||||||
|
self.cache = cache
|
||||||
self.nonce = os.urandom(16).hex()
|
self.nonce = os.urandom(16).hex()
|
||||||
self.future = future
|
self.future = future
|
||||||
|
self.buffer = [] # List[Member]
|
||||||
|
|
||||||
|
def add_members(self, members):
|
||||||
|
self.buffer.extend(members)
|
||||||
|
if self.cache:
|
||||||
|
guild = self.resolver(self.guild_id)
|
||||||
|
if guild is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
for member in members:
|
||||||
|
existing = guild.get_member(member.id)
|
||||||
|
if existing is None or existing.joined_at is None:
|
||||||
|
guild._add_member(member)
|
||||||
|
|
||||||
|
def done(self):
|
||||||
|
self.future.set_result(self.buffer)
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -150,7 +166,7 @@ class ConnectionState:
|
|||||||
# to reconnect loops which cause mass allocations and deallocations.
|
# to reconnect loops which cause mass allocations and deallocations.
|
||||||
gc.collect()
|
gc.collect()
|
||||||
|
|
||||||
def process_chunk_requests(self, guild_id, nonce, members):
|
def process_chunk_requests(self, guild_id, nonce, members, complete):
|
||||||
removed = []
|
removed = []
|
||||||
for i, request in enumerate(self._chunk_requests):
|
for i, request in enumerate(self._chunk_requests):
|
||||||
future = request.future
|
future = request.future
|
||||||
@ -159,8 +175,10 @@ class ConnectionState:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if request.guild_id == guild_id and request.nonce == nonce:
|
if request.guild_id == guild_id and request.nonce == nonce:
|
||||||
future.set_result(members)
|
request.add_members(members)
|
||||||
removed.append(i)
|
if complete:
|
||||||
|
request.done()
|
||||||
|
removed.append(i)
|
||||||
|
|
||||||
for index in reversed(removed):
|
for index in reversed(removed):
|
||||||
del self._chunk_requests[index]
|
del self._chunk_requests[index]
|
||||||
@ -324,19 +342,13 @@ class ConnectionState:
|
|||||||
raise RuntimeError('Somehow do not have a websocket for this guild_id')
|
raise RuntimeError('Somehow do not have a websocket for this guild_id')
|
||||||
|
|
||||||
future = self.loop.create_future()
|
future = self.loop.create_future()
|
||||||
request = ChunkRequest(guild.id, future)
|
request = ChunkRequest(guild.id, future, self._get_guild, cache=cache)
|
||||||
self._chunk_requests.append(request)
|
self._chunk_requests.append(request)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# start the query operation
|
# start the query operation
|
||||||
await ws.request_chunks(guild_id, query=query, limit=limit, user_ids=user_ids, nonce=request.nonce)
|
await ws.request_chunks(guild_id, query=query, limit=limit, user_ids=user_ids, nonce=request.nonce)
|
||||||
members = await asyncio.wait_for(future, timeout=30.0)
|
return await asyncio.wait_for(future, timeout=30.0)
|
||||||
|
|
||||||
if cache:
|
|
||||||
for member in members:
|
|
||||||
guild._add_member(member)
|
|
||||||
|
|
||||||
return members
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
log.warning('Timed out waiting for chunks with query %r and limit %d for guild_id %d', query, limit, guild_id)
|
log.warning('Timed out waiting for chunks with query %r and limit %d for guild_id %d', query, limit, guild_id)
|
||||||
raise
|
raise
|
||||||
@ -741,9 +753,10 @@ class ConnectionState:
|
|||||||
|
|
||||||
return self._add_guild_from_data(data)
|
return self._add_guild_from_data(data)
|
||||||
|
|
||||||
async def chunk_guild(self, guild, *, wait=True):
|
async def chunk_guild(self, guild, *, wait=True, cache=None):
|
||||||
|
cache = cache or self._cache_members
|
||||||
future = self.loop.create_future()
|
future = self.loop.create_future()
|
||||||
request = ChunkRequest(guild.id, future)
|
request = ChunkRequest(guild.id, future, self._get_guild, cache=cache)
|
||||||
self._chunk_requests.append(request)
|
self._chunk_requests.append(request)
|
||||||
await self.chunker(guild.id, nonce=request.nonce)
|
await self.chunker(guild.id, nonce=request.nonce)
|
||||||
if wait:
|
if wait:
|
||||||
@ -887,14 +900,8 @@ class ConnectionState:
|
|||||||
guild = self._get_guild(guild_id)
|
guild = self._get_guild(guild_id)
|
||||||
members = [Member(guild=guild, data=member, state=self) for member in data.get('members', [])]
|
members = [Member(guild=guild, data=member, state=self) for member in data.get('members', [])]
|
||||||
log.debug('Processed a chunk for %s members in guild ID %s.', len(members), guild_id)
|
log.debug('Processed a chunk for %s members in guild ID %s.', len(members), guild_id)
|
||||||
if self._cache_members:
|
complete = data.get('chunk_index', 0) + 1 == data.get('chunk_count')
|
||||||
for member in members:
|
self.process_chunk_requests(guild_id, data.get('nonce'), members, complete)
|
||||||
existing = guild.get_member(member.id)
|
|
||||||
if existing is None or existing.joined_at is None:
|
|
||||||
guild._add_member(member)
|
|
||||||
|
|
||||||
if data.get('chunk_index', 0) + 1 == data.get('chunk_count'):
|
|
||||||
self.process_chunk_requests(guild_id, data.get('nonce'), members)
|
|
||||||
|
|
||||||
def parse_guild_integrations_update(self, data):
|
def parse_guild_integrations_update(self, data):
|
||||||
guild = self._get_guild(int(data['guild_id']))
|
guild = self._get_guild(int(data['guild_id']))
|
||||||
@ -1069,7 +1076,7 @@ class AutoShardedConnectionState(ConnectionState):
|
|||||||
current_bucket.append(future)
|
current_bucket.append(future)
|
||||||
else:
|
else:
|
||||||
future = self.loop.create_future()
|
future = self.loop.create_future()
|
||||||
future.set_result(True)
|
future.set_result([])
|
||||||
|
|
||||||
processed.append((guild, future))
|
processed.append((guild, future))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user