Browse Source

Implement `Guild.fetch_members`

Also implements `MemberIterator`.
pull/2255/head
NCPlayz 6 years ago
committed by Rapptz
parent
commit
851f83c821
  1. 49
      discord/guild.py
  2. 10
      discord/http.py
  3. 41
      discord/iterators.py

49
discord/guild.py

@ -41,7 +41,7 @@ from .enums import VoiceRegion, Status, ChannelType, try_enum, VerificationLevel
from .mixins import Hashable from .mixins import Hashable
from .user import User from .user import User
from .invite import Invite from .invite import Invite
from .iterators import AuditLogIterator from .iterators import AuditLogIterator, MemberIterator
from .webhook import Webhook from .webhook import Webhook
from .widget import Widget from .widget import Widget
from .asset import Asset from .asset import Asset
@ -1152,6 +1152,53 @@ class Guild(Hashable):
return [convert(d) for d in data] return [convert(d) for d in data]
def fetch_members(self, *, limit=1, after=None):
"""|coro|
Retrieves an :class:`.AsyncIterator` that enables receiving the guild's members.
.. note::
This method is an API call. For general usage, consider :attr:`members` instead.
.. versionadded:: 1.3.0
All parameters are optional.
Parameters
----------
limit: Optional[:class:`int`]
The number of members to retrieve.
Defaults to 1.
after: Optional[Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]]
Retrieve members after this date or object.
If a date is provided it must be a timezone-naive datetime representing UTC time.
Raises
------
HTTPException
Getting the members failed.
Yields
------
:class:`.Member`
The member with the member data parsed.
Examples
--------
Usage ::
async for member in guild.fetch_members(limit=150):
print(member.name)
Flattening into a list ::
members = await guild.fetch_members(limit=150).flatten()
# members is now a list of Member...
"""
return MemberIterator(self, limit=limit, after=after)
async def fetch_member(self, member_id): async def fetch_member(self, member_id):
"""|coro| """|coro|

10
discord/http.py

@ -621,6 +621,16 @@ class HTTPClient:
def get_all_guild_channels(self, guild_id): def get_all_guild_channels(self, guild_id):
return self.request(Route('GET', '/guilds/{guild_id}/channels', guild_id=guild_id)) return self.request(Route('GET', '/guilds/{guild_id}/channels', guild_id=guild_id))
def get_members(self, guild_id, limit, after):
params = {
'limit': limit,
}
if after:
params['after'] = after
r = Route('GET', '/guilds/{guild_id}/members', guild_id=guild_id)
return self.request(r, params=params)
def get_member(self, guild_id, member_id): def get_member(self, guild_id, member_id):
return self.request(Route('GET', '/guilds/{guild_id}/members/{member_id}', guild_id=guild_id, member_id=member_id)) return self.request(Route('GET', '/guilds/{guild_id}/members/{member_id}', guild_id=guild_id, member_id=member_id))

41
discord/iterators.py

@ -587,3 +587,44 @@ class GuildIterator(_AsyncIterator):
self.limit -= retrieve self.limit -= retrieve
self.after = Object(id=int(data[0]['id'])) self.after = Object(id=int(data[0]['id']))
return data return data
class MemberIterator(_AsyncIterator):
def __init__(self, guild, limit=1, after=None):
if isinstance(after, datetime.datetime):
after = Object(id=time_snowflake(after, high=True))
self.guild = guild
self.limit = limit
self.after = after or OLDEST_OBJECT
self.state = self.guild._state
self.get_members = self.state.http.get_members
self.members = asyncio.Queue(loop=self.state.loop)
async def next(self):
if self.members.empty():
await self.fill_members()
try:
return self.members.get_nowait()
except asyncio.QueueEmpty:
raise NoMoreItems()
async def fill_members(self):
if self.limit > 0:
retrieve = self.limit if self.limit <= 1000 else 1000
after = self.after.id if self.after else None
data = await self.get_members(self.guild.id, retrieve, after)
if data:
self.limit -= retrieve
self.after = Object(id=int(data[-1]['user']['id']))
for element in reversed(data):
await self.members.put(self.create_member(element))
def create_member(self, data):
from .member import Member
return Member(data=data, guild=self.guild, state=self.state)

Loading…
Cancel
Save