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
			
			
This commit is contained in:
		| @@ -816,7 +816,7 @@ class Messageable(metaclass=abc.ABCMeta): | ||||
|         """ | ||||
|         return Typing(self) | ||||
|  | ||||
|     async def get_message(self, id): | ||||
|     async def fetch_message(self, id): | ||||
|         """|coro| | ||||
|  | ||||
|         Retrieves a single :class:`.Message` from the destination. | ||||
|   | ||||
| @@ -39,6 +39,7 @@ from .user import User, Profile | ||||
| from .invite import Invite | ||||
| from .object import Object | ||||
| from .guild import Guild | ||||
| from .member import Member | ||||
| from .errors import * | ||||
| from .enums import Status, VoiceRegion | ||||
| from .gateway import * | ||||
| @@ -49,6 +50,7 @@ from .state import ConnectionState | ||||
| from . import utils | ||||
| from .backoff import ExponentialBackoff | ||||
| from .webhook import Webhook | ||||
| from .iterators import GuildIterator | ||||
|  | ||||
| log = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -841,6 +843,77 @@ class Client: | ||||
|  | ||||
|     # Guild stuff | ||||
|  | ||||
|     def fetch_guilds(self, *, limit=100, before=None, after=None): | ||||
|         """|coro| | ||||
|  | ||||
|         Retreives an :class:`AsyncIterator` that enables receiving your guilds. | ||||
|  | ||||
|         All parameters are optional. | ||||
|  | ||||
|         Parameters | ||||
|         ----------- | ||||
|         limit: Optional[:class:`int`] | ||||
|             The number of guilds to retrieve. | ||||
|             If ``None``, it retrieves every guild you have access to. Note, however, | ||||
|             that this would make it a slow operation. | ||||
|             Defaults to 100. | ||||
|         before: :class:`Snowflake` or `datetime` | ||||
|             Retrieves guilds before this date or object. | ||||
|             If a date is provided it must be a timezone-naive datetime representing UTC time. | ||||
|         after: :class:`Snowflake` or `datetime` | ||||
|             Retrieve guilds after this date or object. | ||||
|             If a date is provided it must be a timezone-naive datetime representing UTC time. | ||||
|  | ||||
|         Raises | ||||
|         ------ | ||||
|         HTTPException | ||||
|             Getting the guilds failed. | ||||
|  | ||||
|         Yields | ||||
|         -------- | ||||
|         :class:`Guild` | ||||
|             The guild with the guild data parsed. | ||||
|  | ||||
|         Examples | ||||
|         --------- | ||||
|  | ||||
|         Usage :: | ||||
|  | ||||
|             async for guild in client.fetch_guilds(limit=150): | ||||
|                 print(guild.name) | ||||
|  | ||||
|         Flattening into a list :: | ||||
|  | ||||
|             guilds = await client.fetch_guilds(limit=150).flatten() | ||||
|             # guilds is now a list of Guild... | ||||
|         """ | ||||
|         return GuildIterator(self, limit=limit, before=before, after=after) | ||||
|  | ||||
|     async def fetch_guild(self, guild_id): | ||||
|         """|coro| | ||||
|  | ||||
|         Retreives a :class:`Guild` from an ID. | ||||
|  | ||||
|         Parameters | ||||
|         ----------- | ||||
|         guild_id: :class:`int` | ||||
|             The guild's ID to fetch from. | ||||
|  | ||||
|         Raises | ||||
|         ------ | ||||
|         Forbidden | ||||
|             You do not have access to the guild. | ||||
|         HTTPException | ||||
|             Getting the guild failed. | ||||
|  | ||||
|         Returns | ||||
|         -------- | ||||
|         :class:`Guild` | ||||
|             The guild from the ID. | ||||
|         """ | ||||
|         data = await self.http.get_guild(guild_id) | ||||
|         return Guild(data=data, state=self._connection) | ||||
|  | ||||
|     async def create_guild(self, name, region=None, icon=None): | ||||
|         """|coro| | ||||
|  | ||||
| @@ -885,7 +958,7 @@ class Client: | ||||
|  | ||||
|     # Invite management | ||||
|  | ||||
|     async def get_invite(self, url, *, with_counts=True): | ||||
|     async def fetch_invite(self, url, *, with_counts=True): | ||||
|         """|coro| | ||||
|  | ||||
|         Gets an :class:`Invite` from a discord.gg URL or ID. | ||||
| @@ -974,7 +1047,7 @@ class Client: | ||||
|                        bot_require_code_grant=data['bot_require_code_grant'], | ||||
|                        owner=User(state=self._connection, data=data['owner'])) | ||||
|  | ||||
|     async def get_user_info(self, user_id): | ||||
|     async def fetch_user(self, user_id): | ||||
|         """|coro| | ||||
|  | ||||
|         Retrieves a :class:`User` based on their ID. This can only | ||||
| @@ -1002,7 +1075,7 @@ class Client: | ||||
|         data = await self.http.get_user_info(user_id) | ||||
|         return User(state=self._connection, data=data) | ||||
|  | ||||
|     async def get_user_profile(self, user_id): | ||||
|     async def fetch_user_profile(self, user_id): | ||||
|         """|coro| | ||||
|  | ||||
|         Gets an arbitrary user's profile. This can only be used by non-bot accounts. | ||||
| @@ -1040,7 +1113,7 @@ class Client: | ||||
|                        user=User(data=user, state=state), | ||||
|                        connected_accounts=data['connected_accounts']) | ||||
|  | ||||
|     async def get_webhook_info(self, webhook_id): | ||||
|     async def fetch_webhook(self, webhook_id): | ||||
|         """|coro| | ||||
|  | ||||
|         Retrieves a :class:`Webhook` with the specified ID. | ||||
|   | ||||
| @@ -336,11 +336,11 @@ class GameConverter(Converter): | ||||
| class InviteConverter(Converter): | ||||
|     """Converts to a :class:`Invite`. | ||||
|  | ||||
|     This is done via an HTTP request using :meth:`.Bot.get_invite`. | ||||
|     This is done via an HTTP request using :meth:`.Bot.fetch_invite`. | ||||
|     """ | ||||
|     async def convert(self, ctx, argument): | ||||
|         try: | ||||
|             invite = await ctx.bot.get_invite(argument) | ||||
|             invite = await ctx.bot.fetch_invite(argument) | ||||
|             return invite | ||||
|         except Exception as exc: | ||||
|             raise BadArgument('Invite is invalid or expired') from exc | ||||
|   | ||||
| @@ -944,7 +944,32 @@ class Guild(Hashable): | ||||
|         fields['explicit_content_filter'] = explicit_content_filter.value | ||||
|         await http.edit_guild(self.id, reason=reason, **fields) | ||||
|  | ||||
|     async def get_ban(self, user): | ||||
|     async def fetch_member(self, member_id): | ||||
|         """|coro| | ||||
|  | ||||
|         Retreives a :class:`Member` from a guild ID, and a member ID. | ||||
|  | ||||
|         Parameters | ||||
|         ----------- | ||||
|         member_id: :class:`int` | ||||
|             The member's ID to fetch from. | ||||
|  | ||||
|         Raises | ||||
|         ------- | ||||
|         Forbidden | ||||
|             You do not have access to the guild. | ||||
|         HTTPException | ||||
|             Getting the guild failed. | ||||
|  | ||||
|         Returns | ||||
|         -------- | ||||
|         :class:`Member` | ||||
|             The member from the member ID. | ||||
|         """ | ||||
|         data = await self._state.http.get_member(self.id, member_id) | ||||
|         return Member(data=data, state=self._state, guild=self) | ||||
|  | ||||
|     async def fetch_ban(self, user): | ||||
|         """|coro| | ||||
|  | ||||
|         Retrieves the :class:`BanEntry` for a user, which is a namedtuple | ||||
|   | ||||
| @@ -553,9 +553,24 @@ class HTTPClient: | ||||
|  | ||||
|     # Guild management | ||||
|  | ||||
|     def get_guilds(self, limit, before=None, after=None): | ||||
|         params = { | ||||
|             'limit': limit | ||||
|         } | ||||
|  | ||||
|         if before: | ||||
|             params['before'] = before | ||||
|         if after: | ||||
|             params['after'] = after | ||||
|  | ||||
|         return self.request(Route('GET', '/users/@me/guilds'), params=params) | ||||
|  | ||||
|     def leave_guild(self, guild_id): | ||||
|         return self.request(Route('DELETE', '/users/@me/guilds/{guild_id}', guild_id=guild_id)) | ||||
|  | ||||
|     def get_guild(self, guild_id): | ||||
|         return self.request(Route('GET', '/guilds/{guild_id}', guild_id=guild_id)) | ||||
|  | ||||
|     def delete_guild(self, guild_id): | ||||
|         return self.request(Route('DELETE', '/guilds/{guild_id}', guild_id=guild_id)) | ||||
|  | ||||
| @@ -593,6 +608,9 @@ class HTTPClient: | ||||
|         payload = {'code': code} | ||||
|         return self.request(Route('PATCH', '/guilds/{guild_id}/vanity-url', guild_id=guild_id), json=payload, reason=reason) | ||||
|  | ||||
|     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)) | ||||
|  | ||||
|     def prune_members(self, guild_id, days, *, reason=None): | ||||
|         params = { | ||||
|             'days': days | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user