mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-20 16:00:29 +00:00
[commands] Add custom exception classes for built-in checks
Added: * MissingRole * BotMissingRole * MissingAnyRole * BotMissingAnyRole
This commit is contained in:
parent
746e20a826
commit
bb3ebc0ebc
@ -1302,6 +1302,15 @@ def has_role(item):
|
||||
If the message is invoked in a private message context then the check will
|
||||
return ``False``.
|
||||
|
||||
This check raises one of two special exceptions, :exc:`.MissingRole` if the user
|
||||
is missing a role, or :exc:`.NoPrivateMessage` if it is used in a private message.
|
||||
Both inherit from :exc:`.CheckFailure`.
|
||||
|
||||
.. versionchanged:: 1.1.0
|
||||
|
||||
Raise :exc:`.MissingRole` or :exc:`.NoPrivateMessage`
|
||||
instead of generic :exc:`.CheckFailure`
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
item: Union[:class:`int`, :class:`str`]
|
||||
@ -1310,13 +1319,15 @@ def has_role(item):
|
||||
|
||||
def predicate(ctx):
|
||||
if not isinstance(ctx.channel, discord.abc.GuildChannel):
|
||||
return False
|
||||
raise NoPrivateMessage()
|
||||
|
||||
if isinstance(item, int):
|
||||
role = discord.utils.get(ctx.author.roles, id=item)
|
||||
else:
|
||||
role = discord.utils.get(ctx.author.roles, name=item)
|
||||
return role is not None
|
||||
if role is None:
|
||||
raise MissingRole(item)
|
||||
return True
|
||||
|
||||
return check(predicate)
|
||||
|
||||
@ -1327,6 +1338,15 @@ def has_any_role(*items):
|
||||
|
||||
Similar to :func:`.has_role`\, the names or IDs passed in must be exact.
|
||||
|
||||
This check raises one of two special exceptions, :exc:`.MissingAnyRole` if the user
|
||||
is missing all roles, or :exc:`.NoPrivateMessage` if it is used in a private message.
|
||||
Both inherit from :exc:`.CheckFailure`.
|
||||
|
||||
.. versionchanged:: 1.1.0
|
||||
|
||||
Raise :exc:`.MissingAnyRole` or :exc:`.NoPrivateMessage`
|
||||
instead of generic :exc:`.CheckFailure`
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
items: List[Union[:class:`str`, :class:`int`]]
|
||||
@ -1344,10 +1364,67 @@ def has_any_role(*items):
|
||||
"""
|
||||
def predicate(ctx):
|
||||
if not isinstance(ctx.channel, discord.abc.GuildChannel):
|
||||
return False
|
||||
raise NoPrivateMessage()
|
||||
|
||||
getter = functools.partial(discord.utils.get, ctx.author.roles)
|
||||
return any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items)
|
||||
if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items):
|
||||
return True
|
||||
raise MissingAnyRole(items)
|
||||
|
||||
return check(predicate)
|
||||
|
||||
def bot_has_role(item):
|
||||
"""Similar to :func:`.has_role` except checks if the bot itself has the
|
||||
role.
|
||||
|
||||
This check raises one of two special exceptions, :exc:`.BotMissingRole` if the bot
|
||||
is missing the role, or :exc:`.NoPrivateMessage` if it is used in a private message.
|
||||
Both inherit from :exc:`.CheckFailure`.
|
||||
|
||||
.. versionchanged:: 1.1.0
|
||||
|
||||
Raise :exc:`.BotMissingRole` or :exc:`.NoPrivateMessage`
|
||||
instead of generic :exc:`.CheckFailure`
|
||||
"""
|
||||
|
||||
def predicate(ctx):
|
||||
ch = ctx.channel
|
||||
if not isinstance(ch, discord.abc.GuildChannel):
|
||||
raise NoPrivateMessage()
|
||||
|
||||
me = ch.guild.me
|
||||
if isinstance(item, int):
|
||||
role = discord.utils.get(me.roles, id=item)
|
||||
else:
|
||||
role = discord.utils.get(me.roles, name=item)
|
||||
if role is None:
|
||||
raise BotMissingRole(item)
|
||||
return True
|
||||
return check(predicate)
|
||||
|
||||
def bot_has_any_role(*items):
|
||||
"""Similar to :func:`.has_any_role` except checks if the bot itself has
|
||||
any of the roles listed.
|
||||
|
||||
This check raises one of two special exceptions, :exc:`.BotMissingAnyRole` if the bot
|
||||
is missing all roles, or :exc:`.NoPrivateMessage` if it is used in a private message.
|
||||
Both inherit from :exc:`.CheckFailure`.
|
||||
|
||||
.. versionchanged:: 1.1.0
|
||||
|
||||
Raise :exc:`.BotMissingAnyRole` or :exc:`.NoPrivateMessage`
|
||||
instead of generic checkfailure
|
||||
"""
|
||||
def predicate(ctx):
|
||||
ch = ctx.channel
|
||||
if not isinstance(ch, discord.abc.GuildChannel):
|
||||
raise NoPrivateMessage()
|
||||
|
||||
me = ch.guild.me
|
||||
getter = functools.partial(discord.utils.get, me.roles)
|
||||
if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items):
|
||||
return True
|
||||
raise BotMissingAnyRole(items)
|
||||
return check(predicate)
|
||||
|
||||
def has_permissions(**perms):
|
||||
@ -1389,36 +1466,6 @@ def has_permissions(**perms):
|
||||
|
||||
return check(predicate)
|
||||
|
||||
def bot_has_role(item):
|
||||
"""Similar to :func:`.has_role` except checks if the bot itself has the
|
||||
role.
|
||||
"""
|
||||
|
||||
def predicate(ctx):
|
||||
ch = ctx.channel
|
||||
if not isinstance(ch, discord.abc.GuildChannel):
|
||||
return False
|
||||
me = ch.guild.me
|
||||
if isinstance(item, int):
|
||||
role = discord.utils.get(me.roles, id=item)
|
||||
else:
|
||||
role = discord.utils.get(me.roles, name=item)
|
||||
return role is not None
|
||||
return check(predicate)
|
||||
|
||||
def bot_has_any_role(*items):
|
||||
"""Similar to :func:`.has_any_role` except checks if the bot itself has
|
||||
any of the roles listed.
|
||||
"""
|
||||
def predicate(ctx):
|
||||
ch = ctx.channel
|
||||
if not isinstance(ch, discord.abc.GuildChannel):
|
||||
return False
|
||||
me = ch.guild.me
|
||||
getter = functools.partial(discord.utils.get, me.roles)
|
||||
return any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items)
|
||||
return check(predicate)
|
||||
|
||||
def bot_has_permissions(**perms):
|
||||
"""Similar to :func:`.has_permissions` except checks if the bot itself has
|
||||
the permissions listed.
|
||||
@ -1469,7 +1516,7 @@ def guild_only():
|
||||
|
||||
def predicate(ctx):
|
||||
if ctx.guild is None:
|
||||
raise NoPrivateMessage('This command cannot be used in private messages.')
|
||||
raise NoPrivateMessage()
|
||||
return True
|
||||
|
||||
return check(predicate)
|
||||
@ -1492,9 +1539,20 @@ def is_owner():
|
||||
return check(predicate)
|
||||
|
||||
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.
|
||||
|
||||
This check raises a special exception, :exc:`.NSFWChannelRequired`
|
||||
that is derived from :exc:`.CheckFailure`.
|
||||
|
||||
.. versionchanged:: 1.1.0
|
||||
|
||||
Raise :exc:`.NSFWChannelRequired instead of generic :exc:`.CheckFailure`.`
|
||||
"""
|
||||
def pred(ctx):
|
||||
return isinstance(ctx.channel, discord.TextChannel) and ctx.channel.is_nsfw()
|
||||
ch = ctx.channel
|
||||
if isinstance(ch, discord.TextChannel) and ch.is_nsfw():
|
||||
return True
|
||||
raise NSFWChannelRequired(ch)
|
||||
return check(pred)
|
||||
|
||||
def cooldown(rate, per, type=BucketType.default):
|
||||
|
@ -29,11 +29,12 @@ from discord.errors import DiscordException
|
||||
|
||||
__all__ = ['CommandError', 'MissingRequiredArgument', 'BadArgument',
|
||||
'PrivateMessageOnly', 'NoPrivateMessage', 'CheckFailure',
|
||||
'CommandNotFound' ,'DisabledCommand', 'CommandInvokeError',
|
||||
'TooManyArguments', 'UserInputError', 'CommandOnCooldown',
|
||||
'NotOwner', 'MissingPermissions', 'BotMissingPermissions',
|
||||
'ConversionError', 'BadUnionArgument', 'ArgumentParsingError',
|
||||
'UnexpectedQuoteError', 'InvalidEndOfQuotedStringError',
|
||||
'CommandNotFound', 'DisabledCommand', 'CommandInvokeError',
|
||||
'TooManyArguments','UserInputError', 'CommandOnCooldown',
|
||||
'NotOwner', 'MissingRole', 'BotMissingRole', 'MissingAnyRole',
|
||||
'BotMissingAnyRole','MissingPermissions', 'BotMissingPermissions',
|
||||
'NSFWChannelRequired', 'ConversionError', 'BadUnionArgument',
|
||||
'ArgumentParsingError', 'UnexpectedQuoteError', 'InvalidEndOfQuotedStringError',
|
||||
'ExpectedClosingQuoteError', 'ExtensionError', 'ExtensionAlreadyLoaded',
|
||||
'ExtensionNotLoaded', 'NoEntryPointError', 'ExtensionFailed',
|
||||
'ExtensionNotFound']
|
||||
@ -128,7 +129,9 @@ class NoPrivateMessage(CheckFailure):
|
||||
"""Exception raised when an operation does not work in private message
|
||||
contexts.
|
||||
"""
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
super().__init__('This command cannot be used in private messages.')
|
||||
|
||||
class NotOwner(CheckFailure):
|
||||
"""Exception raised when the message author is not the owner of the bot."""
|
||||
@ -167,8 +170,116 @@ class CommandOnCooldown(CommandError):
|
||||
self.retry_after = retry_after
|
||||
super().__init__('You are on cooldown. Try again in {:.2f}s'.format(retry_after))
|
||||
|
||||
class MissingRole(CheckFailure):
|
||||
"""Exception raised when the command invoker lacks a role to run a command.
|
||||
|
||||
This inherits from :exc:`.CheckFailure`
|
||||
|
||||
.. versionadded:: 1.1.0
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
missing_role: Union[:class:`str`, :class:`int`]
|
||||
The required role that is missing.
|
||||
This is the parameter passed to :func:`~.commands.has_role`.
|
||||
"""
|
||||
def __init__(self, missing_role):
|
||||
self.missing_role = missing_role
|
||||
message = 'Role {0!r} is required to run this command.'.format(missing_role)
|
||||
super().__init__(message)
|
||||
|
||||
class BotMissingRole(CheckFailure):
|
||||
"""Exception raised when the bot's member lacks a role to run a command.
|
||||
|
||||
This inherits from :exc:`.CheckFailure`
|
||||
|
||||
.. versionadded:: 1.1.0
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
missing_role: Union[:class:`str`, :class:`int`]
|
||||
The required role that is missing.
|
||||
This is the parameter passed to :func:`~.commands.has_role`.
|
||||
"""
|
||||
def __init__(self, missing_role):
|
||||
self.missing_role = missing_role
|
||||
message = 'Bot requires the role {0!r} to run this command'.format(missing_role)
|
||||
super().__init__(message)
|
||||
|
||||
class MissingAnyRole(CheckFailure):
|
||||
"""Exception raised when the command invoker lacks any of
|
||||
the roles specified to run a command.
|
||||
|
||||
This inherits from :exc:`.CheckFailure`
|
||||
|
||||
.. versionadded:: 1.1.0
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
missing_roles: List[Union[:class:`str`, :class:`int`]]
|
||||
The roles that the invoker is missing.
|
||||
These are the parameters passed to :func:`~.commands.has_any_role`.
|
||||
"""
|
||||
def __init__(self, missing_roles):
|
||||
self.missing_roles = missing_roles
|
||||
|
||||
missing = ["'{}'".format(role) for role in missing_roles]
|
||||
|
||||
if len(missing) > 2:
|
||||
fmt = '{}, or {}'.format(", ".join(missing[:-1]), missing[-1])
|
||||
else:
|
||||
fmt = ' or '.join(missing)
|
||||
|
||||
message = "You are missing at least one of the required roles: {}".format(fmt)
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
class BotMissingAnyRole(CheckFailure):
|
||||
"""Exception raised when the bot's member lacks any of
|
||||
the roles specified to run a command.
|
||||
|
||||
This inherits from :exc:`.CheckFailure`
|
||||
|
||||
.. versionadded:: 1.1.0
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
missing_roles: List[Union[:class:`str`, :class:`int`]]
|
||||
The roles that the bot's member is missing.
|
||||
These are the parameters passed to :func:`~.commands.has_any_role`.
|
||||
|
||||
"""
|
||||
def __init__(self, missing_roles):
|
||||
self.missing_roles = missing_roles
|
||||
|
||||
missing = ["'{}'".format(role) for role in missing_roles]
|
||||
|
||||
if len(missing) > 2:
|
||||
fmt = '{}, or {}'.format(", ".join(missing[:-1]), missing[-1])
|
||||
else:
|
||||
fmt = ' or '.join(missing)
|
||||
|
||||
message = "Bot is missing at least one of the required roles: {}".format(fmt)
|
||||
super().__init__(message)
|
||||
|
||||
class NSFWChannelRequired(CheckFailure):
|
||||
"""Exception raised when a channel does not have the required NSFW setting.
|
||||
|
||||
This inherits from :exc:`.CheckFailure`.
|
||||
|
||||
.. versionadded:: 1.1.0
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
channel: :class:`discord.abc.GuildChannel`
|
||||
The channel that does not have NSFW enabled.
|
||||
"""
|
||||
def __init__(self, channel):
|
||||
self.channel = channel
|
||||
super().__init__("Channel '{}' needs to be NSFW for this command to work.".format(channel))
|
||||
|
||||
class MissingPermissions(CheckFailure):
|
||||
"""Exception raised when the command invoker lacks permissions to run
|
||||
"""Exception raised when the command invoker lacks permissions to run a
|
||||
command.
|
||||
|
||||
Attributes
|
||||
@ -185,11 +296,12 @@ class MissingPermissions(CheckFailure):
|
||||
fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1])
|
||||
else:
|
||||
fmt = ' and '.join(missing)
|
||||
message = 'You are missing {} permission(s) to run command.'.format(fmt)
|
||||
message = 'You are missing {} permission(s) to run this command.'.format(fmt)
|
||||
super().__init__(message, *args)
|
||||
|
||||
class BotMissingPermissions(CheckFailure):
|
||||
"""Exception raised when the bot lacks permissions to run command.
|
||||
"""Exception raised when the bot's member lacks permissions to run a
|
||||
command.
|
||||
|
||||
Attributes
|
||||
-----------
|
||||
@ -205,7 +317,7 @@ class BotMissingPermissions(CheckFailure):
|
||||
fmt = '{}, and {}'.format(", ".join(missing[:-1]), missing[-1])
|
||||
else:
|
||||
fmt = ' and '.join(missing)
|
||||
message = 'Bot requires {} permission(s) to run command.'.format(fmt)
|
||||
message = 'Bot requires {} permission(s) to run this command.'.format(fmt)
|
||||
super().__init__(message, *args)
|
||||
|
||||
class BadUnionArgument(UserInputError):
|
||||
|
@ -255,6 +255,9 @@ Exceptions
|
||||
.. autoexception:: discord.ext.commands.BadUnionArgument
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.PrivateMessageOnly
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.NoPrivateMessage
|
||||
:members:
|
||||
|
||||
@ -288,6 +291,21 @@ Exceptions
|
||||
.. autoexception:: discord.ext.commands.BotMissingPermissions
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.MissingRole
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.BotMissingRole
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.MissingAnyRole
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.BotMissingAnyRole
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.NSFWChannelRequired
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.ExtensionError
|
||||
:members:
|
||||
|
||||
@ -326,10 +344,16 @@ Exception Hierarchy
|
||||
- :exc:`~.commands.ExpectedClosingQuoteError`
|
||||
- :exc:`~.commands.CommandNotFound`
|
||||
- :exc:`~.commands.CheckFailure`
|
||||
- :exc:`~.commands.PrivateMessageOnly`
|
||||
- :exc:`~.commands.NoPrivateMessage`
|
||||
- :exc:`~.commands.NotOwner`
|
||||
- :exc:`~.commands.MissingPermissions`
|
||||
- :exc:`~.commands.BotMissingPermissions`
|
||||
- :exc:`~.commands.MissingRole`
|
||||
- :exc:`~.commands.BotMissingRole`
|
||||
- :exc:`~.commands.MissingAnyRole`
|
||||
- :exc:`~.commands.BotMissingAnyRole`
|
||||
- :exc:`~.commands.NSFWChannelRequired`
|
||||
- :exc:`~.commands.DisabledCommand`
|
||||
- :exc:`~.commands.CommandInvokeError`
|
||||
- :exc:`~.commands.CommandOnCooldown`
|
||||
|
Loading…
x
Reference in New Issue
Block a user