aboutsummaryrefslogtreecommitdiff
path: root/discord/iterators.py
diff options
context:
space:
mode:
authorNCPlayz <[email protected]>2019-03-14 12:38:02 +0000
committerRapptz <[email protected]>2019-03-19 09:00:18 -0400
commitf507f508a2aa56305ac90bd222f49af9cf47c49b (patch)
treea9ba58dde45156651f76196c06514a622e7fa6a8 /discord/iterators.py
parentOrganise documentation (diff)
downloaddiscord.py-f507f508a2aa56305ac90bd222f49af9cf47c49b.tar.xz
discord.py-f507f508a2aa56305ac90bd222f49af9cf47c49b.zip
Expose Metadata
Added access to: * `/users/@me/guilds` * `/guilds/{guild_id}` * `/guilds/{guild_id}/members/{member_id}` BREAKING CHANGE: * `get_user_info` -> `fetch_user_info` to match naming scheme. Remove useless note Remove `reverse` and corresponding documentation Update documentation to reflect #1988 Rename `get_` HTTP functions to `fetch_` Breaking Changes: * `get_message` -> `fetch_message` * `get_invite` -> `fetch_invite` * `get_user_profile` -> `fetch_user_profile` * `get_webhook_info` -> `fetch_webhook` * `get_ban` -> `fetch_ban` Fix InviteConverter, update migrating.rst Rename get_message to fetch_message
Diffstat (limited to 'discord/iterators.py')
-rw-r--r--discord/iterators.py132
1 files changed, 131 insertions, 1 deletions
diff --git a/discord/iterators.py b/discord/iterators.py
index d77592a5..015620bc 100644
--- a/discord/iterators.py
+++ b/discord/iterators.py
@@ -237,7 +237,7 @@ class HistoryIterator(_AsyncIterator):
elif self.limit == 101:
self.limit = 100 # Thanks discord
elif self.limit == 1:
- raise ValueError("Use get_message.")
+ raise ValueError("Use fetch_message.")
self._retrieve_messages = self._retrieve_messages_around_strategy
if self.before and self.after:
@@ -459,3 +459,133 @@ class AuditLogIterator(_AsyncIterator):
continue
await self.entries.put(AuditLogEntry(data=element, users=self._users, guild=self.guild))
+
+
+class GuildIterator(_AsyncIterator):
+ """Iterator for receiving the client's guilds.
+
+ The guilds endpoint has the same two behaviours as described
+ in :class:`HistoryIterator`:
+ If `before` is specified, the guilds endpoint returns the `limit`
+ newest guilds before `before`, sorted with newest first. For filling over
+ 100 guilds, update the `before` parameter to the oldest guild received.
+ Guilds will be returned in order by time.
+ If `after` is specified, it returns the `limit` oldest guilds after `after`,
+ sorted with newest first. For filling over 100 guilds, update the `after`
+ parameter to the newest guild received, If guilds are not reversed, they
+ will be out of order (99-0, 199-100, so on)
+
+ Not that if both before and after are specified, before is ignored by the
+ guilds endpoint.
+
+ Parameters
+ -----------
+ bot: :class:`discord.Client`
+ The client to retrieve the guilds from.
+ limit: :class:`int`
+ Maximum number of guilds to retrieve.
+ before: :class:`Snowflake`
+ Object before which all guilds must be.
+ after: :class:`Snowflake`
+ Object after which all guilds must be.
+ """
+ def __init__(self, bot, limit, before=None, after=None):
+
+ if isinstance(before, datetime.datetime):
+ before = Object(id=time_snowflake(before, high=False))
+ if isinstance(after, datetime.datetime):
+ after = Object(id=time_snowflake(after, high=True))
+
+ self.bot = bot
+ self.limit = limit
+ self.before = before
+ self.after = after
+
+ self._filter = None
+
+ self.state = self.bot._connection
+ self.get_guilds = self.bot.http.get_guilds
+ self.guilds = asyncio.Queue(loop=self.state.loop)
+
+ if self.before and self.after:
+ self._retrieve_guilds = self._retrieve_guilds_before_strategy
+ self._filter = lambda m: int(m['id']) > self.after.id
+ elif self.after:
+ self._retrieve_guilds = self._retrieve_guilds_after_strategy
+ else:
+ self._retrieve_guilds = self._retrieve_guilds_before_strategy
+
+ async def next(self):
+ if self.guilds.empty():
+ await self.fill_guilds()
+
+ try:
+ return self.guilds.get_nowait()
+ except asyncio.QueueEmpty:
+ raise NoMoreItems()
+
+ def _get_retrieve(self):
+ l = self.limit
+ if l is None:
+ r = 100
+ elif l <= 100:
+ r = l
+ else:
+ r = 100
+
+ self.retrieve = r
+ return r > 0
+
+ def create_guild(self, data):
+ from .guild import Guild
+ return Guild(state=self.state, data=data)
+
+ async def flatten(self):
+ result = []
+ while self._get_retrieve():
+ data = await self._retrieve_guilds(self.retrieve)
+ if len(data) < 100:
+ self.limit = 0
+
+ if self._filter:
+ data = filter(self._filter, data)
+
+ for element in data:
+ result.append(self.create_guild(element))
+ return result
+
+ async def fill_guilds(self):
+ if self._get_retrieve():
+ data = await self._retrieve_guilds(self.retrieve)
+ if self.limit is None or len(data) < 100:
+ self.limit = 0
+
+ if self._filter:
+ data = filter(self._filter, data)
+
+ for element in data:
+ await self.guilds.put(self.create_guild(element))
+
+ async def _retrieve_guilds(self, retrieve):
+ """Retrieve guilds and update next parameters."""
+ pass
+
+ async def _retrieve_guilds_before_strategy(self, retrieve):
+ """Retrieve guilds using before parameter."""
+ before = self.before.id if self.before else None
+ data = await self.get_guilds(retrieve, before=before)
+ if len(data):
+ if self.limit is not None:
+ self.limit -= retrieve
+ self.before = Object(id=int(data[-1]['id']))
+ return data
+
+ async def _retrieve_guilds_after_strategy(self, retrieve):
+ """Retrieve guilds using after parameter."""
+ after = self.after.id if self.after else None
+ data = await self.get_guilds(retrieve, after=after)
+ if len(data):
+ if self.limit is not None:
+ self.limit -= retrieve
+ self.after = Object(id=int(data[0]['id']))
+ return data