Browse Source

Implement presences for `Guild.query_members`

pull/6232/head
Nadir Chowdhury 4 years ago
committed by GitHub
parent
commit
59c11e71a2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      discord/gateway.py
  2. 17
      discord/guild.py
  3. 23
      discord/state.py

3
discord/gateway.py

@ -636,11 +636,12 @@ class DiscordWebSocket:
} }
await self.send_as_json(payload) await self.send_as_json(payload)
async def request_chunks(self, guild_id, query=None, *, limit, user_ids=None, nonce=None): async def request_chunks(self, guild_id, query=None, *, limit, user_ids=None, presences, nonce=None):
payload = { payload = {
'op': self.REQUEST_MEMBERS, 'op': self.REQUEST_MEMBERS,
'd': { 'd': {
'guild_id': guild_id, 'guild_id': guild_id,
'presences': presences,
'limit': limit 'limit': limit
} }
} }

17
discord/guild.py

@ -2108,7 +2108,7 @@ class Guild(Hashable):
return await self._state.chunk_guild(self, cache=cache) 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, presences=False, cache=True):
"""|coro| """|coro|
Request members that belong to this guild whose username starts with Request members that belong to this guild whose username starts with
@ -2125,6 +2125,12 @@ class Guild(Hashable):
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 5 and 100. a number between 5 and 100.
presences: :class:`bool`
Whether to request for presences to be provided. This defaults
to ``False``.
.. versionadded:: 1.6
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.
@ -2140,6 +2146,8 @@ class Guild(Hashable):
The query timed out waiting for the members. The query timed out waiting for the members.
ValueError ValueError
Invalid parameters were passed to the function Invalid parameters were passed to the function
ClientException
The presences intent is not enabled.
Returns Returns
-------- --------
@ -2147,6 +2155,9 @@ class Guild(Hashable):
The list of members that have matched the query. The list of members that have matched the query.
""" """
if presences and not self._state._intents.presences:
raise ClientException('Intents.presences must be enabled to use this.')
if query is None: if query is None:
if query == '': if query == '':
raise ValueError('Cannot pass empty query string.') raise ValueError('Cannot pass empty query string.')
@ -2156,9 +2167,9 @@ class Guild(Hashable):
if user_ids is not None and query is not None: if user_ids is not None and query is not None:
raise ValueError('Cannot pass both query and user_ids') raise ValueError('Cannot pass both query and user_ids')
limit = min(100, limit or 5) limit = min(100, limit or 5)
return await self._state.query_members(self, query=query, limit=limit, user_ids=user_ids, cache=cache) return await self._state.query_members(self, query=query, limit=limit, user_ids=user_ids, presences=presences, cache=cache)
async def change_voice_state(self, *, channel, self_mute=False, self_deaf=False): async def change_voice_state(self, *, channel, self_mute=False, self_deaf=False):
"""|coro| """|coro|

23
discord/state.py

@ -382,11 +382,11 @@ class ConnectionState:
return channel or Object(id=channel_id), guild return channel or Object(id=channel_id), guild
async def chunker(self, guild_id, query='', limit=0, *, nonce=None): async def chunker(self, guild_id, query='', limit=0, presences=False, *, nonce=None):
ws = self._get_websocket(guild_id) # This is ignored upstream ws = self._get_websocket(guild_id) # This is ignored upstream
await ws.request_chunks(guild_id, query=query, limit=limit, nonce=nonce) await ws.request_chunks(guild_id, query=query, limit=limit, presences=presences, nonce=nonce)
async def query_members(self, guild, query, limit, user_ids, cache): async def query_members(self, guild, query, limit, user_ids, cache, presences):
guild_id = guild.id guild_id = guild.id
ws = self._get_websocket(guild_id) ws = self._get_websocket(guild_id)
if ws is None: if ws is None:
@ -397,7 +397,7 @@ class ConnectionState:
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, presences=presences, nonce=request.nonce)
return await asyncio.wait_for(request.wait(), timeout=30.0) return await asyncio.wait_for(request.wait(), timeout=30.0)
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)
@ -967,8 +967,19 @@ class ConnectionState:
def parse_guild_members_chunk(self, data): def parse_guild_members_chunk(self, data):
guild_id = int(data['guild_id']) guild_id = int(data['guild_id'])
guild = self._get_guild(guild_id) guild = self._get_guild(guild_id)
presences = data.get('presences', [])
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 presences:
member_dict = {str(member.id): member for member in members}
for presence in presences:
user = presence['user']
member_id = user['id']
member = member_dict.get(member_id)
member._presence_update(presence, user)
complete = data.get('chunk_index', 0) + 1 == data.get('chunk_count') complete = data.get('chunk_index', 0) + 1 == data.get('chunk_count')
self.process_chunk_requests(guild_id, data.get('nonce'), members, complete) self.process_chunk_requests(guild_id, data.get('nonce'), members, complete)
@ -1121,9 +1132,9 @@ class AutoShardedConnectionState(ConnectionState):
channel = new_guild.get_channel(channel_id) or Object(id=channel_id) channel = new_guild.get_channel(channel_id) or Object(id=channel_id)
msg._rebind_channel_reference(channel) msg._rebind_channel_reference(channel)
async def chunker(self, guild_id, query='', limit=0, *, shard_id=None, nonce=None): async def chunker(self, guild_id, query='', limit=0, presences=False, *, shard_id=None, nonce=None):
ws = self._get_websocket(guild_id, shard_id=shard_id) ws = self._get_websocket(guild_id, shard_id=shard_id)
await ws.request_chunks(guild_id, query=query, limit=limit, nonce=nonce) await ws.request_chunks(guild_id, query=query, limit=limit, presences=presences, nonce=nonce)
async def _delay_ready(self): async def _delay_ready(self):
await self.shards_launched.wait() await self.shards_launched.wait()

Loading…
Cancel
Save