First pass at documentation reform.
@ -47,11 +47,22 @@ class _Undefined:
|
|||||||
_undefined = _Undefined()
|
_undefined = _Undefined()
|
||||||
|
|
||||||
class Snowflake(metaclass=abc.ABCMeta):
|
class Snowflake(metaclass=abc.ABCMeta):
|
||||||
|
"""An ABC that details the common operations on a Discord model.
|
||||||
|
|
||||||
|
Almost all :ref:`Discord models <discord_api_models>` meet this
|
||||||
|
abstract base class.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
id: int
|
||||||
|
The model's unique ID.
|
||||||
|
"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def created_at(self):
|
def created_at(self):
|
||||||
|
"""Returns the model's creation time in UTC."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -68,16 +79,39 @@ class Snowflake(metaclass=abc.ABCMeta):
|
|||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
class User(metaclass=abc.ABCMeta):
|
class User(metaclass=abc.ABCMeta):
|
||||||
|
"""An ABC that details the common operations on a Discord user.
|
||||||
|
|
||||||
|
The following implement this ABC:
|
||||||
|
|
||||||
|
- :class:`User`
|
||||||
|
- :class:`ClientUser`
|
||||||
|
- :class:`Member`
|
||||||
|
|
||||||
|
This ABC must also implement :class:`abc.Snowflake`.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
name: str
|
||||||
|
The user's username.
|
||||||
|
discriminator: str
|
||||||
|
The user's discriminator.
|
||||||
|
avatar: Optional[str]
|
||||||
|
The avatar hash the user has.
|
||||||
|
bot: bool
|
||||||
|
If the user is a bot account.
|
||||||
|
"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def display_name(self):
|
def display_name(self):
|
||||||
|
"""Returns the user's display name."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def mention(self):
|
def mention(self):
|
||||||
|
"""Returns a string that allows you to mention the given user."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -97,6 +131,20 @@ class User(metaclass=abc.ABCMeta):
|
|||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
class PrivateChannel(metaclass=abc.ABCMeta):
|
class PrivateChannel(metaclass=abc.ABCMeta):
|
||||||
|
"""An ABC that details the common operations on a private Discord channel.
|
||||||
|
|
||||||
|
The follow implement this ABC:
|
||||||
|
|
||||||
|
- :class:`DMChannel`
|
||||||
|
- :class:`GroupChannel`
|
||||||
|
|
||||||
|
This ABC must also implement :class:`abc.Snowflake`.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
me: :class:`ClientUser`
|
||||||
|
The user presenting yourself.
|
||||||
|
"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -115,6 +163,25 @@ class PrivateChannel(metaclass=abc.ABCMeta):
|
|||||||
_Overwrites = namedtuple('_Overwrites', 'id allow deny type')
|
_Overwrites = namedtuple('_Overwrites', 'id allow deny type')
|
||||||
|
|
||||||
class GuildChannel:
|
class GuildChannel:
|
||||||
|
"""An ABC that details the common operations on a Discord guild channel.
|
||||||
|
|
||||||
|
The follow implement this ABC:
|
||||||
|
|
||||||
|
- :class:`TextChannel`
|
||||||
|
- :class:`VoiceChannel`
|
||||||
|
|
||||||
|
This ABC must also implement :class:`abc.Snowflake`.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
name: str
|
||||||
|
The channel name.
|
||||||
|
guild: :class:`Guild`
|
||||||
|
The guild the channel belongs to.
|
||||||
|
position: int
|
||||||
|
The position in the channel list. This is a number that starts at 0.
|
||||||
|
e.g. the top channel is position 0.
|
||||||
|
"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -539,6 +606,20 @@ class GuildChannel:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class Messageable(metaclass=abc.ABCMeta):
|
class Messageable(metaclass=abc.ABCMeta):
|
||||||
|
"""An ABC that details the common operations on a model that can send messages.
|
||||||
|
|
||||||
|
The follow implement this ABC:
|
||||||
|
|
||||||
|
- :class:`TextChannel`
|
||||||
|
- :class:`DMChannel`
|
||||||
|
- :class:`GroupChannel`
|
||||||
|
- :class:`User`
|
||||||
|
- :class:`Member`
|
||||||
|
- :class:`~ext.commands.Context`
|
||||||
|
|
||||||
|
This ABC must also implement :class:`abc.Snowflake`.
|
||||||
|
"""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -728,7 +809,7 @@ class Messageable(metaclass=abc.ABCMeta):
|
|||||||
def history(self, *, limit=100, before=None, after=None, around=None, reverse=None):
|
def history(self, *, limit=100, before=None, after=None, around=None, reverse=None):
|
||||||
"""Return an :class:`AsyncIterator` that enables receiving the destination's message history.
|
"""Return an :class:`AsyncIterator` that enables receiving the destination's message history.
|
||||||
|
|
||||||
You must have Read Message History permissions to use this.
|
You must have :attr:`~Permissions.read_message_history` permissions to use this.
|
||||||
|
|
||||||
All parameters are optional.
|
All parameters are optional.
|
||||||
|
|
||||||
@ -799,6 +880,13 @@ class Messageable(metaclass=abc.ABCMeta):
|
|||||||
|
|
||||||
|
|
||||||
class Connectable(metaclass=abc.ABCMeta):
|
class Connectable(metaclass=abc.ABCMeta):
|
||||||
|
"""An ABC that details the common operations on a channel that can
|
||||||
|
connect to a voice server.
|
||||||
|
|
||||||
|
The follow implement this ABC:
|
||||||
|
|
||||||
|
- :class:`VoiceChannel`
|
||||||
|
"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -428,7 +428,7 @@ class DMChannel(discord.abc.Messageable, Hashable):
|
|||||||
----------
|
----------
|
||||||
recipient: :class:`User`
|
recipient: :class:`User`
|
||||||
The user you are participating with in the direct message channel.
|
The user you are participating with in the direct message channel.
|
||||||
me: :class:`User`
|
me: :class:`ClientUser`
|
||||||
The user presenting yourself.
|
The user presenting yourself.
|
||||||
id: int
|
id: int
|
||||||
The direct message channel ID.
|
The direct message channel ID.
|
||||||
@ -507,7 +507,7 @@ class GroupChannel(discord.abc.Messageable, Hashable):
|
|||||||
----------
|
----------
|
||||||
recipients: list of :class:`User`
|
recipients: list of :class:`User`
|
||||||
The users you are participating with in the group channel.
|
The users you are participating with in the group channel.
|
||||||
me: :class:`User`
|
me: :class:`ClientUser`
|
||||||
The user presenting yourself.
|
The user presenting yourself.
|
||||||
id: int
|
id: int
|
||||||
The group channel ID.
|
The group channel ID.
|
||||||
|
@ -123,7 +123,7 @@ class Emoji(Hashable):
|
|||||||
|
|
||||||
Deletes the custom emoji.
|
Deletes the custom emoji.
|
||||||
|
|
||||||
You must have :attr:`Permissions.manage_emojis` permission to
|
You must have :attr:`~Permissions.manage_emojis` permission to
|
||||||
do this.
|
do this.
|
||||||
|
|
||||||
Guild local emotes can only be deleted by user bots.
|
Guild local emotes can only be deleted by user bots.
|
||||||
@ -149,7 +149,7 @@ class Emoji(Hashable):
|
|||||||
|
|
||||||
Edits the custom emoji.
|
Edits the custom emoji.
|
||||||
|
|
||||||
You must have :attr:`Permissions.manage_emojis` permission to
|
You must have :attr:`~Permissions.manage_emojis` permission to
|
||||||
do this.
|
do this.
|
||||||
|
|
||||||
Guild local emotes can only be edited by user bots.
|
Guild local emotes can only be edited by user bots.
|
||||||
|
@ -55,7 +55,7 @@ def when_mentioned_or(*prefixes):
|
|||||||
|
|
||||||
See Also
|
See Also
|
||||||
----------
|
----------
|
||||||
:func:`when_mentioned`
|
:func:`.when_mentioned`
|
||||||
"""
|
"""
|
||||||
def inner(bot, msg):
|
def inner(bot, msg):
|
||||||
r = list(prefixes)
|
r = list(prefixes)
|
||||||
@ -212,17 +212,17 @@ class BotBase(GroupMixin):
|
|||||||
def check(self, func):
|
def check(self, func):
|
||||||
"""A decorator that adds a global check to the bot.
|
"""A decorator that adds a global check to the bot.
|
||||||
|
|
||||||
A global check is similar to a :func:`check` that is applied
|
A global check is similar to a :func:`.check` that is applied
|
||||||
on a per command basis except it is run before any command checks
|
on a per command basis except it is run before any command checks
|
||||||
have been verified and applies to every command the bot has.
|
have been verified and applies to every command the bot has.
|
||||||
|
|
||||||
.. info::
|
.. note::
|
||||||
|
|
||||||
This function can either be a regular function or a coroutine.
|
This function can either be a regular function or a coroutine.
|
||||||
|
|
||||||
Similar to a command :func:`check`\, this takes a single parameter
|
Similar to a command :func:`.check`\, this takes a single parameter
|
||||||
of type :class:`Context` and can only raise exceptions derived from
|
of type :class:`.Context` and can only raise exceptions derived from
|
||||||
:exc:`CommandError`.
|
:exc:`.CommandError`.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
---------
|
---------
|
||||||
@ -240,7 +240,7 @@ class BotBase(GroupMixin):
|
|||||||
def add_check(self, func):
|
def add_check(self, func):
|
||||||
"""Adds a global check to the bot.
|
"""Adds a global check to the bot.
|
||||||
|
|
||||||
This is the non-decorator interface to :meth:`check`.
|
This is the non-decorator interface to :meth:`.check`.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -275,15 +275,15 @@ class BotBase(GroupMixin):
|
|||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def is_owner(self, user):
|
def is_owner(self, user):
|
||||||
"""Checks if a :class:`User` or :class:`Member` is the owner of
|
"""Checks if a :class:`.User` or :class:`.Member` is the owner of
|
||||||
this bot.
|
this bot.
|
||||||
|
|
||||||
If an :attr:`owner_id` is not set, it is fetched automatically
|
If an :attr:`owner_id` is not set, it is fetched automatically
|
||||||
through the use of :meth:`application_info`.
|
through the use of :meth:`~.Bot.application_info`.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
user: :class:`abc.User`
|
user: :class:`.abc.User`
|
||||||
The user to check for.
|
The user to check for.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -300,11 +300,11 @@ class BotBase(GroupMixin):
|
|||||||
called. This makes it a useful function to set up database
|
called. This makes it a useful function to set up database
|
||||||
connections or any type of set up required.
|
connections or any type of set up required.
|
||||||
|
|
||||||
This pre-invoke hook takes a sole parameter, a :class:`Context`.
|
This pre-invoke hook takes a sole parameter, a :class:`.Context`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The :meth:`before_invoke` and :meth:`after_invoke` hooks are
|
The :meth:`~.Bot.before_invoke` and :meth:`~.Bot.after_invoke` hooks are
|
||||||
only called if all checks and argument parsing procedures pass
|
only called if all checks and argument parsing procedures pass
|
||||||
without error. If any check or argument parsing procedures fail
|
without error. If any check or argument parsing procedures fail
|
||||||
then the hooks are not called.
|
then the hooks are not called.
|
||||||
@ -316,7 +316,7 @@ class BotBase(GroupMixin):
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
discord.ClientException
|
:exc:`.ClientException`
|
||||||
The coroutine is not actually a coroutine.
|
The coroutine is not actually a coroutine.
|
||||||
"""
|
"""
|
||||||
if not asyncio.iscoroutinefunction(coro):
|
if not asyncio.iscoroutinefunction(coro):
|
||||||
@ -332,14 +332,14 @@ class BotBase(GroupMixin):
|
|||||||
called. This makes it a useful function to clean-up database
|
called. This makes it a useful function to clean-up database
|
||||||
connections or any type of clean up required.
|
connections or any type of clean up required.
|
||||||
|
|
||||||
This post-invoke hook takes a sole parameter, a :class:`Context`.
|
This post-invoke hook takes a sole parameter, a :class:`.Context`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Similar to :meth:`before_invoke`\, this is not called unless
|
Similar to :meth:`~.Bot.before_invoke`\, this is not called unless
|
||||||
checks and argument parsing procedures succeed. This hook is,
|
checks and argument parsing procedures succeed. This hook is,
|
||||||
however, **always** called regardless of the internal command
|
however, **always** called regardless of the internal command
|
||||||
callback raising an error (i.e. :exc:`CommandInvokeError`\).
|
callback raising an error (i.e. :exc:`.CommandInvokeError`\).
|
||||||
This makes it ideal for clean-up scenarios.
|
This makes it ideal for clean-up scenarios.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@ -349,7 +349,7 @@ class BotBase(GroupMixin):
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
discord.ClientException
|
:exc:`.ClientException`
|
||||||
The coroutine is not actually a coroutine.
|
The coroutine is not actually a coroutine.
|
||||||
"""
|
"""
|
||||||
if not asyncio.iscoroutinefunction(coro):
|
if not asyncio.iscoroutinefunction(coro):
|
||||||
@ -361,7 +361,7 @@ class BotBase(GroupMixin):
|
|||||||
# listener registration
|
# listener registration
|
||||||
|
|
||||||
def add_listener(self, func, name=None):
|
def add_listener(self, func, name=None):
|
||||||
"""The non decorator alternative to :meth:`listen`.
|
"""The non decorator alternative to :meth:`.listen`.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -415,7 +415,7 @@ class BotBase(GroupMixin):
|
|||||||
def listen(self, name=None):
|
def listen(self, name=None):
|
||||||
"""A decorator that registers another function as an external
|
"""A decorator that registers another function as an external
|
||||||
event listener. Basically this allows you to listen to multiple
|
event listener. Basically this allows you to listen to multiple
|
||||||
events from different places e.g. such as :func:`discord.on_ready`
|
events from different places e.g. such as :func:`.on_ready`
|
||||||
|
|
||||||
The functions being listened to must be a coroutine.
|
The functions being listened to must be a coroutine.
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ class BotBase(GroupMixin):
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
discord.ClientException
|
:exc:`.ClientException`
|
||||||
The function being listened to is not a coroutine.
|
The function being listened to is not a coroutine.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -459,7 +459,7 @@ class BotBase(GroupMixin):
|
|||||||
into a singular class that shares some state or no state at all.
|
into a singular class that shares some state or no state at all.
|
||||||
|
|
||||||
The cog can also have a ``__global_check`` member function that allows
|
The cog can also have a ``__global_check`` member function that allows
|
||||||
you to define a global check. See :meth:`check` for more info.
|
you to define a global check. See :meth:`.check` for more info.
|
||||||
|
|
||||||
More information will be documented soon.
|
More information will be documented soon.
|
||||||
|
|
||||||
@ -515,7 +515,7 @@ class BotBase(GroupMixin):
|
|||||||
|
|
||||||
Returns
|
Returns
|
||||||
---------
|
---------
|
||||||
Set[:class:`Command`]
|
Set[:class:`.Command`]
|
||||||
A unique set of commands without aliases that belong
|
A unique set of commands without aliases that belong
|
||||||
to the cog.
|
to the cog.
|
||||||
"""
|
"""
|
||||||
@ -675,27 +675,27 @@ class BotBase(GroupMixin):
|
|||||||
|
|
||||||
Returns the invocation context from the message.
|
Returns the invocation context from the message.
|
||||||
|
|
||||||
This is a more low-level counter-part for :meth:`process_message`
|
This is a more low-level counter-part for :meth:`.process_commands`
|
||||||
to allow users more fine grained control over the processing.
|
to allow users more fine grained control over the processing.
|
||||||
|
|
||||||
The returned context is not guaranteed to be a valid invocation
|
The returned context is not guaranteed to be a valid invocation
|
||||||
context, :attr:`Context.valid` must be checked to make sure it is.
|
context, :attr:`.Context.valid` must be checked to make sure it is.
|
||||||
If the context is not valid then it is not a valid candidate to be
|
If the context is not valid then it is not a valid candidate to be
|
||||||
invoked under :meth:`invoke`.
|
invoked under :meth:`~.Bot.invoke`.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
message: :class:`discord.Message`
|
message: :class:`discord.Message`
|
||||||
The message to get the invocation context from.
|
The message to get the invocation context from.
|
||||||
cls: type
|
cls
|
||||||
The factory class that will be used to create the context.
|
The factory class that will be used to create the context.
|
||||||
By default, this is :class:`Context`. Should a custom
|
By default, this is :class:`.Context`. Should a custom
|
||||||
class be provided, it must be similar enough to :class:`Context`\'s
|
class be provided, it must be similar enough to :class:`.Context`\'s
|
||||||
interface.
|
interface.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
--------
|
--------
|
||||||
:class:`Context`
|
:class:`.Context`
|
||||||
The invocation context. The type of this can change via the
|
The invocation context. The type of this can change via the
|
||||||
``cls`` parameter.
|
``cls`` parameter.
|
||||||
"""
|
"""
|
||||||
@ -732,7 +732,7 @@ class BotBase(GroupMixin):
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
ctx: :class:`Context`
|
ctx: :class:`.Context`
|
||||||
The invocation context to invoke.
|
The invocation context to invoke.
|
||||||
"""
|
"""
|
||||||
if ctx.command is not None:
|
if ctx.command is not None:
|
||||||
@ -756,12 +756,12 @@ class BotBase(GroupMixin):
|
|||||||
to the bot and other groups. Without this coroutine, none of the
|
to the bot and other groups. Without this coroutine, none of the
|
||||||
commands will be triggered.
|
commands will be triggered.
|
||||||
|
|
||||||
By default, this coroutine is called inside the :func:`on_message`
|
By default, this coroutine is called inside the :func:`.on_message`
|
||||||
event. If you choose to override the :func:`on_message` event, then
|
event. If you choose to override the :func:`.on_message` event, then
|
||||||
you should invoke this coroutine as well.
|
you should invoke this coroutine as well.
|
||||||
|
|
||||||
This is built using other low level tools, and is equivalent to a
|
This is built using other low level tools, and is equivalent to a
|
||||||
call to :meth:`get_context` followed by a call to :meth:`invoke`.
|
call to :meth:`~.Bot.get_context` followed by a call to :meth:`~.Bot.invoke`.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -782,7 +782,10 @@ class Bot(BotBase, discord.Client):
|
|||||||
anything that you can do with a :class:`discord.Client` you can do with
|
anything that you can do with a :class:`discord.Client` you can do with
|
||||||
this bot.
|
this bot.
|
||||||
|
|
||||||
This class also subclasses :class:`GroupMixin` to provide the functionality
|
.. _deque: https://docs.python.org/3.4/library/collections.html#collections.deque
|
||||||
|
.. _event loop: https://docs.python.org/3/library/asyncio-eventloops.html
|
||||||
|
|
||||||
|
This class also subclasses :class:`.GroupMixin` to provide the functionality
|
||||||
to manage commands.
|
to manage commands.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
@ -799,18 +802,18 @@ class Bot(BotBase, discord.Client):
|
|||||||
The command prefix could also be a list or a tuple indicating that
|
The command prefix could also be a list or a tuple indicating that
|
||||||
multiple checks for the prefix should be used and the first one to
|
multiple checks for the prefix should be used and the first one to
|
||||||
match will be the invocation prefix. You can get this prefix via
|
match will be the invocation prefix. You can get this prefix via
|
||||||
:attr:`Context.prefix`.
|
:attr:`.Context.prefix`.
|
||||||
description : str
|
description : str
|
||||||
The content prefixed into the default help message.
|
The content prefixed into the default help message.
|
||||||
self_bot : bool
|
self_bot : bool
|
||||||
If ``True``, the bot will only listen to commands invoked by itself rather
|
If ``True``, the bot will only listen to commands invoked by itself rather
|
||||||
than ignoring itself. If ``False`` (the default) then the bot will ignore
|
than ignoring itself. If ``False`` (the default) then the bot will ignore
|
||||||
itself. This cannot be changed once initialised.
|
itself. This cannot be changed once initialised.
|
||||||
formatter : :class:`HelpFormatter`
|
formatter : :class:`.HelpFormatter`
|
||||||
The formatter used to format the help message. By default, it uses a
|
The formatter used to format the help message. By default, it uses a
|
||||||
the :class:`HelpFormatter`. Check it for more info on how to override it.
|
the :class:`.HelpFormatter`. Check it for more info on how to override it.
|
||||||
If you want to change the help command completely (add aliases, etc) then
|
If you want to change the help command completely (add aliases, etc) then
|
||||||
a call to :meth:`remove_command` with 'help' as the argument would do the
|
a call to :meth:`~.Bot.remove_command` with 'help' as the argument would do the
|
||||||
trick.
|
trick.
|
||||||
pm_help : Optional[bool]
|
pm_help : Optional[bool]
|
||||||
A tribool that indicates if the help command should PM the user instead of
|
A tribool that indicates if the help command should PM the user instead of
|
||||||
@ -823,7 +826,7 @@ class Bot(BotBase, discord.Client):
|
|||||||
A dictionary of options to pass in for the construction of the help command.
|
A dictionary of options to pass in for the construction of the help command.
|
||||||
This allows you to change the command behaviour without actually changing
|
This allows you to change the command behaviour without actually changing
|
||||||
the implementation of the command. The attributes will be the same as the
|
the implementation of the command. The attributes will be the same as the
|
||||||
ones passed in the :class:`Command` constructor. Note that ``pass_context``
|
ones passed in the :class:`.Command` constructor. Note that ``pass_context``
|
||||||
will always be set to ``True`` regardless of what you pass in.
|
will always be set to ``True`` regardless of what you pass in.
|
||||||
command_not_found : str
|
command_not_found : str
|
||||||
The format string used when the help command is invoked with a command that
|
The format string used when the help command is invoked with a command that
|
||||||
@ -833,16 +836,16 @@ class Bot(BotBase, discord.Client):
|
|||||||
The format string used when the help command is invoked with requests for a
|
The format string used when the help command is invoked with requests for a
|
||||||
subcommand but the command does not have any subcommands. Defaults to
|
subcommand but the command does not have any subcommands. Defaults to
|
||||||
``"Command {0.name} has no subcommands."``. The first format argument is the
|
``"Command {0.name} has no subcommands."``. The first format argument is the
|
||||||
:class:`Command` attempted to get a subcommand and the second is the name.
|
:class:`.Command` attempted to get a subcommand and the second is the name.
|
||||||
owner_id: Optional[int]
|
owner_id: Optional[int]
|
||||||
The ID that owns the bot. If this is not set and is then queried via
|
The ID that owns the bot. If this is not set and is then queried via
|
||||||
:meth:`is_owner` then it is fetched automatically using
|
:meth:`.is_owner` then it is fetched automatically using
|
||||||
:meth:`application_info`.
|
:meth:`~.Bot.application_info`.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AutoShardedBot(BotBase, discord.AutoShardedClient):
|
class AutoShardedBot(BotBase, discord.AutoShardedClient):
|
||||||
"""This is similar to :class:`Bot` except that it is derived from
|
"""This is similar to :class:`.Bot` except that it is derived from
|
||||||
:class:`discord.AutoShardedClient` instead.
|
:class:`discord.AutoShardedClient` instead.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -40,7 +40,7 @@ class Context(discord.abc.Messageable):
|
|||||||
-----------
|
-----------
|
||||||
message: :class:`discord.Message`
|
message: :class:`discord.Message`
|
||||||
The message that triggered the command being executed.
|
The message that triggered the command being executed.
|
||||||
bot: :class:`Bot`
|
bot: :class:`.Bot`
|
||||||
The bot that contains the command being executed.
|
The bot that contains the command being executed.
|
||||||
args: list
|
args: list
|
||||||
The list of transformed arguments that were passed into the command.
|
The list of transformed arguments that were passed into the command.
|
||||||
@ -53,13 +53,13 @@ class Context(discord.abc.Messageable):
|
|||||||
prefix: str
|
prefix: str
|
||||||
The prefix that was used to invoke the command.
|
The prefix that was used to invoke the command.
|
||||||
command
|
command
|
||||||
The command (i.e. :class:`Command` or its superclasses) that is being
|
The command (i.e. :class:`.Command` or its superclasses) that is being
|
||||||
invoked currently.
|
invoked currently.
|
||||||
invoked_with: str
|
invoked_with: str
|
||||||
The command name that triggered this invocation. Useful for finding out
|
The command name that triggered this invocation. Useful for finding out
|
||||||
which alias called the command.
|
which alias called the command.
|
||||||
invoked_subcommand
|
invoked_subcommand
|
||||||
The subcommand (i.e. :class:`Command` or its superclasses) that was
|
The subcommand (i.e. :class:`.Command` or its superclasses) that was
|
||||||
invoked. If no valid subcommand was invoked then this is equal to
|
invoked. If no valid subcommand was invoked then this is equal to
|
||||||
`None`.
|
`None`.
|
||||||
subcommand_passed: Optional[str]
|
subcommand_passed: Optional[str]
|
||||||
@ -93,7 +93,7 @@ class Context(discord.abc.Messageable):
|
|||||||
Calls a command with the arguments given.
|
Calls a command with the arguments given.
|
||||||
|
|
||||||
This is useful if you want to just call the callback that a
|
This is useful if you want to just call the callback that a
|
||||||
:class:`Command` holds internally.
|
:class:`.Command` holds internally.
|
||||||
|
|
||||||
Note
|
Note
|
||||||
------
|
------
|
||||||
@ -101,7 +101,7 @@ class Context(discord.abc.Messageable):
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
command : :class:`Command`
|
command : :class:`.Command`
|
||||||
A command or superclass of a command that is going to be called.
|
A command or superclass of a command that is going to be called.
|
||||||
\*args
|
\*args
|
||||||
The arguments to to use.
|
The arguments to to use.
|
||||||
|
@ -46,14 +46,14 @@ def _get_from_guilds(bot, getter, argument):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class Converter:
|
class Converter:
|
||||||
"""The base class of custom converters that require the :class:`Context`
|
"""The base class of custom converters that require the :class:`.Context`
|
||||||
to be passed to be useful.
|
to be passed to be useful.
|
||||||
|
|
||||||
This allows you to implement converters that function similar to the
|
This allows you to implement converters that function similar to the
|
||||||
special cased ``discord`` classes.
|
special cased ``discord`` classes.
|
||||||
|
|
||||||
Classes that derive from this should override the :meth:`convert` method
|
Classes that derive from this should override the :meth:`~.Converter.convert`
|
||||||
to do its conversion logic. This method must be a coroutine.
|
method to do its conversion logic. This method must be a coroutine.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -62,15 +62,13 @@ class Converter:
|
|||||||
|
|
||||||
The method to override to do conversion logic.
|
The method to override to do conversion logic.
|
||||||
|
|
||||||
This can either be a coroutine or a regular function.
|
|
||||||
|
|
||||||
If an error is found while converting, it is recommended to
|
If an error is found while converting, it is recommended to
|
||||||
raise a :class:`CommandError` derived exception as it will
|
raise a :exc:`.CommandError` derived exception as it will
|
||||||
properly propagate to the error handlers.
|
properly propagate to the error handlers.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
ctx: :class:`Context`
|
ctx: :class:`.Context`
|
||||||
The invocation context that the argument is being used in.
|
The invocation context that the argument is being used in.
|
||||||
argument: str
|
argument: str
|
||||||
The argument that is being converted.
|
The argument that is being converted.
|
||||||
@ -86,6 +84,20 @@ class IDConverter(Converter):
|
|||||||
return self._id_regex.match(argument)
|
return self._id_regex.match(argument)
|
||||||
|
|
||||||
class MemberConverter(IDConverter):
|
class MemberConverter(IDConverter):
|
||||||
|
"""Converts to a :class:`Member`.
|
||||||
|
|
||||||
|
All lookups are via the local guild. If in a DM context, then the lookup
|
||||||
|
is done by the global cache.
|
||||||
|
|
||||||
|
The lookup strategy is as follows (in order):
|
||||||
|
|
||||||
|
1. Lookup by ID.
|
||||||
|
2. Lookup by mention.
|
||||||
|
3. Lookup by name#discrim
|
||||||
|
4. Lookup by name
|
||||||
|
5. Lookup by nickname
|
||||||
|
"""
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
message = ctx.message
|
message = ctx.message
|
||||||
@ -112,6 +124,17 @@ class MemberConverter(IDConverter):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class UserConverter(IDConverter):
|
class UserConverter(IDConverter):
|
||||||
|
"""Converts to a :class:`User`.
|
||||||
|
|
||||||
|
All lookups are via the global user cache.
|
||||||
|
|
||||||
|
The lookup strategy is as follows (in order):
|
||||||
|
|
||||||
|
1. Lookup by ID.
|
||||||
|
2. Lookup by mention.
|
||||||
|
3. Lookup by name#discrim
|
||||||
|
4. Lookup by name
|
||||||
|
"""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument)
|
match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument)
|
||||||
@ -141,6 +164,17 @@ class UserConverter(IDConverter):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class TextChannelConverter(IDConverter):
|
class TextChannelConverter(IDConverter):
|
||||||
|
"""Converts to a :class:`TextChannel`.
|
||||||
|
|
||||||
|
All lookups are via the local guild. If in a DM context, then the lookup
|
||||||
|
is done by the global cache.
|
||||||
|
|
||||||
|
The lookup strategy is as follows (in order):
|
||||||
|
|
||||||
|
1. Lookup by ID.
|
||||||
|
2. Lookup by mention.
|
||||||
|
3. Lookup by name
|
||||||
|
"""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
bot = ctx.bot
|
bot = ctx.bot
|
||||||
@ -170,6 +204,17 @@ class TextChannelConverter(IDConverter):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class VoiceChannelConverter(IDConverter):
|
class VoiceChannelConverter(IDConverter):
|
||||||
|
"""Converts to a :class:`VoiceChannel`.
|
||||||
|
|
||||||
|
All lookups are via the local guild. If in a DM context, then the lookup
|
||||||
|
is done by the global cache.
|
||||||
|
|
||||||
|
The lookup strategy is as follows (in order):
|
||||||
|
|
||||||
|
1. Lookup by ID.
|
||||||
|
2. Lookup by mention.
|
||||||
|
3. Lookup by name
|
||||||
|
"""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
bot = ctx.bot
|
bot = ctx.bot
|
||||||
@ -198,6 +243,17 @@ class VoiceChannelConverter(IDConverter):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class ColourConverter(Converter):
|
class ColourConverter(Converter):
|
||||||
|
"""Converts to a :class:`Colour`.
|
||||||
|
|
||||||
|
The following formats are accepted:
|
||||||
|
|
||||||
|
- ``0x<hex>``
|
||||||
|
- ``#<hex>``
|
||||||
|
- ``0x#<hex>``
|
||||||
|
- Any of the ``classmethod`` in :class:`Colour`
|
||||||
|
|
||||||
|
- The ``_`` in the name can be optionally replaced with spaces.
|
||||||
|
"""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
arg = argument.replace('0x', '').lower()
|
arg = argument.replace('0x', '').lower()
|
||||||
@ -208,12 +264,24 @@ class ColourConverter(Converter):
|
|||||||
value = int(arg, base=16)
|
value = int(arg, base=16)
|
||||||
return discord.Colour(value=value)
|
return discord.Colour(value=value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
method = getattr(discord.Colour, arg, None)
|
method = getattr(discord.Colour, arg.replace(' ', '_'), None)
|
||||||
if method is None or not inspect.ismethod(method):
|
if method is None or not inspect.ismethod(method):
|
||||||
raise BadArgument('Colour "{}" is invalid.'.format(arg))
|
raise BadArgument('Colour "{}" is invalid.'.format(arg))
|
||||||
return method()
|
return method()
|
||||||
|
|
||||||
class RoleConverter(IDConverter):
|
class RoleConverter(IDConverter):
|
||||||
|
"""Converts to a :class:`Role`.
|
||||||
|
|
||||||
|
|
||||||
|
All lookups are via the local guild. If in a DM context, then the lookup
|
||||||
|
is done by the global cache.
|
||||||
|
|
||||||
|
The lookup strategy is as follows (in order):
|
||||||
|
|
||||||
|
1. Lookup by ID.
|
||||||
|
2. Lookup by mention.
|
||||||
|
3. Lookup by name
|
||||||
|
"""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
guild = ctx.message.guild
|
guild = ctx.message.guild
|
||||||
@ -228,11 +296,16 @@ class RoleConverter(IDConverter):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class GameConverter(Converter):
|
class GameConverter(Converter):
|
||||||
|
"""Converts to :class:`Game`."""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
return discord.Game(name=argument)
|
return discord.Game(name=argument)
|
||||||
|
|
||||||
class InviteConverter(Converter):
|
class InviteConverter(Converter):
|
||||||
|
"""Converts to a :class:`Invite`.
|
||||||
|
|
||||||
|
This is done via an HTTP request using :meth:`.Bot.get_invite`.
|
||||||
|
"""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
try:
|
try:
|
||||||
@ -242,6 +315,18 @@ class InviteConverter(Converter):
|
|||||||
raise BadArgument('Invite is invalid or expired') from e
|
raise BadArgument('Invite is invalid or expired') from e
|
||||||
|
|
||||||
class EmojiConverter(IDConverter):
|
class EmojiConverter(IDConverter):
|
||||||
|
"""Converts to a :class:`Emoji`.
|
||||||
|
|
||||||
|
|
||||||
|
All lookups are via the local guild. If in a DM context, then the lookup
|
||||||
|
is done by the global cache.
|
||||||
|
|
||||||
|
The lookup strategy is as follows (in order):
|
||||||
|
|
||||||
|
1. Lookup by ID.
|
||||||
|
2. Lookup by extracting ID from the emoji.
|
||||||
|
3. Lookup by name
|
||||||
|
"""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def convert(self, ctx, argument):
|
def convert(self, ctx, argument):
|
||||||
match = self._get_id_match(argument) or re.match(r'<:[a-zA-Z0-9]+:([0-9]+)>$', argument)
|
match = self._get_id_match(argument) or re.match(r'<:[a-zA-Z0-9]+:([0-9]+)>$', argument)
|
||||||
@ -272,6 +357,18 @@ class EmojiConverter(IDConverter):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
class clean_content(Converter):
|
class clean_content(Converter):
|
||||||
|
"""Converts the argument to mention scrubbed version of
|
||||||
|
said content.
|
||||||
|
|
||||||
|
This behaves similarly to :attr:`.Message.clean_content`.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
------------
|
||||||
|
fix_channel_mentions: bool
|
||||||
|
Whether to clean channel mentions.
|
||||||
|
use_nicknames: bool
|
||||||
|
Whether to use nicknames when transforming mentions.
|
||||||
|
"""
|
||||||
def __init__(self, *, fix_channel_mentions=False, use_nicknames=True):
|
def __init__(self, *, fix_channel_mentions=False, use_nicknames=True):
|
||||||
self.fix_channel_mentions = fix_channel_mentions
|
self.fix_channel_mentions = fix_channel_mentions
|
||||||
self.use_nicknames = use_nicknames
|
self.use_nicknames = use_nicknames
|
||||||
|
@ -88,54 +88,54 @@ class Command:
|
|||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
-----------
|
-----------
|
||||||
name : str
|
name: str
|
||||||
The name of the command.
|
The name of the command.
|
||||||
callback : coroutine
|
callback: coroutine
|
||||||
The coroutine that is executed when the command is called.
|
The coroutine that is executed when the command is called.
|
||||||
help : str
|
help: str
|
||||||
The long help text for the command.
|
The long help text for the command.
|
||||||
brief : str
|
brief: str
|
||||||
The short help text for the command. If this is not specified
|
The short help text for the command. If this is not specified
|
||||||
then the first line of the long help text is used instead.
|
then the first line of the long help text is used instead.
|
||||||
usage : str
|
usage: str
|
||||||
A replacement for arguments in the default help text.
|
A replacement for arguments in the default help text.
|
||||||
aliases : list
|
aliases: list
|
||||||
The list of aliases the command can be invoked under.
|
The list of aliases the command can be invoked under.
|
||||||
pass_context : bool
|
pass_context: bool
|
||||||
A boolean that indicates that the current :class:`Context` should
|
A boolean that indicates that the current :class:`.Context` should
|
||||||
be passed as the **first parameter**. Defaults to `True`.
|
be passed as the **first parameter**. Defaults to `True`.
|
||||||
enabled : bool
|
enabled: bool
|
||||||
A boolean that indicates if the command is currently enabled.
|
A boolean that indicates if the command is currently enabled.
|
||||||
If the command is invoked while it is disabled, then
|
If the command is invoked while it is disabled, then
|
||||||
:exc:`DisabledCommand` is raised to the :func:`on_command_error`
|
:exc:`.DisabledCommand` is raised to the :func:`.on_command_error`
|
||||||
event. Defaults to ``True``.
|
event. Defaults to ``True``.
|
||||||
parent : Optional[command]
|
parent: Optional[command]
|
||||||
The parent command that this command belongs to. ``None`` is there
|
The parent command that this command belongs to. ``None`` is there
|
||||||
isn't one.
|
isn't one.
|
||||||
checks
|
checks
|
||||||
A list of predicates that verifies if the command could be executed
|
A list of predicates that verifies if the command could be executed
|
||||||
with the given :class:`Context` as the sole parameter. If an exception
|
with the given :class:`.Context` as the sole parameter. If an exception
|
||||||
is necessary to be thrown to signal failure, then one derived from
|
is necessary to be thrown to signal failure, then one derived from
|
||||||
:exc:`CommandError` should be used. Note that if the checks fail then
|
:exc:`.CommandError` should be used. Note that if the checks fail then
|
||||||
:exc:`CheckFailure` exception is raised to the :func:`on_command_error`
|
:exc:`.CheckFailure` exception is raised to the :func:`.on_command_error`
|
||||||
event.
|
event.
|
||||||
description : str
|
description: str
|
||||||
The message prefixed into the default help command.
|
The message prefixed into the default help command.
|
||||||
hidden : bool
|
hidden: bool
|
||||||
If ``True``\, the default help command does not show this in the
|
If ``True``\, the default help command does not show this in the
|
||||||
help output.
|
help output.
|
||||||
rest_is_raw : bool
|
rest_is_raw: bool
|
||||||
If ``False`` and a keyword-only argument is provided then the keyword
|
If ``False`` and a keyword-only argument is provided then the keyword
|
||||||
only argument is stripped and handled as if it was a regular argument
|
only argument is stripped and handled as if it was a regular argument
|
||||||
that handles :exc:`MissingRequiredArgument` and default values in a
|
that handles :exc:`.MissingRequiredArgument` and default values in a
|
||||||
regular matter rather than passing the rest completely raw. If ``True``
|
regular matter rather than passing the rest completely raw. If ``True``
|
||||||
then the keyword-only argument will pass in the rest of the arguments
|
then the keyword-only argument will pass in the rest of the arguments
|
||||||
in a completely raw matter. Defaults to ``False``.
|
in a completely raw matter. Defaults to ``False``.
|
||||||
ignore_extra : bool
|
ignore_extra: bool
|
||||||
If ``True``\, ignores extraneous strings passed to a command if all its
|
If ``True``\, ignores extraneous strings passed to a command if all its
|
||||||
requirements are met (e.g. ``?foo a b c`` when only expecting ``a``
|
requirements are met (e.g. ``?foo a b c`` when only expecting ``a``
|
||||||
and ``b``). Otherwise :func:`on_command_error` and local error handlers
|
and ``b``). Otherwise :func:`.on_command_error` and local error handlers
|
||||||
are called with :exc:`TooManyArguments`. Defaults to ``True``.
|
are called with :exc:`.TooManyArguments`. Defaults to ``True``.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, callback, **kwargs):
|
def __init__(self, name, callback, **kwargs):
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -418,7 +418,7 @@ class Command:
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
ctx: :class:`Context`
|
ctx: :class:`.Context`
|
||||||
The invocation context to reset the cooldown under.
|
The invocation context to reset the cooldown under.
|
||||||
"""
|
"""
|
||||||
if self._buckets.valid:
|
if self._buckets.valid:
|
||||||
@ -439,8 +439,8 @@ class Command:
|
|||||||
def error(self, coro):
|
def error(self, coro):
|
||||||
"""A decorator that registers a coroutine as a local error handler.
|
"""A decorator that registers a coroutine as a local error handler.
|
||||||
|
|
||||||
A local error handler is an :func:`on_command_error` event limited to
|
A local error handler is an :func:`.on_command_error` event limited to
|
||||||
a single command. However, the :func:`on_command_error` is still
|
a single command. However, the :func:`.on_command_error` is still
|
||||||
invoked afterwards as the catch-all.
|
invoked afterwards as the catch-all.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@ -463,13 +463,13 @@ class Command:
|
|||||||
def before_invoke(self, coro):
|
def before_invoke(self, coro):
|
||||||
"""A decorator that registers a coroutine as a pre-invoke hook.
|
"""A decorator that registers a coroutine as a pre-invoke hook.
|
||||||
|
|
||||||
A pre-invoke hook is called directly before :meth:`invoke` is
|
A pre-invoke hook is called directly before the command is
|
||||||
called. This makes it a useful function to set up database
|
called. This makes it a useful function to set up database
|
||||||
connections or any type of set up required.
|
connections or any type of set up required.
|
||||||
|
|
||||||
This pre-invoke hook takes a sole parameter, a :class:`Context`.
|
This pre-invoke hook takes a sole parameter, a :class:`.Context`.
|
||||||
|
|
||||||
See :meth:`Bot.before_invoke` for more info.
|
See :meth:`.Bot.before_invoke` for more info.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -478,7 +478,7 @@ class Command:
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
discord.ClientException
|
:exc:`.ClientException`
|
||||||
The coroutine is not actually a coroutine.
|
The coroutine is not actually a coroutine.
|
||||||
"""
|
"""
|
||||||
if not asyncio.iscoroutinefunction(coro):
|
if not asyncio.iscoroutinefunction(coro):
|
||||||
@ -490,13 +490,13 @@ class Command:
|
|||||||
def after_invoke(self, coro):
|
def after_invoke(self, coro):
|
||||||
"""A decorator that registers a coroutine as a post-invoke hook.
|
"""A decorator that registers a coroutine as a post-invoke hook.
|
||||||
|
|
||||||
A post-invoke hook is called directly after :meth:`invoke` is
|
A post-invoke hook is called directly after the command is
|
||||||
called. This makes it a useful function to clean-up database
|
called. This makes it a useful function to clean-up database
|
||||||
connections or any type of clean up required.
|
connections or any type of clean up required.
|
||||||
|
|
||||||
This post-invoke hook takes a sole parameter, a :class:`Context`.
|
This post-invoke hook takes a sole parameter, a :class:`.Context`.
|
||||||
|
|
||||||
See :meth:`Bot.after_invoke` for more info.
|
See :meth:`.Bot.after_invoke` for more info.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -505,7 +505,7 @@ class Command:
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
discord.ClientException
|
:exc:`.ClientException`
|
||||||
The coroutine is not actually a coroutine.
|
The coroutine is not actually a coroutine.
|
||||||
"""
|
"""
|
||||||
if not asyncio.iscoroutinefunction(coro):
|
if not asyncio.iscoroutinefunction(coro):
|
||||||
@ -577,11 +577,11 @@ class Command:
|
|||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Checks if the command can be executed by checking all the predicates
|
Checks if the command can be executed by checking all the predicates
|
||||||
inside the :attr:`checks` attribute.
|
inside the :attr:`.checks` attribute.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
ctx: :class:`Context`
|
ctx: :class:`.Context`
|
||||||
The ctx of the command currently being invoked.
|
The ctx of the command currently being invoked.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@ -613,12 +613,12 @@ class Command:
|
|||||||
|
|
||||||
class GroupMixin:
|
class GroupMixin:
|
||||||
"""A mixin that implements common functionality for classes that behave
|
"""A mixin that implements common functionality for classes that behave
|
||||||
similar to :class:`Group` and are allowed to register commands.
|
similar to :class:`.Group` and are allowed to register commands.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
-----------
|
-----------
|
||||||
all_commands: dict
|
all_commands: dict
|
||||||
A mapping of command name to :class:`Command` or superclass
|
A mapping of command name to :class:`.Command` or superclass
|
||||||
objects.
|
objects.
|
||||||
"""
|
"""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
@ -627,7 +627,7 @@ class GroupMixin:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def commands(self):
|
def commands(self):
|
||||||
"""Set[:class:`Command`]: A unique set of commands without aliases that are registered."""
|
"""Set[:class:`.Command`]: A unique set of commands without aliases that are registered."""
|
||||||
return set(self.all_commands.values())
|
return set(self.all_commands.values())
|
||||||
|
|
||||||
def recursively_remove_all_commands(self):
|
def recursively_remove_all_commands(self):
|
||||||
@ -637,11 +637,11 @@ class GroupMixin:
|
|||||||
self.remove_command(command.name)
|
self.remove_command(command.name)
|
||||||
|
|
||||||
def add_command(self, command):
|
def add_command(self, command):
|
||||||
"""Adds a :class:`Command` or its superclasses into the internal list
|
"""Adds a :class:`.Command` or its superclasses into the internal list
|
||||||
of commands.
|
of commands.
|
||||||
|
|
||||||
This is usually not called, instead the :meth:`command` or
|
This is usually not called, instead the :meth:`~.GroupMixin.command` or
|
||||||
:meth:`group` shortcut decorators are used instead.
|
:meth:`~.GroupMixin.group` shortcut decorators are used instead.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -650,10 +650,10 @@ class GroupMixin:
|
|||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
discord.ClientException
|
:exc:`.ClientException`
|
||||||
If the command is already registered.
|
If the command is already registered.
|
||||||
TypeError
|
TypeError
|
||||||
If the command passed is not a subclass of :class:`Command`.
|
If the command passed is not a subclass of :class:`.Command`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not isinstance(command, Command):
|
if not isinstance(command, Command):
|
||||||
@ -672,19 +672,19 @@ class GroupMixin:
|
|||||||
self.all_commands[alias] = command
|
self.all_commands[alias] = command
|
||||||
|
|
||||||
def remove_command(self, name):
|
def remove_command(self, name):
|
||||||
"""Remove a :class:`Command` or subclasses from the internal list
|
"""Remove a :class:`.Command` or subclasses from the internal list
|
||||||
of commands.
|
of commands.
|
||||||
|
|
||||||
This could also be used as a way to remove aliases.
|
This could also be used as a way to remove aliases.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
name : str
|
name: str
|
||||||
The name of the command to remove.
|
The name of the command to remove.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
--------
|
--------
|
||||||
Command or subclass
|
:class:`.Command` or subclass
|
||||||
The command that was removed. If the name is not valid then
|
The command that was removed. If the name is not valid then
|
||||||
`None` is returned instead.
|
`None` is returned instead.
|
||||||
"""
|
"""
|
||||||
@ -711,7 +711,7 @@ class GroupMixin:
|
|||||||
yield from command.walk_commands()
|
yield from command.walk_commands()
|
||||||
|
|
||||||
def get_command(self, name):
|
def get_command(self, name):
|
||||||
"""Get a :class:`Command` or subclasses from the internal list
|
"""Get a :class:`.Command` or subclasses from the internal list
|
||||||
of commands.
|
of commands.
|
||||||
|
|
||||||
This could also be used as a way to get aliases.
|
This could also be used as a way to get aliases.
|
||||||
@ -745,8 +745,8 @@ class GroupMixin:
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
def command(self, *args, **kwargs):
|
def command(self, *args, **kwargs):
|
||||||
"""A shortcut decorator that invokes :func:`command` and adds it to
|
"""A shortcut decorator that invokes :func:`.command` and adds it to
|
||||||
the internal command list via :meth:`add_command`.
|
the internal command list via :meth:`~.GroupMixin.add_command`.
|
||||||
"""
|
"""
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
result = command(*args, **kwargs)(func)
|
result = command(*args, **kwargs)(func)
|
||||||
@ -756,8 +756,8 @@ class GroupMixin:
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def group(self, *args, **kwargs):
|
def group(self, *args, **kwargs):
|
||||||
"""A shortcut decorator that invokes :func:`group` and adds it to
|
"""A shortcut decorator that invokes :func:`.group` and adds it to
|
||||||
the internal command list via :meth:`add_command`.
|
the internal command list via :meth:`~.GroupMixin.add_command`.
|
||||||
"""
|
"""
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
result = group(*args, **kwargs)(func)
|
result = group(*args, **kwargs)(func)
|
||||||
@ -770,12 +770,12 @@ class Group(GroupMixin, Command):
|
|||||||
"""A class that implements a grouping protocol for commands to be
|
"""A class that implements a grouping protocol for commands to be
|
||||||
executed as subcommands.
|
executed as subcommands.
|
||||||
|
|
||||||
This class is a subclass of :class:`Command` and thus all options
|
This class is a subclass of :class:`.Command` and thus all options
|
||||||
valid in :class:`Command` are valid in here as well.
|
valid in :class:`.Command` are valid in here as well.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
-----------
|
-----------
|
||||||
invoke_without_command : bool
|
invoke_without_command: bool
|
||||||
Indicates if the group callback should begin parsing and
|
Indicates if the group callback should begin parsing and
|
||||||
invocation only if no subcommand was found. Useful for
|
invocation only if no subcommand was found. Useful for
|
||||||
making it an error handling function to tell the user that
|
making it an error handling function to tell the user that
|
||||||
@ -820,25 +820,25 @@ class Group(GroupMixin, Command):
|
|||||||
# Decorators
|
# Decorators
|
||||||
|
|
||||||
def command(name=None, cls=None, **attrs):
|
def command(name=None, cls=None, **attrs):
|
||||||
"""A decorator that transforms a function into a :class:`Command`
|
"""A decorator that transforms a function into a :class:`.Command`
|
||||||
or if called with :func:`group`, :class:`Group`.
|
or if called with :func:`.group`, :class:`.Group`.
|
||||||
|
|
||||||
By default the ``help`` attribute is received automatically from the
|
By default the ``help`` attribute is received automatically from the
|
||||||
docstring of the function and is cleaned up with the use of
|
docstring of the function and is cleaned up with the use of
|
||||||
``inspect.cleandoc``. If the docstring is ``bytes``, then it is decoded
|
``inspect.cleandoc``. If the docstring is ``bytes``, then it is decoded
|
||||||
into ``str`` using utf-8 encoding.
|
into ``str`` using utf-8 encoding.
|
||||||
|
|
||||||
All checks added using the :func:`check` & co. decorators are added into
|
All checks added using the :func:`.check` & co. decorators are added into
|
||||||
the function. There is no way to supply your own checks through this
|
the function. There is no way to supply your own checks through this
|
||||||
decorator.
|
decorator.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
name : str
|
name: str
|
||||||
The name to create the command with. By default this uses the
|
The name to create the command with. By default this uses the
|
||||||
function name unchanged.
|
function name unchanged.
|
||||||
cls
|
cls
|
||||||
The class to construct with. By default this is :class:`Command`.
|
The class to construct with. By default this is :class:`.Command`.
|
||||||
You usually do not change this.
|
You usually do not change this.
|
||||||
attrs
|
attrs
|
||||||
Keyword arguments to pass into the construction of the class denoted
|
Keyword arguments to pass into the construction of the class denoted
|
||||||
@ -886,28 +886,28 @@ def command(name=None, cls=None, **attrs):
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def group(name=None, **attrs):
|
def group(name=None, **attrs):
|
||||||
"""A decorator that transforms a function into a :class:`Group`.
|
"""A decorator that transforms a function into a :class:`.Group`.
|
||||||
|
|
||||||
This is similar to the :func:`command` decorator but creates a
|
This is similar to the :func:`.command` decorator but creates a
|
||||||
:class:`Group` instead of a :class:`Command`.
|
:class:`.Group` instead of a :class:`.Command`.
|
||||||
"""
|
"""
|
||||||
return command(name=name, cls=Group, **attrs)
|
return command(name=name, cls=Group, **attrs)
|
||||||
|
|
||||||
def check(predicate):
|
def check(predicate):
|
||||||
"""A decorator that adds a check to the :class:`Command` or its
|
"""A decorator that adds a check to the :class:`.Command` or its
|
||||||
subclasses. These checks could be accessed via :attr:`Command.checks`.
|
subclasses. These checks could be accessed via :attr:`.Command.checks`.
|
||||||
|
|
||||||
These checks should be predicates that take in a single parameter taking
|
These checks should be predicates that take in a single parameter taking
|
||||||
a :class:`Context`. If the check returns a ``False``\-like value then
|
a :class:`.Context`. If the check returns a ``False``\-like value then
|
||||||
during invocation a :exc:`CheckFailure` exception is raised and sent to
|
during invocation a :exc:`.CheckFailure` exception is raised and sent to
|
||||||
the :func:`on_command_error` event.
|
the :func:`.on_command_error` event.
|
||||||
|
|
||||||
If an exception should be thrown in the predicate then it should be a
|
If an exception should be thrown in the predicate then it should be a
|
||||||
subclass of :exc:`CommandError`. Any exception not subclassed from it
|
subclass of :exc:`.CommandError`. Any exception not subclassed from it
|
||||||
will be propagated while those subclassed will be sent to
|
will be propagated while those subclassed will be sent to
|
||||||
:func:`on_command_error`.
|
:func:`.on_command_error`.
|
||||||
|
|
||||||
.. info::
|
.. note::
|
||||||
|
|
||||||
These functions can either be regular functions or coroutines.
|
These functions can either be regular functions or coroutines.
|
||||||
|
|
||||||
@ -960,7 +960,7 @@ def check(predicate):
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def has_role(name):
|
def has_role(name):
|
||||||
"""A :func:`check` that is added that checks if the member invoking the
|
"""A :func:`.check` that is added that checks if the member invoking the
|
||||||
command has the role specified via the name specified.
|
command has the role specified via the name specified.
|
||||||
|
|
||||||
The name is case sensitive and must be exact. No normalisation is done in
|
The name is case sensitive and must be exact. No normalisation is done in
|
||||||
@ -971,7 +971,7 @@ def has_role(name):
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
name : str
|
name: str
|
||||||
The name of the role to check.
|
The name of the role to check.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -985,11 +985,11 @@ def has_role(name):
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def has_any_role(*names):
|
def has_any_role(*names):
|
||||||
"""A :func:`check` that is added that checks if the member invoking the
|
"""A :func:`.check` that is added that checks if the member invoking the
|
||||||
command has **any** of the roles specified. This means that if they have
|
command has **any** of the roles specified. This means that if they have
|
||||||
one out of the three roles specified, then this check will return `True`.
|
one out of the three roles specified, then this check will return `True`.
|
||||||
|
|
||||||
Similar to :func:`has_role`\, the names passed in must be exact.
|
Similar to :func:`.has_role`\, the names passed in must be exact.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
@ -1015,11 +1015,11 @@ def has_any_role(*names):
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def has_permissions(**perms):
|
def has_permissions(**perms):
|
||||||
"""A :func:`check` that is added that checks if the member has any of
|
"""A :func:`.check` that is added that checks if the member has any of
|
||||||
the permissions necessary.
|
the permissions necessary.
|
||||||
|
|
||||||
The permissions passed in must be exactly like the properties shown under
|
The permissions passed in must be exactly like the properties shown under
|
||||||
:class:`discord.Permissions`.
|
:class:`.discord.Permissions`.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
------------
|
------------
|
||||||
@ -1045,7 +1045,7 @@ def has_permissions(**perms):
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def bot_has_role(name):
|
def bot_has_role(name):
|
||||||
"""Similar to :func:`has_role` except checks if the bot itself has the
|
"""Similar to :func:`.has_role` except checks if the bot itself has the
|
||||||
role.
|
role.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -1059,7 +1059,7 @@ def bot_has_role(name):
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def bot_has_any_role(*names):
|
def bot_has_any_role(*names):
|
||||||
"""Similar to :func:`has_any_role` except checks if the bot itself has
|
"""Similar to :func:`.has_any_role` except checks if the bot itself has
|
||||||
any of the roles listed.
|
any of the roles listed.
|
||||||
"""
|
"""
|
||||||
def predicate(ctx):
|
def predicate(ctx):
|
||||||
@ -1072,7 +1072,7 @@ def bot_has_any_role(*names):
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def bot_has_permissions(**perms):
|
def bot_has_permissions(**perms):
|
||||||
"""Similar to :func:`has_permissions` except checks if the bot itself has
|
"""Similar to :func:`.has_permissions` except checks if the bot itself has
|
||||||
the permissions listed.
|
the permissions listed.
|
||||||
"""
|
"""
|
||||||
def predicate(ctx):
|
def predicate(ctx):
|
||||||
@ -1083,12 +1083,12 @@ def bot_has_permissions(**perms):
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def guild_only():
|
def guild_only():
|
||||||
"""A :func:`check` that indicates this command must only be used in a
|
"""A :func:`.check` that indicates this command must only be used in a
|
||||||
guild context only. Basically, no private messages are allowed when
|
guild context only. Basically, no private messages are allowed when
|
||||||
using the command.
|
using the command.
|
||||||
|
|
||||||
This check raises a special exception, :exc:`NoPrivateMessage`
|
This check raises a special exception, :exc:`.NoPrivateMessage`
|
||||||
that is derived from :exc:`CheckFailure`.
|
that is derived from :exc:`.CheckFailure`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def predicate(ctx):
|
def predicate(ctx):
|
||||||
@ -1099,13 +1099,13 @@ def guild_only():
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def is_owner():
|
def is_owner():
|
||||||
"""A :func:`check` that checks if the person invoking this command is the
|
"""A :func:`.check` that checks if the person invoking this command is the
|
||||||
owner of the bot.
|
owner of the bot.
|
||||||
|
|
||||||
This is powered by :meth:`Bot.is_owner`.
|
This is powered by :meth:`.Bot.is_owner`.
|
||||||
|
|
||||||
This check raises a special exception, :exc:`NotOwner` that is derived
|
This check raises a special exception, :exc:`.NotOwner` that is derived
|
||||||
from :exc:`CheckFailure`.
|
from :exc:`.CheckFailure`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -1117,13 +1117,13 @@ def is_owner():
|
|||||||
return check(predicate)
|
return check(predicate)
|
||||||
|
|
||||||
def is_nsfw():
|
def is_nsfw():
|
||||||
"""A :func:`check` that checks if the channel is a NSFW channel."""
|
"""A :func:`.check` that checks if the channel is a NSFW channel."""
|
||||||
def pred(ctx):
|
def pred(ctx):
|
||||||
return isinstance(ctx.channel, discord.TextChannel) and ctx.channel.is_nsfw()
|
return isinstance(ctx.channel, discord.TextChannel) and ctx.channel.is_nsfw()
|
||||||
return check(pred)
|
return check(pred)
|
||||||
|
|
||||||
def cooldown(rate, per, type=BucketType.default):
|
def cooldown(rate, per, type=BucketType.default):
|
||||||
"""A decorator that adds a cooldown to a :class:`Command`
|
"""A decorator that adds a cooldown to a :class:`.Command`
|
||||||
or its subclasses.
|
or its subclasses.
|
||||||
|
|
||||||
A cooldown allows a command to only be used a specific amount
|
A cooldown allows a command to only be used a specific amount
|
||||||
@ -1137,8 +1137,8 @@ def cooldown(rate, per, type=BucketType.default):
|
|||||||
- ``BucketType.guild`` for a per-guild basis.
|
- ``BucketType.guild`` for a per-guild basis.
|
||||||
- ``BucketType.channel`` for a per-channel basis.
|
- ``BucketType.channel`` for a per-channel basis.
|
||||||
|
|
||||||
If a cooldown is triggered, then :exc:`CommandOnCooldown` is triggered in
|
If a cooldown is triggered, then :exc:`.CommandOnCooldown` is triggered in
|
||||||
:func:`on_command_error` and the local error handler.
|
:func:`.on_command_error` and the local error handler.
|
||||||
|
|
||||||
A command can only have a single cooldown.
|
A command can only have a single cooldown.
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class CommandError(DiscordException):
|
|||||||
|
|
||||||
This exception and exceptions derived from it are handled
|
This exception and exceptions derived from it are handled
|
||||||
in a special way as they are caught and passed into a special event
|
in a special way as they are caught and passed into a special event
|
||||||
from :class:`Bot`\, :func:`on_command_error`.
|
from :class:`.Bot`\, :func:`on_command_error`.
|
||||||
"""
|
"""
|
||||||
def __init__(self, message=None, *args):
|
def __init__(self, message=None, *args):
|
||||||
if message is not None:
|
if message is not None:
|
||||||
@ -52,7 +52,7 @@ class UserInputError(CommandError):
|
|||||||
"""The base exception type for errors that involve errors
|
"""The base exception type for errors that involve errors
|
||||||
regarding user input.
|
regarding user input.
|
||||||
|
|
||||||
This inherits from :exc:`CommandError`.
|
This inherits from :exc:`.CommandError`.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ class MissingRequiredArgument(UserInputError):
|
|||||||
|
|
||||||
class TooManyArguments(UserInputError):
|
class TooManyArguments(UserInputError):
|
||||||
"""Exception raised when the command was passed too many arguments and its
|
"""Exception raised when the command was passed too many arguments and its
|
||||||
:attr:`Command.ignore_extra` attribute was not set to ``True``.
|
:attr:`.Command.ignore_extra` attribute was not set to ``True``.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ class BadArgument(UserInputError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class CheckFailure(CommandError):
|
class CheckFailure(CommandError):
|
||||||
"""Exception raised when the predicates in :attr:`Command.checks` have failed."""
|
"""Exception raised when the predicates in :attr:`.Command.checks` have failed."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class NoPrivateMessage(CheckFailure):
|
class NoPrivateMessage(CheckFailure):
|
||||||
@ -128,7 +128,7 @@ class CommandOnCooldown(CommandError):
|
|||||||
-----------
|
-----------
|
||||||
cooldown: Cooldown
|
cooldown: Cooldown
|
||||||
A class with attributes ``rate``, ``per``, and ``type`` similar to
|
A class with attributes ``rate``, ``per``, and ``type`` similar to
|
||||||
the :func:`cooldown` decorator.
|
the :func:`.cooldown` decorator.
|
||||||
retry_after: float
|
retry_after: float
|
||||||
The amount of seconds to wait before you can retry again.
|
The amount of seconds to wait before you can retry again.
|
||||||
"""
|
"""
|
||||||
|
@ -127,19 +127,19 @@ class HelpFormatter:
|
|||||||
"""The default base implementation that handles formatting of the help
|
"""The default base implementation that handles formatting of the help
|
||||||
command.
|
command.
|
||||||
|
|
||||||
To override the behaviour of the formatter, :meth:`format`
|
To override the behaviour of the formatter, :meth:`~.HelpFormatter.format`
|
||||||
should be overridden. A number of utility functions are provided for use
|
should be overridden. A number of utility functions are provided for use
|
||||||
inside that method.
|
inside that method.
|
||||||
|
|
||||||
Parameters
|
Attributes
|
||||||
-----------
|
-----------
|
||||||
show_hidden : bool
|
show_hidden: bool
|
||||||
Dictates if hidden commands should be shown in the output.
|
Dictates if hidden commands should be shown in the output.
|
||||||
Defaults to ``False``.
|
Defaults to ``False``.
|
||||||
show_check_failure : bool
|
show_check_failure: bool
|
||||||
Dictates if commands that have their :attr:`Command.checks` failed
|
Dictates if commands that have their :attr:`.Command.checks` failed
|
||||||
shown. Defaults to ``False``.
|
shown. Defaults to ``False``.
|
||||||
width : int
|
width: int
|
||||||
The maximum number of characters that fit in a line.
|
The maximum number of characters that fit in a line.
|
||||||
Defaults to 80.
|
Defaults to 80.
|
||||||
"""
|
"""
|
||||||
@ -149,15 +149,15 @@ class HelpFormatter:
|
|||||||
self.show_check_failure = show_check_failure
|
self.show_check_failure = show_check_failure
|
||||||
|
|
||||||
def has_subcommands(self):
|
def has_subcommands(self):
|
||||||
"""bool : Specifies if the command has subcommands."""
|
"""bool: Specifies if the command has subcommands."""
|
||||||
return isinstance(self.command, GroupMixin)
|
return isinstance(self.command, GroupMixin)
|
||||||
|
|
||||||
def is_bot(self):
|
def is_bot(self):
|
||||||
"""bool : Specifies if the command being formatted is the bot itself."""
|
"""bool: Specifies if the command being formatted is the bot itself."""
|
||||||
return self.command is self.context.bot
|
return self.command is self.context.bot
|
||||||
|
|
||||||
def is_cog(self):
|
def is_cog(self):
|
||||||
"""bool : Specifies if the command being formatted is actually a cog."""
|
"""bool: Specifies if the command being formatted is actually a cog."""
|
||||||
return not self.is_bot() and not isinstance(self.command, Command)
|
return not self.is_bot() and not isinstance(self.command, Command)
|
||||||
|
|
||||||
def shorten(self, text):
|
def shorten(self, text):
|
||||||
@ -168,7 +168,7 @@ class HelpFormatter:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def max_name_size(self):
|
def max_name_size(self):
|
||||||
"""int : Returns the largest name length of a command or if it has subcommands
|
"""int: Returns the largest name length of a command or if it has subcommands
|
||||||
the largest subcommand name."""
|
the largest subcommand name."""
|
||||||
try:
|
try:
|
||||||
commands = self.command.all_commands if not self.is_cog() else self.context.bot.all_commands
|
commands = self.command.all_commands if not self.is_cog() else self.context.bot.all_commands
|
||||||
@ -202,8 +202,8 @@ class HelpFormatter:
|
|||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def filter_command_list(self):
|
def filter_command_list(self):
|
||||||
"""Returns a filtered list of commands based on the two attributes
|
"""Returns a filtered list of commands based on the two attributes
|
||||||
provided, :attr:`show_check_failure` and :attr:`show_hidden`. Also
|
provided, :attr:`show_check_failure` and :attr:`show_hidden`.
|
||||||
filters based on if :meth:`is_cog` is valid.
|
Also filters based on if :meth:`~.HelpFormatter.is_cog` is valid.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
--------
|
--------
|
||||||
@ -262,13 +262,13 @@ class HelpFormatter:
|
|||||||
def format_help_for(self, context, command_or_bot):
|
def format_help_for(self, context, command_or_bot):
|
||||||
"""Formats the help page and handles the actual heavy lifting of how
|
"""Formats the help page and handles the actual heavy lifting of how
|
||||||
the help command looks like. To change the behaviour, override the
|
the help command looks like. To change the behaviour, override the
|
||||||
:meth:`format` method.
|
:meth:`~.HelpFormatter.format` method.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-----------
|
-----------
|
||||||
context : :class:`Context`
|
context: :class:`.Context`
|
||||||
The context of the invoked help command.
|
The context of the invoked help command.
|
||||||
command_or_bot : :class:`Command` or :class:`Bot`
|
command_or_bot: :class:`.Command` or :class:`.Bot`
|
||||||
The bot or command that we are getting the help of.
|
The bot or command that we are getting the help of.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
|
@ -566,7 +566,7 @@ class Guild(Hashable):
|
|||||||
|
|
||||||
Edits the guild.
|
Edits the guild.
|
||||||
|
|
||||||
You must have the :attr:`Permissions.manage_guild` permission
|
You must have the :attr:`~Permissions.manage_guild` permission
|
||||||
to edit the guild.
|
to edit the guild.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@ -671,7 +671,7 @@ class Guild(Hashable):
|
|||||||
that got banned along with a ``reason`` field specifying
|
that got banned along with a ``reason`` field specifying
|
||||||
why the user was banned that could be set to ``None``.
|
why the user was banned that could be set to ``None``.
|
||||||
|
|
||||||
You must have :attr:`Permissions.ban_members` permission
|
You must have :attr:`~Permissions.ban_members` permission
|
||||||
to get this information.
|
to get this information.
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
@ -701,7 +701,7 @@ class Guild(Hashable):
|
|||||||
The inactive members are denoted if they have not logged on in
|
The inactive members are denoted if they have not logged on in
|
||||||
``days`` number of days and they have no roles.
|
``days`` number of days and they have no roles.
|
||||||
|
|
||||||
You must have the :attr:`Permissions.kick_members` permission
|
You must have the :attr:`~Permissions.kick_members` permission
|
||||||
to use this.
|
to use this.
|
||||||
|
|
||||||
To check how many members you would prune without actually pruning,
|
To check how many members you would prune without actually pruning,
|
||||||
@ -775,7 +775,7 @@ class Guild(Hashable):
|
|||||||
|
|
||||||
Returns a list of all active instant invites from the guild.
|
Returns a list of all active instant invites from the guild.
|
||||||
|
|
||||||
You must have :attr:`Permissions.manage_guild` to get this information.
|
You must have :attr:`~Permissions.manage_guild` to get this information.
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
-------
|
-------
|
||||||
|
@ -458,7 +458,7 @@ class Member(discord.abc.Messageable):
|
|||||||
|
|
||||||
Moves a member to a new voice channel (they must be connected first).
|
Moves a member to a new voice channel (they must be connected first).
|
||||||
|
|
||||||
You must have the :attr:`Permissions.move_members` permission to
|
You must have the :attr:`~Permissions.move_members` permission to
|
||||||
use this.
|
use this.
|
||||||
|
|
||||||
This raises the same exceptions as :meth:`edit`.
|
This raises the same exceptions as :meth:`edit`.
|
||||||
@ -478,7 +478,7 @@ class Member(discord.abc.Messageable):
|
|||||||
|
|
||||||
Gives the member a number of :class:`Role`\s.
|
Gives the member a number of :class:`Role`\s.
|
||||||
|
|
||||||
You must have the :attr:`Permissions.manage_roles` permission to
|
You must have the :attr:`~Permissions.manage_roles` permission to
|
||||||
use this.
|
use this.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@ -505,7 +505,7 @@ class Member(discord.abc.Messageable):
|
|||||||
|
|
||||||
Removes :class:`Role`\s from this member.
|
Removes :class:`Role`\s from this member.
|
||||||
|
|
||||||
You must have the :attr:`Permissions.manage_roles` permission to
|
You must have the :attr:`~Permissions.manage_roles` permission to
|
||||||
use this.
|
use this.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
@ -413,7 +413,7 @@ class Message:
|
|||||||
Deletes the message.
|
Deletes the message.
|
||||||
|
|
||||||
Your own messages could be deleted without any proper permissions. However to
|
Your own messages could be deleted without any proper permissions. However to
|
||||||
delete other people's messages, you need the :attr:`Permissions.manage_messages`
|
delete other people's messages, you need the :attr:`~Permissions.manage_messages`
|
||||||
permission.
|
permission.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@ -475,7 +475,7 @@ class Message:
|
|||||||
def pin(self):
|
def pin(self):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Pins the message. You must have :attr:`Permissions.manage_messages`
|
Pins the message. You must have :attr:`~Permissions.manage_messages`
|
||||||
permissions to do this in a non-private channel context.
|
permissions to do this in a non-private channel context.
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
@ -496,7 +496,7 @@ class Message:
|
|||||||
def unpin(self):
|
def unpin(self):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
|
||||||
Unpins the message. You must have :attr:`Permissions.manage_messages`
|
Unpins the message. You must have :attr:`~Permissions.manage_messages`
|
||||||
permissions to do this in a non-private channel context.
|
permissions to do this in a non-private channel context.
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
@ -520,8 +520,8 @@ class Message:
|
|||||||
|
|
||||||
The emoji may be a unicode emoji or a custom guild :class:`Emoji`.
|
The emoji may be a unicode emoji or a custom guild :class:`Emoji`.
|
||||||
|
|
||||||
You must have the :attr:`Permissions.add_reactions` permission to
|
You must have the :attr:`~Permissions.add_reactions` and
|
||||||
add new reactions to a message.
|
:attr:`~Permissions.read_message_history` permissions to use this.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
------------
|
------------
|
||||||
@ -560,7 +560,7 @@ class Message:
|
|||||||
The emoji may be a unicode emoji or a custom guild :class:`Emoji`.
|
The emoji may be a unicode emoji or a custom guild :class:`Emoji`.
|
||||||
|
|
||||||
If the reaction is not your own (i.e. ``member`` parameter is not you) then
|
If the reaction is not your own (i.e. ``member`` parameter is not you) then
|
||||||
the :attr:`Permissions.manage_messages` permission is needed.
|
the :attr:`~Permissions.manage_messages` permission is needed.
|
||||||
|
|
||||||
The ``member`` parameter must represent a member and meet
|
The ``member`` parameter must represent a member and meet
|
||||||
the :class:`abc.Snowflake` abc.
|
the :class:`abc.Snowflake` abc.
|
||||||
@ -601,7 +601,7 @@ class Message:
|
|||||||
|
|
||||||
Removes all the reactions from the message.
|
Removes all the reactions from the message.
|
||||||
|
|
||||||
You need :attr:`Permissions.manage_messages` permission
|
You need :attr:`~Permissions.manage_messages` permission
|
||||||
to use this.
|
to use this.
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
|
@ -197,7 +197,7 @@ class ClientUser(BaseUser):
|
|||||||
The user's unique ID.
|
The user's unique ID.
|
||||||
discriminator: str
|
discriminator: str
|
||||||
The user's discriminator. This is given when the username has conflicts.
|
The user's discriminator. This is given when the username has conflicts.
|
||||||
avatar: str
|
avatar: Optional[str]
|
||||||
The avatar hash the user has. Could be None.
|
The avatar hash the user has. Could be None.
|
||||||
bot: bool
|
bot: bool
|
||||||
Specifies if the user is a bot account.
|
Specifies if the user is a bot account.
|
||||||
@ -404,7 +404,7 @@ class User(BaseUser, discord.abc.Messageable):
|
|||||||
The user's unique ID.
|
The user's unique ID.
|
||||||
discriminator: str
|
discriminator: str
|
||||||
The user's discriminator. This is given when the username has conflicts.
|
The user's discriminator. This is given when the username has conflicts.
|
||||||
avatar: str
|
avatar: Optional[str]
|
||||||
The avatar hash the user has. Could be None.
|
The avatar hash the user has. Could be None.
|
||||||
bot: bool
|
bot: bool
|
||||||
Specifies if the user is a bot account.
|
Specifies if the user is a bot account.
|
||||||
|
@ -62,8 +62,8 @@ from .player import AudioPlayer, AudioSource
|
|||||||
class VoiceClient:
|
class VoiceClient:
|
||||||
"""Represents a Discord voice connection.
|
"""Represents a Discord voice connection.
|
||||||
|
|
||||||
This client is created solely through :meth:`Client.join_voice_channel`
|
You do not create these, you typically get them from
|
||||||
and its only purpose is to transmit voice.
|
e.g. :meth:`VoiceChannel.connect`.
|
||||||
|
|
||||||
Warning
|
Warning
|
||||||
--------
|
--------
|
||||||
|
40
docs/_static/style.css
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
body {
|
||||||
|
font-family: Georgia, 'Hiragino Mincho Pro', serif;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code {
|
||||||
|
font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
code.descname, code.descclassname {
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
|
||||||
|
code.descname {
|
||||||
|
background-color: transparent;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, * pre {
|
||||||
|
padding: 7px 0 7px 30px !important;
|
||||||
|
margin: 15px 0 !important;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.warning {
|
||||||
|
background-color: #ffe6cc;
|
||||||
|
border: 1px solid #ffd5aa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't link-ify the FAQ page */
|
||||||
|
a.toc-backref {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #3E4349;
|
||||||
|
}
|
||||||
|
|
||||||
|
code.xref {
|
||||||
|
background-color: #ecf0f3;
|
||||||
|
border-bottom: 1px dotted #222;
|
||||||
|
}
|
411
docs/api.rst
@ -79,21 +79,22 @@ overriding the specific events. For example: ::
|
|||||||
import discord
|
import discord
|
||||||
|
|
||||||
class MyClient(discord.Client):
|
class MyClient(discord.Client):
|
||||||
|
async def on_message(self, message):
|
||||||
|
if message.author != self.user:
|
||||||
|
return
|
||||||
|
|
||||||
@asyncio.coroutine
|
if message.content.startswith('$hello'):
|
||||||
def on_message(self, message):
|
await message.channel.send('Hello World!')
|
||||||
yield from self.send_message(message.channel, 'Hello World!')
|
|
||||||
|
|
||||||
|
|
||||||
If an event handler raises an exception, :func:`on_error` will be called
|
If an event handler raises an exception, :func:`on_error` will be called
|
||||||
to handle it, which defaults to print a traceback and ignore the exception.
|
to handle it, which defaults to print a traceback and ignoring the exception.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
All the events must be a |corourl|_. If they aren't, then you might get unexpected
|
All the events must be a |corourl|_. If they aren't, then you might get unexpected
|
||||||
errors. In order to turn a function into a coroutine they must either be decorated
|
errors. In order to turn a function into a coroutine they must either be ``async def``
|
||||||
with ``@asyncio.coroutine`` or in Python 3.5+ be defined using the ``async def``
|
functions or in 3.4 decorated with ``@asyncio.coroutine``.
|
||||||
declaration.
|
|
||||||
|
|
||||||
The following two functions are examples of coroutine functions: ::
|
The following two functions are examples of coroutine functions: ::
|
||||||
|
|
||||||
@ -104,14 +105,6 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
def on_ready():
|
def on_ready():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
Since this can be a potentially common mistake, there is a helper
|
|
||||||
decorator, :meth:`Client.async_event` to convert a basic function
|
|
||||||
into a coroutine and an event at the same time. Note that it is
|
|
||||||
not necessary if you use ``async def``.
|
|
||||||
|
|
||||||
.. versionadded:: 0.7.0
|
|
||||||
Subclassing to listen to events.
|
|
||||||
|
|
||||||
.. function:: on_connect()
|
.. function:: on_connect()
|
||||||
|
|
||||||
Called when the client has successfully connected to Discord. This is not
|
Called when the client has successfully connected to Discord. This is not
|
||||||
@ -164,48 +157,71 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
:param kwargs: The keyword arguments for the event that raised the
|
:param kwargs: The keyword arguments for the event that raised the
|
||||||
execption.
|
execption.
|
||||||
|
|
||||||
.. function:: on_message(message)
|
|
||||||
|
|
||||||
Called when a message is created and sent to a guild.
|
|
||||||
|
|
||||||
:param message: A :class:`Message` of the current message.
|
|
||||||
|
|
||||||
.. function:: on_socket_raw_receive(msg)
|
.. function:: on_socket_raw_receive(msg)
|
||||||
|
|
||||||
Called whenever a message is received from the websocket, before
|
Called whenever a message is received from the WebSocket, before
|
||||||
it's processed.This event is always dispatched when a message is
|
it's processed. This event is always dispatched when a message is
|
||||||
received and the passed data is not processed in any way.
|
received and the passed data is not processed in any way.
|
||||||
|
|
||||||
This is only really useful for grabbing the websocket stream and
|
This is only really useful for grabbing the WebSocket stream and
|
||||||
debugging purposes.
|
debugging purposes.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
This is only for the messages received from the client
|
This is only for the messages received from the client
|
||||||
websocket. The voice websocket will not trigger this event.
|
WebSocket. The voice WebSocket will not trigger this event.
|
||||||
|
|
||||||
:param msg: The message passed in from the websocket library.
|
:param msg: The message passed in from the WebSocket library.
|
||||||
Could be ``bytes`` for a binary message or ``str``
|
Could be ``bytes`` for a binary message or ``str``
|
||||||
for a regular message.
|
for a regular message.
|
||||||
|
|
||||||
.. function:: on_socket_raw_send(payload)
|
.. function:: on_socket_raw_send(payload)
|
||||||
|
|
||||||
Called whenever a send operation is done on the websocket before the
|
Called whenever a send operation is done on the WebSocket before the
|
||||||
message is sent. The passed parameter is the message that is to
|
message is sent. The passed parameter is the message that is being
|
||||||
sent to the websocket.
|
sent to the WebSocket.
|
||||||
|
|
||||||
This is only really useful for grabbing the websocket stream and
|
This is only really useful for grabbing the WebSocket stream and
|
||||||
debugging purposes.
|
debugging purposes.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
This is only for the messages received from the client
|
This is only for the messages received from the client
|
||||||
websocket. The voice websocket will not trigger this event.
|
WebSocket. The voice WebSocket will not trigger this event.
|
||||||
|
|
||||||
:param payload: The message that is about to be passed on to the
|
:param payload: The message that is about to be passed on to the
|
||||||
websocket library. It can be ``bytes`` to denote a binary
|
WebSocket library. It can be ``bytes`` to denote a binary
|
||||||
message or ``str`` to denote a regular text message.
|
message or ``str`` to denote a regular text message.
|
||||||
|
|
||||||
|
.. function:: on_typing(channel, user, when)
|
||||||
|
|
||||||
|
Called when someone begins typing a message.
|
||||||
|
|
||||||
|
The ``channel`` parameter can be a :class:`abc.Messageable` instance.
|
||||||
|
Which could either be :class:`TextChannel`, :class:`GroupChannel`, or
|
||||||
|
:class:`DMChannel`.
|
||||||
|
|
||||||
|
If the ``channel`` is a :class:`TextChannel` then the ``user`` parameter
|
||||||
|
is a :class:`Member`, otherwise it is a :class:`User`.
|
||||||
|
|
||||||
|
:param channel: The location where the typing originated from.
|
||||||
|
:param user: The user that started typing.
|
||||||
|
:param when: A ``datetime.datetime`` object representing when typing started.
|
||||||
|
|
||||||
|
.. function:: on_message(message)
|
||||||
|
|
||||||
|
Called when a :class:`Message` is created and sent.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Your bot's own messages and private messages are sent through this
|
||||||
|
event. This can lead cases of 'recursion' depending on how your bot was
|
||||||
|
programmed. If you want the bot to not reply to itself, consider
|
||||||
|
checking the user IDs. Note that :class:`~ext.commands.Bot` does not
|
||||||
|
have this problem.
|
||||||
|
|
||||||
|
:param message: A :class:`Message` of the current message.
|
||||||
|
|
||||||
.. function:: on_message_delete(message)
|
.. function:: on_message_delete(message)
|
||||||
|
|
||||||
Called when a message is deleted. If the message is not found in the
|
Called when a message is deleted. If the message is not found in the
|
||||||
@ -218,7 +234,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
|
|
||||||
.. function:: on_message_edit(before, after)
|
.. function:: on_message_edit(before, after)
|
||||||
|
|
||||||
Called when a message receives an update event. If the message is not found
|
Called when a :class:`Message` receives an update event. If the message is not found
|
||||||
in the :attr:`Client.messages` cache, then these events will not be called.
|
in the :attr:`Client.messages` cache, then these events will not be called.
|
||||||
This happens if the message is too old or the client is participating in high
|
This happens if the message is too old or the client is participating in high
|
||||||
traffic guilds. To fix this, increase the ``max_messages`` option of :class:`Client`.
|
traffic guilds. To fix this, increase the ``max_messages`` option of :class:`Client`.
|
||||||
@ -228,7 +244,9 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
- A message has been pinned or unpinned.
|
- A message has been pinned or unpinned.
|
||||||
- The message content has been changed.
|
- The message content has been changed.
|
||||||
- The message has received an embed.
|
- The message has received an embed.
|
||||||
- For performance reasons, the embed guild does not do this in a "consistent" manner.
|
|
||||||
|
- For performance reasons, the embed server does not do this in a "consistent" manner.
|
||||||
|
|
||||||
- A call message has received an update to its participants or ending time.
|
- A call message has received an update to its participants or ending time.
|
||||||
|
|
||||||
:param before: A :class:`Message` of the previous version of the message.
|
:param before: A :class:`Message` of the previous version of the message.
|
||||||
@ -242,7 +260,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
To get the message being reacted, access it via :attr:`Reaction.message`.
|
To get the :class:`Message` being reacted, access it via :attr:`Reaction.message`.
|
||||||
|
|
||||||
:param reaction: A :class:`Reaction` showing the current state of the reaction.
|
:param reaction: A :class:`Reaction` showing the current state of the reaction.
|
||||||
:param user: A :class:`User` or :class:`Member` of the user who added the reaction.
|
:param user: A :class:`User` or :class:`Member` of the user who added the reaction.
|
||||||
@ -269,29 +287,49 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
:param message: The :class:`Message` that had its reactions cleared.
|
:param message: The :class:`Message` that had its reactions cleared.
|
||||||
:param reactions: A list of :class:`Reaction`\s that were removed.
|
:param reactions: A list of :class:`Reaction`\s that were removed.
|
||||||
|
|
||||||
.. function:: on_channel_delete(channel)
|
.. function:: on_private_channel_delete(channel)
|
||||||
on_channel_create(channel)
|
on_private_channel_create(channel)
|
||||||
|
|
||||||
Called whenever a channel is removed or added from a guild.
|
Called whenever a private channel is deleted or created.
|
||||||
|
|
||||||
Note that you can get the guild from :attr:`Channel.guild`.
|
:param channel: The :class:`abc.PrivateChannel` that got created or deleted.
|
||||||
:func:`on_channel_create` could also pass in a :class:`PrivateChannel` depending
|
|
||||||
on the value of :attr:`Channel.is_private`.
|
|
||||||
|
|
||||||
:param channel: The :class:`Channel` that got added or deleted.
|
.. function:: on_private_channel_update(before, after)
|
||||||
|
|
||||||
.. function:: on_channel_update(before, after)
|
Called whenever a private group DM is updated. e.g. changed name or topic.
|
||||||
|
|
||||||
Called whenever a channel is updated. e.g. changed name, topic, permissions.
|
:param before: The :class:`GroupChannel` that got updated with the old info.
|
||||||
|
:param after: The :class:`GroupChannel` that got updated with the updated info.
|
||||||
|
|
||||||
:param before: The :class:`Channel` that got updated with the old info.
|
.. function:: on_private_channel_pins_update(channel, last_pin)
|
||||||
:param after: The :class:`Channel` that got updated with the updated info.
|
|
||||||
|
|
||||||
.. function:: on_channel_pins_update(channel, last_pin)
|
Called whenever a message is pinned or unpinned from a private channel.
|
||||||
|
|
||||||
Called whenever a message is pinned or unpinned from a channel.
|
:param channel: The :class:`abc.PrivateChannel` that had it's pins updated.
|
||||||
|
:param last_pin: A ``datetime.datetime`` object representing when the latest message
|
||||||
|
was pinned or ``None`` if there are no pins.
|
||||||
|
|
||||||
:param channel: The :class:`Channel` that had it's pins updated.
|
.. function:: on_guild_channel_delete(channel)
|
||||||
|
on_guild_channel_create(channel)
|
||||||
|
|
||||||
|
Called whenever a guild channel is deleted or created.
|
||||||
|
|
||||||
|
Note that you can get the guild from :attr:`~abc.GuildChannel.guild`.
|
||||||
|
|
||||||
|
:param channel: The :class:`abc.GuildChannel` that got created or deleted.
|
||||||
|
|
||||||
|
.. function:: on_guild_channel_update(before, after)
|
||||||
|
|
||||||
|
Called whenever a guild channel is updated. e.g. changed name, topic, permissions.
|
||||||
|
|
||||||
|
:param before: The :class:`abc.GuildChannel` that got updated with the old info.
|
||||||
|
:param after: The :class:`abc.GuildChannel` that got updated with the updated info.
|
||||||
|
|
||||||
|
.. function:: on_guild_channel_pins_update(channel, last_pin)
|
||||||
|
|
||||||
|
Called whenever a message is pinned or unpinned from a guild channel.
|
||||||
|
|
||||||
|
:param channel: The :class:`abc.GuildChannel` that had it's pins updated.
|
||||||
:param last_pin: A ``datetime.datetime`` object representing when the latest message
|
:param last_pin: A ``datetime.datetime`` object representing when the latest message
|
||||||
was pinned or ``None`` if there are no pins.
|
was pinned or ``None`` if there are no pins.
|
||||||
|
|
||||||
@ -368,10 +406,11 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
:param before: The :class:`Role` that updated with the old info.
|
:param before: The :class:`Role` that updated with the old info.
|
||||||
:param after: The :class:`Role` that updated with the updated info.
|
:param after: The :class:`Role` that updated with the updated info.
|
||||||
|
|
||||||
.. function:: on_guild_emojis_update(before, after)
|
.. function:: on_guild_emojis_update(guild, before, after)
|
||||||
|
|
||||||
Called when a :class:`Guild` adds or removes :class:`Emoji`.
|
Called when a :class:`Guild` adds or removes :class:`Emoji`.
|
||||||
|
|
||||||
|
:param guild: The :class:`Guild` who got their emojis updated.
|
||||||
:param before: A list of :class:`Emoji` before the update.
|
:param before: A list of :class:`Emoji` before the update.
|
||||||
:param after: A list of :class:`Emoji` after the update.
|
:param after: A list of :class:`Emoji` after the update.
|
||||||
|
|
||||||
@ -383,9 +422,9 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
|
|
||||||
:param guild: The :class:`Guild` that has changed availability.
|
:param guild: The :class:`Guild` that has changed availability.
|
||||||
|
|
||||||
.. function:: on_voice_state_update(before, after)
|
.. function:: on_voice_state_update(member, before, after)
|
||||||
|
|
||||||
Called when a :class:`Member` changes their voice state.
|
Called when a :class:`Member` changes their :class:`VoiceState`.
|
||||||
|
|
||||||
The following, but not limited to, examples illustrate when this event is called:
|
The following, but not limited to, examples illustrate when this event is called:
|
||||||
|
|
||||||
@ -394,35 +433,25 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
|||||||
- A member is muted or deafened by their own accord.
|
- A member is muted or deafened by their own accord.
|
||||||
- A member is muted or deafened by a guild administrator.
|
- A member is muted or deafened by a guild administrator.
|
||||||
|
|
||||||
:param before: The :class:`Member` whose voice state changed prior to the changes.
|
:param member: The :class:`Member` whose voice states changed.
|
||||||
:param after: The :class:`Member` whose voice state changed after the changes.
|
:param before: The :class:`VoiceState` prior to the changes.
|
||||||
|
:param after: The :class:`VoiceState` after to the changes.
|
||||||
|
|
||||||
.. function:: on_member_ban(member)
|
.. function:: on_member_ban(guild, user)
|
||||||
|
|
||||||
Called when a :class:`Member` gets banned from a :class:`Guild`.
|
Called when user gets banned from a :class:`Guild`.
|
||||||
|
|
||||||
You can access the guild that the member got banned from via :attr:`Member.guild`.
|
:param guild: The :class:`Guild` the user got banned from.
|
||||||
|
:param user: The user that got banned.
|
||||||
:param member: The member that got banned.
|
Can be either :class:`User` or :class:`Member` depending if
|
||||||
|
the user was in the guild or not at the time of removal.
|
||||||
|
|
||||||
.. function:: on_member_unban(guild, user)
|
.. function:: on_member_unban(guild, user)
|
||||||
|
|
||||||
Called when a :class:`User` gets unbanned from a :class:`Guild`.
|
Called when a :class:`User` gets unbanned from a :class:`Guild`.
|
||||||
|
|
||||||
:param guild: The guild the user got unbanned from.
|
:param guild: The :class:`Guild` the user got unbanned from.
|
||||||
:param user: The user that got unbanned.
|
:param user: The :class:`User` that got unbanned.
|
||||||
|
|
||||||
.. function:: on_typing(channel, user, when)
|
|
||||||
|
|
||||||
Called when someone begins typing a message.
|
|
||||||
|
|
||||||
The ``channel`` parameter could either be a :class:`PrivateChannel` or a
|
|
||||||
:class:`Channel`. If ``channel`` is a :class:`PrivateChannel` then the
|
|
||||||
``user`` parameter is a :class:`User`, otherwise it is a :class:`Member`.
|
|
||||||
|
|
||||||
:param channel: The location where the typing originated from.
|
|
||||||
:param user: The user that started typing.
|
|
||||||
:param when: A ``datetime.datetime`` object representing when typing started.
|
|
||||||
|
|
||||||
.. function:: on_group_join(channel, user)
|
.. function:: on_group_join(channel, user)
|
||||||
on_group_remove(channel, user)
|
on_group_remove(channel, user)
|
||||||
@ -1281,15 +1310,15 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
|
|
||||||
.. attribute:: owner
|
.. attribute:: owner
|
||||||
|
|
||||||
*Union[:class:`Member`, :class:`User`]`* – The guild's owner. See also :attr:`Guild.owner`
|
Union[:class:`Member`, :class:`User`] – The guild's owner. See also :attr:`Guild.owner`
|
||||||
|
|
||||||
.. attribute:: region
|
.. attribute:: region
|
||||||
|
|
||||||
*:class:`GuildRegion`* – The guild's voice region. See also :attr:`Guild.region`.
|
:class:`GuildRegion` – The guild's voice region. See also :attr:`Guild.region`.
|
||||||
|
|
||||||
.. attribute:: afk_channel
|
.. attribute:: afk_channel
|
||||||
|
|
||||||
*Union[:class:`VoiceChannel`, :class:`Object`]* – The guild's AFK channel.
|
Union[:class:`VoiceChannel`, :class:`Object`] – The guild's AFK channel.
|
||||||
|
|
||||||
If this could not be found, then it falls back to a :class:`Object`
|
If this could not be found, then it falls back to a :class:`Object`
|
||||||
with the ID being set.
|
with the ID being set.
|
||||||
@ -1310,20 +1339,20 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
|
|
||||||
.. attribute:: widget_channel
|
.. attribute:: widget_channel
|
||||||
|
|
||||||
*Union[:class:`TextChannel`, :class:`Object`]* – The widget's channel.
|
Union[:class:`TextChannel`, :class:`Object`] – The widget's channel.
|
||||||
|
|
||||||
If this could not be found then it falls back to a :class:`Object`
|
If this could not be found then it falls back to a :class:`Object`
|
||||||
with the ID being set.
|
with the ID being set.
|
||||||
|
|
||||||
.. attribute:: verification_level
|
.. attribute:: verification_level
|
||||||
|
|
||||||
*:class:`VerificationLevel`* – The guild's verification level.
|
:class:`VerificationLevel` – The guild's verification level.
|
||||||
|
|
||||||
See also :attr:`Guild.verification_level`.
|
See also :attr:`Guild.verification_level`.
|
||||||
|
|
||||||
.. attribute:: explicit_content_filter
|
.. attribute:: explicit_content_filter
|
||||||
|
|
||||||
*:class:`ContentFilter`* – The guild's content filter.
|
:class:`ContentFilter` – The guild's content filter.
|
||||||
|
|
||||||
See also :attr:`Guild.explicit_content_filter`.
|
See also :attr:`Guild.explicit_content_filter`.
|
||||||
|
|
||||||
@ -1365,7 +1394,7 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
|
|
||||||
.. attribute:: overwrites
|
.. attribute:: overwrites
|
||||||
|
|
||||||
*List[Tuple[target, :class:`PermissionOverwrite`]]* – A list of
|
List[Tuple[target, :class:`PermissionOverwrite`]] – A list of
|
||||||
permission overwrite tuples that represents a target and a
|
permission overwrite tuples that represents a target and a
|
||||||
:class:`PermissionOverwrite` for said target.
|
:class:`PermissionOverwrite` for said target.
|
||||||
|
|
||||||
@ -1377,7 +1406,7 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
|
|
||||||
.. attribute:: roles
|
.. attribute:: roles
|
||||||
|
|
||||||
*List[Union[:class:`Role`, :class:`Object`]]* – A list of roles being added or removed
|
List[Union[:class:`Role`, :class:`Object`]] – A list of roles being added or removed
|
||||||
from a member.
|
from a member.
|
||||||
|
|
||||||
If a role is not found then it is a :class:`Object` with the ID and name being
|
If a role is not found then it is a :class:`Object` with the ID and name being
|
||||||
@ -1403,14 +1432,14 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
|
|
||||||
.. attribute:: permissions
|
.. attribute:: permissions
|
||||||
|
|
||||||
*:class:`Permissions`* – The permissions of a role.
|
:class:`Permissions` – The permissions of a role.
|
||||||
|
|
||||||
See also :attr:`Role.permissions`.
|
See also :attr:`Role.permissions`.
|
||||||
|
|
||||||
.. attribute:: colour
|
.. attribute:: colour
|
||||||
color
|
color
|
||||||
|
|
||||||
*:class:`Colour`* – The colour of a role.
|
:class:`Colour` – The colour of a role.
|
||||||
|
|
||||||
See also :attr:`Role.colour`
|
See also :attr:`Role.colour`
|
||||||
|
|
||||||
@ -1434,14 +1463,14 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
|
|
||||||
.. attribute:: channel
|
.. attribute:: channel
|
||||||
|
|
||||||
*Union[:class:`abc.GuildChannel`, :class:`Object`]* – A guild channel.
|
Union[:class:`abc.GuildChannel`, :class:`Object`] – A guild channel.
|
||||||
|
|
||||||
If the channel is not found then it is a :class:`Object` with the ID
|
If the channel is not found then it is a :class:`Object` with the ID
|
||||||
being set. In some cases the channel name is also set.
|
being set. In some cases the channel name is also set.
|
||||||
|
|
||||||
.. attribute:: inviter
|
.. attribute:: inviter
|
||||||
|
|
||||||
*:class:`User`* – The user who created the invite.
|
:class:`User` – The user who created the invite.
|
||||||
|
|
||||||
See also :attr:`Invite.inviter`.
|
See also :attr:`Invite.inviter`.
|
||||||
|
|
||||||
@ -1472,7 +1501,7 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
.. attribute:: allow
|
.. attribute:: allow
|
||||||
deny
|
deny
|
||||||
|
|
||||||
*:class:`Permissions`* – The permissions being allowed or denied.
|
:class:`Permissions` – The permissions being allowed or denied.
|
||||||
|
|
||||||
.. attribute:: id
|
.. attribute:: id
|
||||||
|
|
||||||
@ -1487,43 +1516,72 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
|||||||
.. this is currently missing the following keys: reason and application_id
|
.. this is currently missing the following keys: reason and application_id
|
||||||
I'm not sure how to about porting these
|
I'm not sure how to about porting these
|
||||||
|
|
||||||
.. _discord_api_data:
|
.. _discord_api_abcs:
|
||||||
|
|
||||||
Data Classes
|
Abstract Base Classes
|
||||||
--------------
|
-----------------------
|
||||||
|
|
||||||
Some classes are just there to be data containers, this lists them.
|
An abstract base class (also known as an ``abc``) is a class that models can inherit
|
||||||
|
to get their behaviour. The Python implementation of an `abc <https://docs.python.org/3/library/abc.html>`_ is
|
||||||
|
slightly different in that you can register them at run-time. **Abstract base classes cannot be instantiated**.
|
||||||
|
They are mainly there for usage with ``isinstance`` and ``issubclass``\.
|
||||||
|
|
||||||
.. note::
|
This library has a module related to abstract base classes, some of which are actually from the ``abc`` standard
|
||||||
|
module, others which are not.
|
||||||
|
|
||||||
With the exception of :class:`Object`, :class:`Colour`, and :class:`Permissions` the
|
.. autoclass:: discord.abc.Snowflake
|
||||||
data classes listed below are **not intended to be created by users** and are also
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.abc.User
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.abc.PrivateChannel
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.abc.GuildChannel
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.abc.Messageable
|
||||||
|
:members:
|
||||||
|
:exclude-members: history typing
|
||||||
|
|
||||||
|
.. autocomethod:: discord.abc.Messageable.history
|
||||||
|
:async-for:
|
||||||
|
|
||||||
|
.. autocomethod:: discord.abc.Messageable.typing
|
||||||
|
:async-with:
|
||||||
|
|
||||||
|
.. autoclass:: discord.abc.Connectable
|
||||||
|
|
||||||
|
.. _discord_api_models:
|
||||||
|
|
||||||
|
Discord Models
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Models are classes that are received from Discord and are not meant to be created by
|
||||||
|
the user of the library.
|
||||||
|
|
||||||
|
.. danger::
|
||||||
|
|
||||||
|
The classes listed below are **not intended to be created by users** and are also
|
||||||
**read-only**.
|
**read-only**.
|
||||||
|
|
||||||
For example, this means that you should not make your own :class:`User` instances
|
For example, this means that you should not make your own :class:`User` instances
|
||||||
nor should you modify the :class:`User` instance yourself.
|
nor should you modify the :class:`User` instance yourself.
|
||||||
|
|
||||||
If you want to get one of these data classes instances they'd have to be through
|
If you want to get one of these model classes instances they'd have to be through
|
||||||
the cache, and a common way of doing so is through the :func:`utils.find` function
|
the cache, and a common way of doing so is through the :func:`utils.find` function
|
||||||
or attributes of data classes that you receive from the events specified in the
|
or attributes of model classes that you receive from the events specified in the
|
||||||
:ref:`discord-api-events`.
|
:ref:`discord-api-events`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
.. warning::
|
Nearly all classes here have ``__slots__`` defined which means that it is
|
||||||
|
impossible to have dynamic attributes to the data classes.
|
||||||
Nearly all data classes here have ``__slots__`` defined which means that it is
|
|
||||||
impossible to have dynamic attributes to the data classes. The only exception
|
|
||||||
to this rule is :class:`Object` which was designed with dynamic attributes in
|
|
||||||
mind.
|
|
||||||
|
|
||||||
More information about ``__slots__`` can be found
|
More information about ``__slots__`` can be found
|
||||||
`in the official python documentation <https://docs.python.org/3/reference/datamodel.html#slots>`_.
|
`in the official python documentation <https://docs.python.org/3/reference/datamodel.html#slots>`_.
|
||||||
|
|
||||||
Object
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: Object
|
|
||||||
:members:
|
|
||||||
|
|
||||||
ClientUser
|
ClientUser
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
@ -1544,6 +1602,13 @@ User
|
|||||||
.. autoclass:: User
|
.. autoclass:: User
|
||||||
:members:
|
:members:
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
|
:exclude-members: history typing
|
||||||
|
|
||||||
|
.. autocomethod:: history
|
||||||
|
:async-for:
|
||||||
|
|
||||||
|
.. autocomethod:: typing
|
||||||
|
:async-with:
|
||||||
|
|
||||||
Message
|
Message
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
@ -1556,18 +1621,10 @@ Reaction
|
|||||||
|
|
||||||
.. autoclass:: Reaction
|
.. autoclass:: Reaction
|
||||||
:members:
|
:members:
|
||||||
|
:exclude-members: users
|
||||||
|
|
||||||
Embed
|
.. autocomethod:: users
|
||||||
~~~~~~
|
:async-for:
|
||||||
|
|
||||||
.. autoclass:: Embed
|
|
||||||
:members:
|
|
||||||
|
|
||||||
File
|
|
||||||
~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: File
|
|
||||||
:members:
|
|
||||||
|
|
||||||
CallMessage
|
CallMessage
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
@ -1586,6 +1643,10 @@ Guild
|
|||||||
|
|
||||||
.. autoclass:: Guild
|
.. autoclass:: Guild
|
||||||
:members:
|
:members:
|
||||||
|
:exclude-members: audit_logs
|
||||||
|
|
||||||
|
.. autocomethod:: audit_logs
|
||||||
|
:async-for:
|
||||||
|
|
||||||
Member
|
Member
|
||||||
~~~~~~
|
~~~~~~
|
||||||
@ -1593,6 +1654,13 @@ Member
|
|||||||
.. autoclass:: Member
|
.. autoclass:: Member
|
||||||
:members:
|
:members:
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
|
:exclude-members: history typing
|
||||||
|
|
||||||
|
.. autocomethod:: history
|
||||||
|
:async-for:
|
||||||
|
|
||||||
|
.. autocomethod:: typing
|
||||||
|
:async-with:
|
||||||
|
|
||||||
VoiceState
|
VoiceState
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
@ -1600,18 +1668,6 @@ VoiceState
|
|||||||
.. autoclass:: VoiceState
|
.. autoclass:: VoiceState
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
Colour
|
|
||||||
~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: Colour
|
|
||||||
:members:
|
|
||||||
|
|
||||||
Game
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
.. autoclass:: Game
|
|
||||||
:members:
|
|
||||||
|
|
||||||
Emoji
|
Emoji
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
@ -1624,25 +1680,19 @@ Role
|
|||||||
.. autoclass:: Role
|
.. autoclass:: Role
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
Permissions
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: Permissions
|
|
||||||
:members:
|
|
||||||
|
|
||||||
PermissionOverwrite
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: PermissionOverwrite
|
|
||||||
:members:
|
|
||||||
|
|
||||||
|
|
||||||
TextChannel
|
TextChannel
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
.. autoclass:: TextChannel
|
.. autoclass:: TextChannel
|
||||||
:members:
|
:members:
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
|
:exclude-members: history typing
|
||||||
|
|
||||||
|
.. autocomethod:: history
|
||||||
|
:async-for:
|
||||||
|
|
||||||
|
.. autocomethod:: typing
|
||||||
|
:async-with:
|
||||||
|
|
||||||
VoiceChannel
|
VoiceChannel
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
@ -1657,6 +1707,13 @@ DMChannel
|
|||||||
.. autoclass:: DMChannel
|
.. autoclass:: DMChannel
|
||||||
:members:
|
:members:
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
|
:exclude-members: history typing
|
||||||
|
|
||||||
|
.. autocomethod:: history
|
||||||
|
:async-for:
|
||||||
|
|
||||||
|
.. autocomethod:: typing
|
||||||
|
:async-with:
|
||||||
|
|
||||||
GroupChannel
|
GroupChannel
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
@ -1664,6 +1721,13 @@ GroupChannel
|
|||||||
.. autoclass:: GroupChannel
|
.. autoclass:: GroupChannel
|
||||||
:members:
|
:members:
|
||||||
:inherited-members:
|
:inherited-members:
|
||||||
|
:exclude-members: history typing
|
||||||
|
|
||||||
|
.. autocomethod:: history
|
||||||
|
:async-for:
|
||||||
|
|
||||||
|
.. autocomethod:: typing
|
||||||
|
:async-with:
|
||||||
|
|
||||||
|
|
||||||
Invite
|
Invite
|
||||||
@ -1672,6 +1736,69 @@ Invite
|
|||||||
.. autoclass:: Invite
|
.. autoclass:: Invite
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
.. _discord_api_data:
|
||||||
|
|
||||||
|
Data Classes
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Some classes are just there to be data containers, this lists them.
|
||||||
|
|
||||||
|
Unlike :ref:`models <discord_api_models>` you are allowed to create
|
||||||
|
these yourself, even if they can also be used to hold attributes.
|
||||||
|
|
||||||
|
Nearly all classes here have ``__slots__`` defined which means that it is
|
||||||
|
impossible to have dynamic attributes to the data classes.
|
||||||
|
|
||||||
|
The only exception to this rule is :class:`Object`, which is made with
|
||||||
|
dynamic attributes in mind.
|
||||||
|
|
||||||
|
More information about ``__slots__`` can be found
|
||||||
|
`in the official python documentation <https://docs.python.org/3/reference/datamodel.html#slots>`_.
|
||||||
|
|
||||||
|
|
||||||
|
Object
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: Object
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Embed
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: Embed
|
||||||
|
:members:
|
||||||
|
|
||||||
|
File
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: File
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Colour
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: Colour
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Game
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
.. autoclass:: Game
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Permissions
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: Permissions
|
||||||
|
:members:
|
||||||
|
|
||||||
|
PermissionOverwrite
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: PermissionOverwrite
|
||||||
|
:members:
|
||||||
|
|
||||||
|
|
||||||
Exceptions
|
Exceptions
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
10
docs/conf.py
@ -34,6 +34,7 @@ sys.path.insert(0, os.path.abspath('..'))
|
|||||||
extensions = [
|
extensions = [
|
||||||
'sphinx.ext.autodoc',
|
'sphinx.ext.autodoc',
|
||||||
'sphinx.ext.extlinks',
|
'sphinx.ext.extlinks',
|
||||||
|
'sphinxcontrib.asyncio'
|
||||||
]
|
]
|
||||||
|
|
||||||
if on_rtd:
|
if on_rtd:
|
||||||
@ -115,7 +116,7 @@ exclude_patterns = ['_build']
|
|||||||
#show_authors = False
|
#show_authors = False
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
pygments_style = 'sphinx'
|
pygments_style = 'friendly'
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
# A list of ignored prefixes for module index sorting.
|
||||||
#modindex_common_prefix = []
|
#modindex_common_prefix = []
|
||||||
@ -128,7 +129,7 @@ pygments_style = 'sphinx'
|
|||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
html_theme = 'sphinx_rtd_theme'
|
html_theme = 'alabaster'
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
@ -159,7 +160,7 @@ html_theme = 'sphinx_rtd_theme'
|
|||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
# html_static_path = ['_static']
|
html_static_path = ['_static']
|
||||||
|
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
@ -304,3 +305,6 @@ texinfo_documents = [
|
|||||||
|
|
||||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||||
#texinfo_no_detailmenu = False
|
#texinfo_no_detailmenu = False
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_stylesheet('style.css')
|
||||||
|
92
docs/discord.rst
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
.. _discord-intro:
|
||||||
|
|
||||||
|
Creating a Bot Account
|
||||||
|
========================
|
||||||
|
|
||||||
|
In order to work with the library and the Discord API in general, we must first create a Discord Bot account.
|
||||||
|
|
||||||
|
Creating a Bot account is a pretty straightforward process.
|
||||||
|
|
||||||
|
1. Make sure you're logged on to the `Discord website <https://discordapp.com>`_.
|
||||||
|
2. Navigate to the `application page <https://discordapp.com/developers/applications/me>`_
|
||||||
|
3. Click on the "New App" button.
|
||||||
|
|
||||||
|
.. image:: /images/discord_new_app_button.png
|
||||||
|
:alt: The new app button.
|
||||||
|
|
||||||
|
4. Give the application a name and a description if wanted and click "Create App".
|
||||||
|
|
||||||
|
- You can also put an avatar you want your bot to use, don't worry you can change this later.
|
||||||
|
- **Leave the Redirect URI(s) blank** unless are creating a service.
|
||||||
|
|
||||||
|
.. image:: /images/discord_new_app_form.png
|
||||||
|
:alt: The new application form filled in.
|
||||||
|
5. Create a Bot User by clicking on the accompanying button and confirming it.
|
||||||
|
|
||||||
|
.. image:: /images/discord_create_bot_user_button.png
|
||||||
|
:alt: The Create a Bot User button.
|
||||||
|
6. Make sure that **Public Bot** is ticked if you want others to invite your bot.
|
||||||
|
|
||||||
|
- You should also make sure that **Require OAuth2 Code Grant** is unchecked unless you
|
||||||
|
are developing a service that needs it. If you're unsure, then **leave it unchecked**.
|
||||||
|
|
||||||
|
.. figure:: /images/discord_finished_bot_user.png
|
||||||
|
|
||||||
|
How the Bot User options should look like for most people.
|
||||||
|
|
||||||
|
7. Click to reveal the token.
|
||||||
|
|
||||||
|
- **This is not the Client Secret**
|
||||||
|
|
||||||
|
.. figure:: /images/discord_reveal_token.png
|
||||||
|
|
||||||
|
How the token reveal button looks like.
|
||||||
|
|
||||||
|
And that's it. You now have a bot account and you can login with that token.
|
||||||
|
|
||||||
|
.. _discord_invite_bot:
|
||||||
|
|
||||||
|
Inviting Your Bot
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
So you've made a Bot User but it's not actually in any server.
|
||||||
|
|
||||||
|
If you want to invite your bot you must create an invite URL for your bot.
|
||||||
|
|
||||||
|
First, you must fetch the Client ID of the Bot. You can find this in the Bot's application page.
|
||||||
|
|
||||||
|
.. image:: /images/discord_client_id.png
|
||||||
|
:alt: The Bot's Client ID.
|
||||||
|
|
||||||
|
Copy paste that into the pre-formatted URL:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
https://discordapp.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot&permissions=0
|
||||||
|
|
||||||
|
Replace ``YOUR_CLIENT_ID`` with the Client ID we got in the previous step. For example,
|
||||||
|
in the image above our client ID is 312718641634213889 so the resulting URL would be
|
||||||
|
https://discordapp.com/oauth2/authorize?client_id=312718641634213889&scope=bot&permissions=0
|
||||||
|
(note that this bot has been deleted).
|
||||||
|
|
||||||
|
Now you can click the link and invite your bot to any server you have "Manage Server" permissions on.
|
||||||
|
|
||||||
|
Adding Permissions
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
In the above URL, you might have noticed an interesting bit, the ``permissions=0`` fragment.
|
||||||
|
|
||||||
|
Bot accounts can request specific permissions to be granted upon joining. When the bot joins
|
||||||
|
the guild, they will be granted a managed role that contains the permissions you requested.
|
||||||
|
If the permissions is 0, then no special role is created.
|
||||||
|
|
||||||
|
This ``permissions`` value is calculated based on bit-wise arithmetic. Thankfully, people have
|
||||||
|
created a calculate that makes it easy to calculate the permissions necessary visually.
|
||||||
|
|
||||||
|
- https://discordapi.com/permissions.html
|
||||||
|
- https://finitereality.github.io/permissions/
|
||||||
|
|
||||||
|
Feel free to use whichever is easier for you to grasp.
|
||||||
|
|
||||||
|
If you want to generate this URL dynamically at run-time inside your bot and using the
|
||||||
|
:class:`discord.Permissions` interface, you can use :func:`discord.utils.oauth_url`.
|
197
docs/ext/commands/api.rst
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
.. currentmodule:: discord
|
||||||
|
|
||||||
|
API Reference
|
||||||
|
===============
|
||||||
|
|
||||||
|
The following section outlines the API of discord.py's command extension module.
|
||||||
|
|
||||||
|
Bot
|
||||||
|
----
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.Bot
|
||||||
|
:members:
|
||||||
|
:inherited-members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.AutoShardedBot
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Event Reference
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
These events function similar to :ref:`the regular events <discord-api-events>`, except they
|
||||||
|
are custom to the command extension module.
|
||||||
|
|
||||||
|
.. function:: on_command_error(ctx, error)
|
||||||
|
|
||||||
|
An error handler that is called when an error is raised
|
||||||
|
inside a command either through user input error, check
|
||||||
|
failure, or an error in your own code.
|
||||||
|
|
||||||
|
A default one is provided (:meth:`.Bot.on_command_error`).
|
||||||
|
|
||||||
|
:param ctx: The invocation context.
|
||||||
|
:type ctx: :class:`Context`
|
||||||
|
:param error: The error that was raised.
|
||||||
|
:type error: :class:`CommandError` derived
|
||||||
|
|
||||||
|
.. function:: on_command(ctx)
|
||||||
|
|
||||||
|
An event that is called when a command is found and is about to be invoked.
|
||||||
|
|
||||||
|
This event is called regardless of whether the command itself succeeds via
|
||||||
|
error or completes.
|
||||||
|
|
||||||
|
:param ctx: The invocation context.
|
||||||
|
:type ctx: :class:`Context`
|
||||||
|
|
||||||
|
.. function:: on_command_completion(ctx)
|
||||||
|
|
||||||
|
An event that is called when a command has completed its invocation.
|
||||||
|
|
||||||
|
This event is called only if the command succeeded, i.e. all checks have
|
||||||
|
passed and the user input it correctly.
|
||||||
|
|
||||||
|
:param ctx: The invocation context.
|
||||||
|
:type ctx: :class:`Context`
|
||||||
|
|
||||||
|
|
||||||
|
Command
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.command
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.group
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.Command
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.Group
|
||||||
|
:members:
|
||||||
|
:inherited-members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.GroupMixin
|
||||||
|
:members:
|
||||||
|
|
||||||
|
|
||||||
|
Formatters
|
||||||
|
-----------
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.Paginator
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.HelpFormatter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Checks
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.check
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.has_role
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.has_permissions
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.has_any_role
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.bot_has_role
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.bot_has_permissions
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.bot_has_any_role
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.cooldown
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.guild_only
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.is_owner
|
||||||
|
|
||||||
|
.. autofunction:: discord.ext.commands.is_nsfw
|
||||||
|
|
||||||
|
Context
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.Context
|
||||||
|
:members:
|
||||||
|
:exclude-members: history typing
|
||||||
|
|
||||||
|
.. autocomethod:: discord.ext.commands.Context.history
|
||||||
|
:async-for:
|
||||||
|
|
||||||
|
.. autocomethod:: discord.ext.commands.Context.typing
|
||||||
|
:async-with:
|
||||||
|
|
||||||
|
Converters
|
||||||
|
------------
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.Converter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.MemberConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.UserConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.TextChannelConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.InviteConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.RoleConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.GameConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.ColourConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.VoiceChannelConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.EmojiConverter
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.clean_content
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Errors
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.CommandError
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.MissingRequiredArgument
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.BadArgument
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.NoPrivateMessage
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.CheckFailure
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.CommandNotFound
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.DisabledCommand
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.CommandInvokeError
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.TooManyArguments
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.UserInputError
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.CommandOnCooldown
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoexception:: discord.ext.commands.NotOwner
|
||||||
|
:members:
|
||||||
|
|
13
docs/ext/commands/index.rst
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
``discord.ext.commands`` -- Bot commands framework
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
``discord.py`` offers a lower level aspect on interacting with Discord. Often times, the library is used for the creation of
|
||||||
|
bots. However this task can be daunting and confusing to get correctly the first time. Many times there comes a repetition in
|
||||||
|
creating a bot command framework that is extensible, flexible, and powerful. For this reason, ``discord.py`` comes with an
|
||||||
|
extension library that handles this for you.
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
api
|
176
docs/faq.rst
@ -16,7 +16,7 @@ Coroutines
|
|||||||
Questions regarding coroutines and asyncio belong here.
|
Questions regarding coroutines and asyncio belong here.
|
||||||
|
|
||||||
I get a SyntaxError around the word ``async``\! What should I do?
|
I get a SyntaxError around the word ``async``\! What should I do?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
This ``SyntaxError`` happens because you're using a Python version lower than 3.5. Python 3.4 uses ``@asyncio.coroutine`` and
|
This ``SyntaxError`` happens because you're using a Python version lower than 3.5. Python 3.4 uses ``@asyncio.coroutine`` and
|
||||||
``yield from`` instead of ``async def`` and ``await``.
|
``yield from`` instead of ``async def`` and ``await``.
|
||||||
@ -52,7 +52,7 @@ Where can I use ``await``\?
|
|||||||
You can only use ``await`` inside ``async def`` functions and nowhere else.
|
You can only use ``await`` inside ``async def`` functions and nowhere else.
|
||||||
|
|
||||||
What does "blocking" mean?
|
What does "blocking" mean?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
In asynchronous programming a blocking call is essentially all the parts of the function that are not ``await``. Do not
|
In asynchronous programming a blocking call is essentially all the parts of the function that are not ``await``. Do not
|
||||||
despair however, because not all forms of blocking are bad! Using blocking calls is inevitable, but you must work to make
|
despair however, because not all forms of blocking are bad! Using blocking calls is inevitable, but you must work to make
|
||||||
@ -78,13 +78,14 @@ Consider the following example: ::
|
|||||||
r = requests.get('http://random.cat/meow')
|
r = requests.get('http://random.cat/meow')
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
js = r.json()
|
js = r.json()
|
||||||
await client.send_message(channel, js['file'])
|
await channel.send(js['file'])
|
||||||
|
|
||||||
# good
|
# good
|
||||||
async with aiohttp.get('http://random.cat/meow') as r:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get('http://random.cat/meow') as r:
|
||||||
if r.status == 200:
|
if r.status == 200:
|
||||||
js = await r.json()
|
js = await r.json()
|
||||||
await client.send_message(channel, js['file'])
|
await channel.send(js['file'])
|
||||||
|
|
||||||
General
|
General
|
||||||
---------
|
---------
|
||||||
@ -103,37 +104,41 @@ following: ::
|
|||||||
How do I send a message to a specific channel?
|
How do I send a message to a specific channel?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you have its ID then you can do this in two ways, first is by using :class:`Object`\: ::
|
You must fetch the channel directly and then call the appropriate method. Example: ::
|
||||||
|
|
||||||
await client.send_message(discord.Object(id='12324234183172'), 'hello')
|
channel = client.get_channel('12324234183172')
|
||||||
|
await channel.send('hello')
|
||||||
The second way is by calling :meth:`Client.get_channel` directly: ::
|
|
||||||
|
|
||||||
await client.send_message(client.get_channel('12324234183172'), 'hello')
|
|
||||||
|
|
||||||
I'm passing IDs as integers and things are not working!
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
In the library IDs must be of type ``str`` not of type ``int``. Wrap it in quotes.
|
|
||||||
|
|
||||||
How do I upload an image?
|
How do I upload an image?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
There are two ways of doing it. Both of which involve using :meth:`Client.send_file`.
|
To upload something to Discord you have to use the :class:`File` object.
|
||||||
|
|
||||||
The first is by opening the file and passing it directly: ::
|
A :class:`File` accepts two parameters, the file-like object (or file path) and the filename
|
||||||
|
to pass to Discord when uploading.
|
||||||
|
|
||||||
with open('my_image.png', 'rb') as f:
|
If you want to upload an image it's as simple as: ::
|
||||||
await client.send_file(channel, f)
|
|
||||||
|
|
||||||
The second is by passing the file name directly: ::
|
await channel.send(file=discord.File('my_file.png'))
|
||||||
|
|
||||||
|
If you have a file-like object you can do as follows: ::
|
||||||
|
|
||||||
|
with open('my_file.png', 'rb') as fp:
|
||||||
|
await channel.send(file=discord.File(fp, 'new_filename.png'))
|
||||||
|
|
||||||
|
To upload multiple files, you can use the ``files`` keyword argument instead of ``file``\: ::
|
||||||
|
|
||||||
|
my_files = [
|
||||||
|
discord.File('result.zip'),
|
||||||
|
discord.File('teaser_graph.png'),
|
||||||
|
]
|
||||||
|
await channel.send(files=my_files)
|
||||||
|
|
||||||
await client.send_file(channel, 'my_image.png')
|
|
||||||
|
|
||||||
How can I add a reaction to a message?
|
How can I add a reaction to a message?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
You use the :meth:`Client.add_reaction` method.
|
You use the :meth:`Message.add_reaction` method.
|
||||||
|
|
||||||
If you want to use unicode emoji, you must pass a valid unicode code point in a string. In your code, you can write this in a few different ways:
|
If you want to use unicode emoji, you must pass a valid unicode code point in a string. In your code, you can write this in a few different ways:
|
||||||
|
|
||||||
@ -141,16 +146,32 @@ If you want to use unicode emoji, you must pass a valid unicode code point in a
|
|||||||
- ``'\U0001F44D'``
|
- ``'\U0001F44D'``
|
||||||
- ``'\N{THUMBS UP SIGN}'``
|
- ``'\N{THUMBS UP SIGN}'``
|
||||||
|
|
||||||
In case you want to use emoji that come from a message, you already get their code points in the content without needing to do anything special.
|
Quick example: ::
|
||||||
You **cannot** send ``':thumbsup:'`` style shorthands.
|
|
||||||
|
|
||||||
For custom emoji, you should pass an instance of :class:`discord.Emoji`. You can also pass a ``'name:id'`` string, but if you can use said emoji,
|
await message.add_reaction('\N{THUMBS UP SIGN}')
|
||||||
you should be able to use :meth:`Client.get_all_emojis`/:attr:`Server.emojis` to find the one you're looking for.
|
|
||||||
|
In case you want to use emoji that come from a message, you already get their code points in the content without needing
|
||||||
|
to do anything special. You **cannot** send ``':thumbsup:'`` style shorthands.
|
||||||
|
|
||||||
|
For custom emoji, you should pass an instance of :class:`Emoji`. You can also pass a ``'name:id'`` string, but if you
|
||||||
|
can use said emoji, you should be able to use :meth:`Client.get_emoji` to get an emoji via ID or use :func:`utils.find`/
|
||||||
|
:func:`utils.get` on :attr:`Client.emojis` or :attr:`Guild.emojis` collections.
|
||||||
|
|
||||||
|
Quick example: ::
|
||||||
|
|
||||||
|
# if you have the ID already
|
||||||
|
emoji = client.get_emoji(310177266011340803)
|
||||||
|
await message.add_reaction(emoji)
|
||||||
|
|
||||||
|
# no ID, do a lookup
|
||||||
|
emoji = discord.utils.get(guild.emojis, name='LUL')
|
||||||
|
if emoji:
|
||||||
|
await message.add_reaction(emoji)
|
||||||
|
|
||||||
How do I pass a coroutine to the player's "after" function?
|
How do I pass a coroutine to the player's "after" function?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A StreamPlayer is just a ``threading.Thread`` object that plays music. As a result it does not execute inside a coroutine.
|
The library's music player launches on a separate thread, ergo it does not execute inside a coroutine.
|
||||||
This does not mean that it is not possible to call a coroutine in the ``after`` parameter. To do so you must pass a callable
|
This does not mean that it is not possible to call a coroutine in the ``after`` parameter. To do so you must pass a callable
|
||||||
that wraps up a couple of aspects.
|
that wraps up a couple of aspects.
|
||||||
|
|
||||||
@ -169,7 +190,7 @@ However, this function returns a ``concurrent.Future`` and to actually call it w
|
|||||||
this together we can do the following: ::
|
this together we can do the following: ::
|
||||||
|
|
||||||
def my_after():
|
def my_after():
|
||||||
coro = client.send_message(some_channel, 'Song is done!')
|
coro = some_channel.send('Song is done!')
|
||||||
fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
|
fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
|
||||||
try:
|
try:
|
||||||
fut.result()
|
fut.result()
|
||||||
@ -177,48 +198,44 @@ this together we can do the following: ::
|
|||||||
# an error happened sending the message
|
# an error happened sending the message
|
||||||
pass
|
pass
|
||||||
|
|
||||||
player = await voice.create_ytdl_player(url, after=my_after)
|
voice.play(discord.FFmpegPCMAudio(url), after=my_after)
|
||||||
player.start()
|
|
||||||
|
|
||||||
Why is my "after" function being called right away?
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``after`` keyword argument expects a *function object* to be passed in. Similar to how ``threading.Thread`` expects a
|
|
||||||
callable in its ``target`` keyword argument. This means that the following are invalid:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
player = await voice.create_ytdl_player(url, after=self.foo())
|
|
||||||
other = await voice.create_ytdl_player(url, after=self.bar(10))
|
|
||||||
|
|
||||||
However the following are correct:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
player = await voice.create_ytdl_player(url, after=self.foo)
|
|
||||||
other = await voice.create_ytdl_player(url, after=lambda: self.bar(10))
|
|
||||||
|
|
||||||
Basically, these functions should not be called.
|
|
||||||
|
|
||||||
|
|
||||||
How do I run something in the background?
|
How do I run something in the background?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
`Check the background_task.py example. <https://github.com/Rapptz/discord.py/blob/master/examples/background_task.py>`_
|
`Check the background_task.py example. <https://github.com/Rapptz/discord.py/blob/rewrite/examples/background_task.py>`_
|
||||||
|
|
||||||
How do I get a specific User/Role/Channel/Server?
|
How do I get a specific model?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
There are multiple ways of doing this. If you have a specific entity's ID then you can use
|
There are multiple ways of doing this. If you have a specific model's ID then you can use
|
||||||
one of the following functions:
|
one of the following functions:
|
||||||
|
|
||||||
- :meth:`Client.get_channel`
|
- :meth:`Client.get_channel`
|
||||||
- :meth:`Client.get_server`
|
- :meth:`Client.get_guild`
|
||||||
- :meth:`Server.get_member`
|
- :meth:`Client.get_user`
|
||||||
- :meth:`Server.get_channel`
|
- :meth:`Client.get_emoji`
|
||||||
|
- :meth:`Guild.get_member`
|
||||||
|
- :meth:`Guild.get_channel`
|
||||||
|
|
||||||
|
The following use an HTTP request:
|
||||||
|
|
||||||
|
- :meth:`abc.Messageable.get_message`
|
||||||
|
- :meth:`Client.get_user_info`
|
||||||
|
|
||||||
|
|
||||||
If the functions above do not help you, then use of :func:`utils.find` or :func:`utils.get` would serve some use in finding
|
If the functions above do not help you, then use of :func:`utils.find` or :func:`utils.get` would serve some use in finding
|
||||||
specific entities. The documentation for those functions provide specific examples.
|
specific models.
|
||||||
|
|
||||||
|
Quick example: ::
|
||||||
|
|
||||||
|
# find a guild by name
|
||||||
|
guild = discord.utils.get(client.guilds, name='My Server')
|
||||||
|
|
||||||
|
# make sure to check if it's found
|
||||||
|
if guild is not None:
|
||||||
|
# find a channel by name
|
||||||
|
channel = discord.utils.get(guild.text_channels, name='cool-channel')
|
||||||
|
|
||||||
Commands Extension
|
Commands Extension
|
||||||
-------------------
|
-------------------
|
||||||
@ -229,10 +246,10 @@ Is there any documentation for this?
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Not at the moment. Writing documentation for stuff takes time. A lot of people get by reading the docstrings in the source
|
Not at the moment. Writing documentation for stuff takes time. A lot of people get by reading the docstrings in the source
|
||||||
code. Others get by via asking questions in the `Discord server <https://discord.gg/0SBTUU1wZTXZNJPa>`_. Others look at the
|
code. Others get by via asking questions in the `Discord server <https://discord.gg/discord-api>`_. Others look at the
|
||||||
source code of `other existing bots <https://github.com/Rapptz/RoboDanny>`_.
|
source code of `other existing bots <https://github.com/Rapptz/RoboDanny>`_.
|
||||||
|
|
||||||
There is a `basic example <https://github.com/Rapptz/discord.py/blob/master/examples/basic_bot.py>`_ showcasing some
|
There is a `basic example <https://github.com/Rapptz/discord.py/blob/rewrite/examples/basic_bot.py>`_ showcasing some
|
||||||
functionality.
|
functionality.
|
||||||
|
|
||||||
**Documentation is being worked on, it will just take some time to polish it**.
|
**Documentation is being worked on, it will just take some time to polish it**.
|
||||||
@ -249,42 +266,36 @@ Overriding the default provided ``on_message`` forbids any extra commands from r
|
|||||||
|
|
||||||
await bot.process_commands(message)
|
await bot.process_commands(message)
|
||||||
|
|
||||||
Can I use ``bot.say`` in other places aside from commands?
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
No. They only work inside commands due to the way the magic involved works.
|
|
||||||
|
|
||||||
Why do my arguments require quotes?
|
Why do my arguments require quotes?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
In a simple command defined as: ::
|
In a simple command defined as: ::
|
||||||
|
|
||||||
@bot.command()
|
@bot.command()
|
||||||
async def echo(message: str):
|
async def echo(ctx, message: str):
|
||||||
await bot.say(message)
|
await ctx.send(message)
|
||||||
|
|
||||||
Calling it via ``?echo a b c`` will only fetch the first argument and disregard the rest. To fix this you should either call
|
Calling it via ``?echo a b c`` will only fetch the first argument and disregard the rest. To fix this you should either call
|
||||||
it via ``?echo "a b c"`` or change the signature to have "consume rest" behaviour. Example: ::
|
it via ``?echo "a b c"`` or change the signature to have "consume rest" behaviour. Example: ::
|
||||||
|
|
||||||
@bot.command()
|
@bot.command()
|
||||||
async def echo(*, message: str):
|
async def echo(ctx, *, message: str):
|
||||||
await bot.say(message)
|
await ctx.send(message)
|
||||||
|
|
||||||
This will allow you to use ``?echo a b c`` without needing the quotes.
|
This will allow you to use ``?echo a b c`` without needing the quotes.
|
||||||
|
|
||||||
How do I get the original ``message``\?
|
How do I get the original ``message``\?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Ask the command to pass you the invocation context via ``pass_context``. This context will be passed as the first parameter.
|
The :class:`~ext.commands.Context` contains an attribute, :attr:`~ext.commands.Context.message` to get the original
|
||||||
|
message.
|
||||||
|
|
||||||
Example: ::
|
Example: ::
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
@bot.command()
|
||||||
async def joined_at(ctx, member: discord.Member = None):
|
async def joined_at(ctx, member: discord.Member = None):
|
||||||
if member is None:
|
member = member or ctx.author
|
||||||
member = ctx.message.author
|
await ctx.send('{0} joined at {0.joined_at}'.format(member))
|
||||||
|
|
||||||
await bot.say('{0} joined at {0.joined_at}'.format(member))
|
|
||||||
|
|
||||||
How do I make a subcommand?
|
How do I make a subcommand?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -294,15 +305,14 @@ the group operating as "subcommands". These groups can be arbitrarily nested as
|
|||||||
|
|
||||||
Example: ::
|
Example: ::
|
||||||
|
|
||||||
@bot.group(pass_context=True)
|
@bot.group()
|
||||||
async def git(ctx):
|
async def git(ctx):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await bot.say('Invalid git command passed...')
|
await bot.say('Invalid git command passed...')
|
||||||
|
|
||||||
@git.command()
|
@git.command()
|
||||||
async def push(remote: str, branch: str):
|
async def push(ctx, remote: str, branch: str):
|
||||||
await bot.say('Pushing to {} {}'.format(remote, branch))
|
await ctx.send('Pushing to {} {}'.format(remote, branch))
|
||||||
|
|
||||||
|
|
||||||
This could then be used as ``?git push origin master``.
|
This could then be used as ``?git push origin master``.
|
||||||
|
|
||||||
|
BIN
docs/images/discord_client_id.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
docs/images/discord_create_bot_user_button.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
docs/images/discord_finished_bot_user.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
docs/images/discord_new_app_button.PNG
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
docs/images/discord_new_app_form.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
docs/images/discord_reveal_token.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
docs/images/snake.png
Normal file
After Width: | Height: | Size: 28 KiB |
@ -3,23 +3,55 @@
|
|||||||
You can adapt this file completely to your liking, but it should at least
|
You can adapt this file completely to your liking, but it should at least
|
||||||
contain the root `toctree` directive.
|
contain the root `toctree` directive.
|
||||||
|
|
||||||
Welcome to discord.py's documentation!
|
Welcome to the discord.py documentation
|
||||||
======================================
|
=========================================
|
||||||
|
|
||||||
Contents:
|
.. image:: /images/snake.png
|
||||||
|
|
||||||
|
discord.py is a modern, easy to use, feature-rich, and async ready API wrapper
|
||||||
|
for Discord.
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
|
||||||
|
- Modern Pythonic API using ``async``\/``await`` syntax
|
||||||
|
- Sane rate limit handling that prevents 429s
|
||||||
|
- Implements the entirety of the Discord API
|
||||||
|
- Command extension to aid with bot creation
|
||||||
|
- Easy to use with an object oriented design
|
||||||
|
- Optimised for both speed and memory
|
||||||
|
|
||||||
|
Documentation Contents
|
||||||
|
-----------------------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
logging
|
intro
|
||||||
whats_new
|
quickstart
|
||||||
migrating
|
migrating
|
||||||
|
logging
|
||||||
api
|
api
|
||||||
|
|
||||||
|
Extensions
|
||||||
|
-----------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
ext/commands/index.rst
|
||||||
|
|
||||||
|
|
||||||
|
Additional Information
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
discord
|
||||||
faq
|
faq
|
||||||
|
whats_new
|
||||||
|
|
||||||
|
If you still can't find what you're looking for, try in one of the following pages:
|
||||||
Indices and tables
|
|
||||||
==================
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
* :ref:`genindex`
|
||||||
* :ref:`modindex`
|
* :ref:`modindex`
|
||||||
|
112
docs/intro.rst
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
.. currentmodule:: discord
|
||||||
|
|
||||||
|
.. _intro:
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
==============
|
||||||
|
|
||||||
|
This is the documentation for discord.py, a library for Python to aid
|
||||||
|
in creating applications that utilise the Discord API.
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
---------------
|
||||||
|
|
||||||
|
discord.py works with Python 3.4.2 or higher. Support for earlier versions of Python
|
||||||
|
is not provided. Python 2.7 or lower is not supported. Python 3.3 is not supported
|
||||||
|
due to one of the dependencies (``aiohttp``) not supporting Python 3.3.
|
||||||
|
|
||||||
|
|
||||||
|
.. _installing:
|
||||||
|
|
||||||
|
Installing
|
||||||
|
-----------
|
||||||
|
|
||||||
|
You can get the library directly from PyPI: ::
|
||||||
|
|
||||||
|
python3 -m pip install -U discord.py
|
||||||
|
|
||||||
|
If you are using Windows, then the following should be used instead: ::
|
||||||
|
|
||||||
|
py -3 -m pip install -U discord.py
|
||||||
|
|
||||||
|
|
||||||
|
To get voice support, you should use ``discord.py[voice]`` instead of ``discord.py``, e.g. ::
|
||||||
|
|
||||||
|
python3 -m pip install -U discord.py[voice]
|
||||||
|
|
||||||
|
On Linux environments, installing voice requires getting the following dependencies:
|
||||||
|
|
||||||
|
- libffi
|
||||||
|
- libnacl
|
||||||
|
- python3-dev
|
||||||
|
|
||||||
|
For a debian-based system, the following command will help get those dependencies:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ apt install libffi-dev libnacl-dev python3-dev
|
||||||
|
|
||||||
|
Remember to check your permissions!
|
||||||
|
|
||||||
|
Virtual Environments
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sometimes we don't want to pollute our system installs with a library or we want to maintain
|
||||||
|
different versions of a library than the currently system installed one. Or we don't have permissions to
|
||||||
|
install a library along side with the system installed ones. For this purpose, the standard library as
|
||||||
|
of 3.3 comes with a concept called "Virtual Environment" to help maintain these separate versions.
|
||||||
|
|
||||||
|
A more in-depth tutorial is found on `the official documentation. <https://docs.python.org/3/tutorial/venv.html>`_
|
||||||
|
|
||||||
|
However, for the quick and dirty:
|
||||||
|
|
||||||
|
1. Go to your project's working directory:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ cd your-bot-source
|
||||||
|
$ python3 -m venv bot-env
|
||||||
|
|
||||||
|
2. Activate the virtual environment:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ source bot-env/bin/activate
|
||||||
|
|
||||||
|
On Windows you activate it with:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ bot-env\Scripts\activate.bat
|
||||||
|
|
||||||
|
3. Use pip like usual:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ pip install -U discord.py
|
||||||
|
|
||||||
|
Congratulations. You now have a virtual environment all set up without messing with your system installation.
|
||||||
|
|
||||||
|
Basic Concepts
|
||||||
|
---------------
|
||||||
|
|
||||||
|
discord.py revolves around the concept of :ref:`events <discord-api-events>`.
|
||||||
|
An event is something you listen to and then respond to. For example, when a message
|
||||||
|
happens, you will receive an event about it and you can then respond to it.
|
||||||
|
|
||||||
|
A quick example to showcase how events work:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import discord
|
||||||
|
|
||||||
|
class MyClient(discord.Client):
|
||||||
|
async def on_ready(self):
|
||||||
|
print('Logged on as {0}!'.format(self.user))
|
||||||
|
|
||||||
|
async def on_message(self, message):
|
||||||
|
print('Message from {0.author}: {0.content}'.format(message))
|
||||||
|
|
||||||
|
client = MyClient()
|
||||||
|
client.run('my token goes here')
|
||||||
|
|
1153
docs/migrating.rst
322
docs/migrating_to_async.rst
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
:orphan:
|
||||||
|
|
||||||
|
.. currentmodule:: discord
|
||||||
|
|
||||||
|
.. _migrating-to-async:
|
||||||
|
|
||||||
|
Migrating to v0.10.0
|
||||||
|
======================
|
||||||
|
|
||||||
|
v0.10.0 is one of the biggest breaking changes in the library due to massive
|
||||||
|
fundamental changes in how the library operates.
|
||||||
|
|
||||||
|
The biggest major change is that the library has dropped support to all versions prior to
|
||||||
|
Python 3.4.2. This was made to support ``asyncio``, in which more detail can be seen
|
||||||
|
:issue:`in the corresponding issue <50>`. To reiterate this, the implication is that
|
||||||
|
**python version 2.7 and 3.3 are no longer supported**.
|
||||||
|
|
||||||
|
Below are all the other major changes from v0.9.0 to v0.10.0.
|
||||||
|
|
||||||
|
Event Registration
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
All events before were registered using :meth:`Client.event`. While this is still
|
||||||
|
possible, the events must be decorated with ``@asyncio.coroutine``.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@client.event
|
||||||
|
def on_message(message):
|
||||||
|
pass
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@client.event
|
||||||
|
@asyncio.coroutine
|
||||||
|
def on_message(message):
|
||||||
|
pass
|
||||||
|
|
||||||
|
Or in Python 3.5+:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@client.event
|
||||||
|
async def on_message(message):
|
||||||
|
pass
|
||||||
|
|
||||||
|
Because there is a lot of typing, a utility decorator (:meth:`Client.async_event`) is provided
|
||||||
|
for easier registration. For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@client.async_event
|
||||||
|
def on_message(message):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
Be aware however, that this is still a coroutine and your other functions that are coroutines must
|
||||||
|
be decorated with ``@asyncio.coroutine`` or be ``async def``.
|
||||||
|
|
||||||
|
Event Changes
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Some events in v0.9.0 were considered pretty useless due to having no separate states. The main
|
||||||
|
events that were changed were the ``_update`` events since previously they had no context on what
|
||||||
|
was changed.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def on_channel_update(channel): pass
|
||||||
|
def on_member_update(member): pass
|
||||||
|
def on_status(member): pass
|
||||||
|
def on_server_role_update(role): pass
|
||||||
|
def on_voice_state_update(member): pass
|
||||||
|
def on_socket_raw_send(payload, is_binary): pass
|
||||||
|
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def on_channel_update(before, after): pass
|
||||||
|
def on_member_update(before, after): pass
|
||||||
|
def on_server_role_update(before, after): pass
|
||||||
|
def on_voice_state_update(before, after): pass
|
||||||
|
def on_socket_raw_send(payload): pass
|
||||||
|
|
||||||
|
Note that ``on_status`` was removed. If you want its functionality, use :func:`on_member_update`.
|
||||||
|
See :ref:`discord-api-events` for more information. Other removed events include ``on_socket_closed``, ``on_socket_receive``, and ``on_socket_opened``.
|
||||||
|
|
||||||
|
|
||||||
|
Coroutines
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The biggest change that the library went through is that almost every function in :class:`Client`
|
||||||
|
was changed to be a `coroutine <https://docs.python.org/3/library/asyncio-task.html>`_. Functions
|
||||||
|
that are marked as a coroutine in the documentation must be awaited from or yielded from in order
|
||||||
|
for the computation to be done. For example...
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
client.send_message(message.channel, 'Hello')
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
yield from client.send_message(message.channel, 'Hello')
|
||||||
|
|
||||||
|
# or in python 3.5+
|
||||||
|
await client.send_message(message.channel, 'Hello')
|
||||||
|
|
||||||
|
In order for you to ``yield from`` or ``await`` a coroutine then your function must be decorated
|
||||||
|
with ``@asyncio.coroutine`` or ``async def``.
|
||||||
|
|
||||||
|
Iterables
|
||||||
|
----------
|
||||||
|
|
||||||
|
For performance reasons, many of the internal data structures were changed into a dictionary to support faster
|
||||||
|
lookup. As a consequence, this meant that some lists that were exposed via the API have changed into iterables
|
||||||
|
and not sequences. In short, this means that certain attributes now only support iteration and not any of the
|
||||||
|
sequence functions.
|
||||||
|
|
||||||
|
The affected attributes are as follows:
|
||||||
|
|
||||||
|
- :attr:`Client.servers`
|
||||||
|
- :attr:`Client.private_channels`
|
||||||
|
- :attr:`Server.channels`
|
||||||
|
- :attr:`Server.members`
|
||||||
|
|
||||||
|
Some examples of previously valid behaviour that is now invalid
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
if client.servers[0].name == "test":
|
||||||
|
# do something
|
||||||
|
|
||||||
|
Since they are no longer ``list``\s, they no longer support indexing or any operation other than iterating.
|
||||||
|
In order to get the old behaviour you should explicitly cast it to a list.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
servers = list(client.servers)
|
||||||
|
# work with servers
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Due to internal changes of the structure, the order you receive the data in
|
||||||
|
is not in a guaranteed order.
|
||||||
|
|
||||||
|
Enumerations
|
||||||
|
------------
|
||||||
|
|
||||||
|
Due to dropping support for versions lower than Python 3.4.2, the library can now use
|
||||||
|
`enumerations <https://docs.python.org/3/library/enum.html>`_ in places where it makes sense.
|
||||||
|
|
||||||
|
The common places where this was changed was in the server region, member status, and channel type.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
server.region == 'us-west'
|
||||||
|
member.status == 'online'
|
||||||
|
channel.type == 'text'
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
server.region == discord.ServerRegion.us_west
|
||||||
|
member.status = discord.Status.online
|
||||||
|
channel.type == discord.ChannelType.text
|
||||||
|
|
||||||
|
The main reason for this change was to reduce the use of finicky strings in the API as this
|
||||||
|
could give users a false sense of power. More information can be found in the :ref:`discord-api-enums` page.
|
||||||
|
|
||||||
|
Properties
|
||||||
|
-----------
|
||||||
|
|
||||||
|
A lot of function calls that returned constant values were changed into Python properties for ease of use
|
||||||
|
in format strings.
|
||||||
|
|
||||||
|
The following functions were changed into properties:
|
||||||
|
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| Before | After |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``User.avatar_url()`` | :attr:`User.avatar_url` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``User.mention()`` | :attr:`User.mention` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Channel.mention()`` | :attr:`Channel.mention` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Channel.is_default_channel()`` | :attr:`Channel.is_default` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Role.is_everyone()`` | :attr:`Role.is_everyone` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Server.get_default_role()`` | :attr:`Server.default_role` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Server.icon_url()`` | :attr:`Server.icon_url` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Server.get_default_channel()`` | :attr:`Server.default_channel` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Message.get_raw_mentions()`` | :attr:`Message.raw_mentions` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
| ``Message.get_raw_channel_mentions()`` | :attr:`Message.raw_channel_mentions` |
|
||||||
|
+----------------------------------------+--------------------------------------+
|
||||||
|
|
||||||
|
Member Management
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Functions that involved banning and kicking were changed.
|
||||||
|
|
||||||
|
+--------------------------------+--------------------------+
|
||||||
|
| Before | After |
|
||||||
|
+--------------------------------+--------------------------+
|
||||||
|
| ``Client.ban(server, user)`` | ``Client.ban(member)`` |
|
||||||
|
+--------------------------------+--------------------------+
|
||||||
|
| ``Client.kick(server, user)`` | ``Client.kick(member)`` |
|
||||||
|
+--------------------------------+--------------------------+
|
||||||
|
|
||||||
|
.. migrating-renames:
|
||||||
|
|
||||||
|
Renamed Functions
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Functions have been renamed.
|
||||||
|
|
||||||
|
+------------------------------------+-------------------------------------------+
|
||||||
|
| Before | After |
|
||||||
|
+------------------------------------+-------------------------------------------+
|
||||||
|
| ``Client.set_channel_permissions`` | :meth:`Client.edit_channel_permissions` |
|
||||||
|
+------------------------------------+-------------------------------------------+
|
||||||
|
|
||||||
|
All the :class:`Permissions` related attributes have been renamed and the `can_` prefix has been
|
||||||
|
dropped. So for example, ``can_manage_messages`` has become ``manage_messages``.
|
||||||
|
|
||||||
|
Forced Keyword Arguments
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Since 3.0+ of Python, we can now force questions to take in forced keyword arguments. A keyword argument is when you
|
||||||
|
explicitly specify the name of the variable and assign to it, for example: ``foo(name='test')``. Due to this support,
|
||||||
|
some functions in the library were changed to force things to take said keyword arguments. This is to reduce errors of
|
||||||
|
knowing the argument order and the issues that could arise from them.
|
||||||
|
|
||||||
|
The following parameters are now exclusively keyword arguments:
|
||||||
|
|
||||||
|
- :meth:`Client.send_message`
|
||||||
|
- ``tts``
|
||||||
|
- :meth:`Client.logs_from`
|
||||||
|
- ``before``
|
||||||
|
- ``after``
|
||||||
|
- :meth:`Client.edit_channel_permissions`
|
||||||
|
- ``allow``
|
||||||
|
- ``deny``
|
||||||
|
|
||||||
|
In the documentation you can tell if a function parameter is a forced keyword argument if it is after ``\*,``
|
||||||
|
in the function signature.
|
||||||
|
|
||||||
|
.. _migrating-running:
|
||||||
|
|
||||||
|
Running the Client
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
In earlier versions of discord.py, ``client.run()`` was a blocking call to the main thread
|
||||||
|
that called it. In v0.10.0 it is still a blocking call but it handles the event loop for you.
|
||||||
|
However, in order to do that you must pass in your credentials to :meth:`Client.run`.
|
||||||
|
|
||||||
|
Basically, before:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
client.login('token')
|
||||||
|
client.run()
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
client.run('token')
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Like in the older ``Client.run`` function, the newer one must be the one of
|
||||||
|
the last functions to call. This is because the function is **blocking**. Registering
|
||||||
|
events or doing anything after :meth:`Client.run` will not execute until the function
|
||||||
|
returns.
|
||||||
|
|
||||||
|
This is a utility function that abstracts the event loop for you. There's no need for
|
||||||
|
the run call to be blocking and out of your control. Indeed, if you want control of the
|
||||||
|
event loop then doing so is quite straightforward:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import discord
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
client = discord.Client()
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def main_task():
|
||||||
|
yield from client.login('token')
|
||||||
|
yield from client.connect()
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
try:
|
||||||
|
loop.run_until_complete(main_task())
|
||||||
|
except:
|
||||||
|
loop.run_until_complete(client.logout())
|
||||||
|
finally:
|
||||||
|
loop.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
76
docs/quickstart.rst
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
.. _quickstart:
|
||||||
|
|
||||||
|
.. currentmodule:: discord
|
||||||
|
|
||||||
|
Quickstart
|
||||||
|
============
|
||||||
|
|
||||||
|
This page gives a brief introduction to the library. It assumes you have the library installed,
|
||||||
|
if you don't check the :ref:`installing` portion.
|
||||||
|
|
||||||
|
A Minimal Bot
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Let's make a bot that replies to a specific message and walk you through it.
|
||||||
|
|
||||||
|
It looks something like this:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import discord
|
||||||
|
|
||||||
|
client = discord.Client()
|
||||||
|
|
||||||
|
@client.event
|
||||||
|
async def on_ready():
|
||||||
|
print('We have logged in as {0.user}'.format(self))
|
||||||
|
|
||||||
|
@client.event
|
||||||
|
async def on_message(message):
|
||||||
|
if message.author == client.user:
|
||||||
|
return
|
||||||
|
|
||||||
|
if message.content.startswith('$hello'):
|
||||||
|
await message.channel.send('Hello!')
|
||||||
|
|
||||||
|
client.run('your token here')
|
||||||
|
|
||||||
|
Let's name this file ``example_bot.py``. Make sure not to name it ``discord.py`` as that'll conflict
|
||||||
|
with the library.
|
||||||
|
|
||||||
|
There's a lot going on here, so let's walk you through it step by step.
|
||||||
|
|
||||||
|
1. The first line just imports the library, if this raises a `ModuleNotFoundError` or `ImportError`
|
||||||
|
then head on over to :ref:`installing` section to properly install.
|
||||||
|
2. Next, we create an instance of a :class:`Client`. This client is our connection to Discord.
|
||||||
|
3. We then use the :meth:`Client.event` decorator to register an event. This library has many events.
|
||||||
|
Since this library is asynchronous, we do things in a "callback" style manner.
|
||||||
|
|
||||||
|
A callback is essentially a function that is called when something happens. In our case,
|
||||||
|
the :func:`on_ready` event is called when the bot has finished logging in and setting things
|
||||||
|
up and the :func:`on_message` event is called when the bot has received a message.
|
||||||
|
4. Since the :func:`on_message` event triggers for *every* message received, we have to make
|
||||||
|
sure that we ignore messages from ourselves. We do this by checking if the :attr:`Message.author`
|
||||||
|
is the same as the :attr:`Client.user`.
|
||||||
|
5. Afterwards, we check if the :class:`Message.content` starts with ``'$hello'``. If it is,
|
||||||
|
then we reply in the channel it was used in with ``'Hello!'``.
|
||||||
|
6. Finally, we run the bot with our login token. If you need help getting your token or creating a bot,
|
||||||
|
look in the :ref:`discord-intro` section.
|
||||||
|
|
||||||
|
|
||||||
|
Now that we've made a bot, we have to *run* the bot. Luckily, this is simple since this is just a
|
||||||
|
Python script, we can run it directly.
|
||||||
|
|
||||||
|
On Windows:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ py -3 example_bot.py
|
||||||
|
|
||||||
|
On other systems:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
$ python3 example_bot.py
|
||||||
|
|
||||||
|
Now you can try playing around with your basic bot.
|
@ -2,12 +2,26 @@
|
|||||||
|
|
||||||
.. _whats_new:
|
.. _whats_new:
|
||||||
|
|
||||||
What's New
|
Changelog
|
||||||
============
|
============
|
||||||
|
|
||||||
This page keeps a detailed human friendly rendering of what's new and changed
|
This page keeps a detailed human friendly rendering of what's new and changed
|
||||||
in specific versions.
|
in specific versions.
|
||||||
|
|
||||||
|
.. _vp0p16p6:
|
||||||
|
|
||||||
|
v0.16.6
|
||||||
|
--------
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
- Fix issue with :meth:`Client.create_server` that made it stop working.
|
||||||
|
- Fix main thread being blocked upon calling ``StreamPlayer.stop``.
|
||||||
|
- Handle HEARTBEAT_ACK and resume gracefully when it occurs.
|
||||||
|
- Fix race condition when pre-emptively rate limiting that caused releasing an already released lock.
|
||||||
|
- Fix invalid state errors when immediately cancelling a coroutine.
|
||||||
|
|
||||||
.. _vp0p16p1:
|
.. _vp0p16p1:
|
||||||
|
|
||||||
v0.16.1
|
v0.16.1
|
||||||
|
2
setup.py
@ -9,6 +9,7 @@ with open('requirements.txt') as f:
|
|||||||
|
|
||||||
if on_rtd:
|
if on_rtd:
|
||||||
requirements.append('sphinxcontrib-napoleon')
|
requirements.append('sphinxcontrib-napoleon')
|
||||||
|
requirements.append('sphinxcontrib-asyncio')
|
||||||
|
|
||||||
version = ''
|
version = ''
|
||||||
with open('discord/__init__.py') as f:
|
with open('discord/__init__.py') as f:
|
||||||
@ -35,6 +36,7 @@ with open('README.md') as f:
|
|||||||
|
|
||||||
extras_require = {
|
extras_require = {
|
||||||
'voice': ['PyNaCl==1.0.1'],
|
'voice': ['PyNaCl==1.0.1'],
|
||||||
|
'docs': ['sphinxcontrib-asyncio']
|
||||||
}
|
}
|
||||||
|
|
||||||
setup(name='discord.py',
|
setup(name='discord.py',
|
||||||
|