aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNCPlayz <[email protected]>2019-06-08 00:15:39 +0100
committerRapptz <[email protected]>2019-06-29 19:14:19 -0400
commit851f83c821c560cff3feb206b5c48a48a961848a (patch)
tree6996c6f168cb0cb0664a5f26c2c8be176814078d
parentUse a new scorer to improve search results. (diff)
downloaddiscord.py-851f83c821c560cff3feb206b5c48a48a961848a.tar.xz
discord.py-851f83c821c560cff3feb206b5c48a48a961848a.zip
Implement `Guild.fetch_members`
Also implements `MemberIterator`.
-rw-r--r--discord/guild.py49
-rw-r--r--discord/http.py10
-rw-r--r--discord/iterators.py41
3 files changed, 99 insertions, 1 deletions
diff --git a/discord/guild.py b/discord/guild.py
index 2ea56d05..b706c905 100644
--- a/discord/guild.py
+++ b/discord/guild.py
@@ -41,7 +41,7 @@ from .enums import VoiceRegion, Status, ChannelType, try_enum, VerificationLevel
from .mixins import Hashable
from .user import User
from .invite import Invite
-from .iterators import AuditLogIterator
+from .iterators import AuditLogIterator, MemberIterator
from .webhook import Webhook
from .widget import Widget
from .asset import Asset
@@ -1152,6 +1152,53 @@ class Guild(Hashable):
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):
"""|coro|
diff --git a/discord/http.py b/discord/http.py
index 16b65717..17ca74db 100644
--- a/discord/http.py
+++ b/discord/http.py
@@ -621,6 +621,16 @@ class HTTPClient:
def get_all_guild_channels(self, 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):
return self.request(Route('GET', '/guilds/{guild_id}/members/{member_id}', guild_id=guild_id, member_id=member_id))
diff --git a/discord/iterators.py b/discord/iterators.py
index 17c11fbe..b2632574 100644
--- a/discord/iterators.py
+++ b/discord/iterators.py
@@ -587,3 +587,44 @@ class GuildIterator(_AsyncIterator):
self.limit -= retrieve
self.after = Object(id=int(data[0]['id']))
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)