mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-13 09:19:48 +00:00
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:
parent
fb02191b80
commit
f507f508a2
@ -816,7 +816,7 @@ class Messageable(metaclass=abc.ABCMeta):
|
|||||||
"""
|
"""
|
||||||
return Typing(self)
|
return Typing(self)
|
||||||
|
|
||||||
async def get_message(self, id):
|
async def fetch_message(self, id):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Retrieves a single :class:`.Message` from the destination.
|
Retrieves a single :class:`.Message` from the destination.
|
||||||
|
@ -39,6 +39,7 @@ from .user import User, Profile
|
|||||||
from .invite import Invite
|
from .invite import Invite
|
||||||
from .object import Object
|
from .object import Object
|
||||||
from .guild import Guild
|
from .guild import Guild
|
||||||
|
from .member import Member
|
||||||
from .errors import *
|
from .errors import *
|
||||||
from .enums import Status, VoiceRegion
|
from .enums import Status, VoiceRegion
|
||||||
from .gateway import *
|
from .gateway import *
|
||||||
@ -49,6 +50,7 @@ from .state import ConnectionState
|
|||||||
from . import utils
|
from . import utils
|
||||||
from .backoff import ExponentialBackoff
|
from .backoff import ExponentialBackoff
|
||||||
from .webhook import Webhook
|
from .webhook import Webhook
|
||||||
|
from .iterators import GuildIterator
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -841,6 +843,77 @@ class Client:
|
|||||||
|
|
||||||
# Guild stuff
|
# 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):
|
async def create_guild(self, name, region=None, icon=None):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
@ -885,7 +958,7 @@ class Client:
|
|||||||
|
|
||||||
# Invite management
|
# Invite management
|
||||||
|
|
||||||
async def get_invite(self, url, *, with_counts=True):
|
async def fetch_invite(self, url, *, with_counts=True):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Gets an :class:`Invite` from a discord.gg URL or ID.
|
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'],
|
bot_require_code_grant=data['bot_require_code_grant'],
|
||||||
owner=User(state=self._connection, data=data['owner']))
|
owner=User(state=self._connection, data=data['owner']))
|
||||||
|
|
||||||
async def get_user_info(self, user_id):
|
async def fetch_user(self, user_id):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Retrieves a :class:`User` based on their ID. This can only
|
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)
|
data = await self.http.get_user_info(user_id)
|
||||||
return User(state=self._connection, data=data)
|
return User(state=self._connection, data=data)
|
||||||
|
|
||||||
async def get_user_profile(self, user_id):
|
async def fetch_user_profile(self, user_id):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Gets an arbitrary user's profile. This can only be used by non-bot accounts.
|
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),
|
user=User(data=user, state=state),
|
||||||
connected_accounts=data['connected_accounts'])
|
connected_accounts=data['connected_accounts'])
|
||||||
|
|
||||||
async def get_webhook_info(self, webhook_id):
|
async def fetch_webhook(self, webhook_id):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Retrieves a :class:`Webhook` with the specified ID.
|
Retrieves a :class:`Webhook` with the specified ID.
|
||||||
|
@ -336,11 +336,11 @@ class GameConverter(Converter):
|
|||||||
class InviteConverter(Converter):
|
class InviteConverter(Converter):
|
||||||
"""Converts to a :class:`Invite`.
|
"""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):
|
async def convert(self, ctx, argument):
|
||||||
try:
|
try:
|
||||||
invite = await ctx.bot.get_invite(argument)
|
invite = await ctx.bot.fetch_invite(argument)
|
||||||
return invite
|
return invite
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise BadArgument('Invite is invalid or expired') from 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
|
fields['explicit_content_filter'] = explicit_content_filter.value
|
||||||
await http.edit_guild(self.id, reason=reason, **fields)
|
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|
|
"""|coro|
|
||||||
|
|
||||||
Retrieves the :class:`BanEntry` for a user, which is a namedtuple
|
Retrieves the :class:`BanEntry` for a user, which is a namedtuple
|
||||||
|
@ -553,9 +553,24 @@ class HTTPClient:
|
|||||||
|
|
||||||
# Guild management
|
# 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):
|
def leave_guild(self, guild_id):
|
||||||
return self.request(Route('DELETE', '/users/@me/guilds/{guild_id}', guild_id=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):
|
def delete_guild(self, guild_id):
|
||||||
return self.request(Route('DELETE', '/guilds/{guild_id}', guild_id=guild_id))
|
return self.request(Route('DELETE', '/guilds/{guild_id}', guild_id=guild_id))
|
||||||
|
|
||||||
@ -593,6 +608,9 @@ class HTTPClient:
|
|||||||
payload = {'code': code}
|
payload = {'code': code}
|
||||||
return self.request(Route('PATCH', '/guilds/{guild_id}/vanity-url', guild_id=guild_id), json=payload, reason=reason)
|
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):
|
def prune_members(self, guild_id, days, *, reason=None):
|
||||||
params = {
|
params = {
|
||||||
'days': days
|
'days': days
|
||||||
|
@ -237,7 +237,7 @@ class HistoryIterator(_AsyncIterator):
|
|||||||
elif self.limit == 101:
|
elif self.limit == 101:
|
||||||
self.limit = 100 # Thanks discord
|
self.limit = 100 # Thanks discord
|
||||||
elif self.limit == 1:
|
elif self.limit == 1:
|
||||||
raise ValueError("Use get_message.")
|
raise ValueError("Use fetch_message.")
|
||||||
|
|
||||||
self._retrieve_messages = self._retrieve_messages_around_strategy
|
self._retrieve_messages = self._retrieve_messages_around_strategy
|
||||||
if self.before and self.after:
|
if self.before and self.after:
|
||||||
@ -459,3 +459,133 @@ class AuditLogIterator(_AsyncIterator):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
await self.entries.put(AuditLogEntry(data=element, users=self._users, guild=self.guild))
|
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
|
||||||
|
@ -148,10 +148,14 @@ A list of these changes is enumerated below.
|
|||||||
+---------------------------------------+------------------------------------------------------------------------------+
|
+---------------------------------------+------------------------------------------------------------------------------+
|
||||||
| ``Client.get_bans`` | :meth:`Guild.bans` |
|
| ``Client.get_bans`` | :meth:`Guild.bans` |
|
||||||
+---------------------------------------+------------------------------------------------------------------------------+
|
+---------------------------------------+------------------------------------------------------------------------------+
|
||||||
| ``Client.get_message`` | :meth:`abc.Messageable.get_message` |
|
| ``Client.get_invite`` | :meth:`Client.fetch_invite` |
|
||||||
|
+---------------------------------------+------------------------------------------------------------------------------+
|
||||||
|
| ``Client.get_message`` | :meth:`abc.Messageable.fetch_message` |
|
||||||
+---------------------------------------+------------------------------------------------------------------------------+
|
+---------------------------------------+------------------------------------------------------------------------------+
|
||||||
| ``Client.get_reaction_users`` | :meth:`Reaction.users` |
|
| ``Client.get_reaction_users`` | :meth:`Reaction.users` |
|
||||||
+---------------------------------------+------------------------------------------------------------------------------+
|
+---------------------------------------+------------------------------------------------------------------------------+
|
||||||
|
| ``Client.get_user_info`` | :meth:`Client.fetch_user` |
|
||||||
|
+---------------------------------------+------------------------------------------------------------------------------+
|
||||||
| ``Client.invites_from`` | :meth:`abc.GuildChannel.invites` or :meth:`Guild.invites` |
|
| ``Client.invites_from`` | :meth:`abc.GuildChannel.invites` or :meth:`Guild.invites` |
|
||||||
+---------------------------------------+------------------------------------------------------------------------------+
|
+---------------------------------------+------------------------------------------------------------------------------+
|
||||||
| ``Client.join_voice_channel`` | :meth:`VoiceChannel.connect` (see :ref:`migrating_1_0_voice`) |
|
| ``Client.join_voice_channel`` | :meth:`VoiceChannel.connect` (see :ref:`migrating_1_0_voice`) |
|
||||||
|
Loading…
x
Reference in New Issue
Block a user