Browse Source

[commands] First pass in making commands ext work again.

pull/447/head
Rapptz 8 years ago
parent
commit
406984af2e
  1. 32
      discord/ext/commands/context.py
  2. 44
      discord/ext/commands/converter.py
  3. 4
      discord/ext/commands/core.py

32
discord/ext/commands/context.py

@ -24,14 +24,18 @@ DEALINGS IN THE SOFTWARE.
""" """
import asyncio import asyncio
import discord.abc
import discord.utils
class Context: class Context(discord.abc.MessageChannel):
"""Represents the context in which a command is being invoked under. """Represents the context in which a command is being invoked under.
This class contains a lot of meta data to help you understand more about This class contains a lot of meta data to help you understand more about
the invocation context. This class is not created manually and is instead the invocation context. This class is not created manually and is instead
passed around to commands by passing in :attr:`Command.pass_context`. passed around to commands by passing in :attr:`Command.pass_context`.
This class implements the :class:`abc.MessageChannel` ABC.
Attributes Attributes
----------- -----------
message : :class:`discord.Message` message : :class:`discord.Message`
@ -76,6 +80,7 @@ class Context:
self.invoked_with = attrs.pop('invoked_with', None) self.invoked_with = attrs.pop('invoked_with', None)
self.invoked_subcommand = attrs.pop('invoked_subcommand', None) self.invoked_subcommand = attrs.pop('invoked_subcommand', None)
self.subcommand_passed = attrs.pop('subcommand_passed', None) self.subcommand_passed = attrs.pop('subcommand_passed', None)
self._state = self.message._state
@asyncio.coroutine @asyncio.coroutine
def invoke(self, command, *args, **kwargs): def invoke(self, command, *args, **kwargs):
@ -112,6 +117,9 @@ class Context:
ret = yield from command.callback(*arguments, **kwargs) ret = yield from command.callback(*arguments, **kwargs)
return ret return ret
def _get_destination(self):
return self.channel.id, getattr(self.guild, 'id', None)
@property @property
def cog(self): def cog(self):
"""Returns the cog associated with this context's command. None if it does not exist.""" """Returns the cog associated with this context's command. None if it does not exist."""
@ -119,3 +127,25 @@ class Context:
if self.command is None: if self.command is None:
return None return None
return self.command.instance return self.command.instance
@discord.utils.cached_property
def id(self):
# we need this to meet MessageChannel abc
# it is purposefully undocumented because it makes no logistic sense
# outside of providing the sugar of the main class.
return self.channel.id
@discord.utils.cached_property
def guild(self):
"""Returns the guild associated with this context's command. None if not available."""
return self.message.guild
@discord.utils.cached_property
def channel(self):
"""Returns the channel associated with this context's command. Shorthand for :attr:`Message.channel`."""
return self.message.channel
@discord.utils.cached_property
def author(self):
"""Returns the author associated with this context's command. Shorthand for :attr:`Message.author`"""
return self.message.author

44
discord/ext/commands/converter.py

@ -32,8 +32,8 @@ import inspect
from .errors import BadArgument, NoPrivateMessage from .errors import BadArgument, NoPrivateMessage
__all__ = [ 'Converter', 'MemberConverter', 'UserConverter', __all__ = [ 'Converter', 'MemberConverter', 'UserConverter',
'ChannelConverter', 'InviteConverter', 'RoleConverter', 'TextChannelConverter', 'InviteConverter', 'RoleConverter',
'GameConverter', 'ColourConverter' ] 'GameConverter', 'ColourConverter', 'VoiceChannelConverter' ]
def _get_from_guilds(bot, getter, argument): def _get_from_guilds(bot, getter, argument):
result = None result = None
@ -103,20 +103,50 @@ class MemberConverter(IDConverter):
UserConverter = MemberConverter UserConverter = MemberConverter
class ChannelConverter(IDConverter): class TextChannelConverter(IDConverter):
def convert(self): def convert(self):
message = self.ctx.message
bot = self.ctx.bot bot = self.ctx.bot
match = self._get_id_match() or re.match(r'<#([0-9]+)>$', self.argument) match = self._get_id_match() or re.match(r'<#([0-9]+)>$', self.argument)
result = None result = None
guild = message.guild guild = self.ctx.guild
if match is None:
# not a mention
if guild:
result = discord.utils.get(guild.text_channels, name=self.argument)
else:
def check(c):
return isinstance(c, discord.TextChannel) and c.name == self.argument
result = discord.utils.find(check, bot.get_all_channels())
else:
channel_id = int(match.group(1))
if guild:
result = guild.get_channel(channel_id)
else:
result = _get_from_guilds(bot, 'get_channel', channel_id)
if result is None:
raise BadArgument('Channel "{}" not found.'.format(self.argument))
return result
class VoiceChannelConverter(IDConverter):
def convert(self):
bot = self.ctx.bot
match = self._get_id_match() or re.match(r'<#([0-9]+)>$', self.argument)
result = None
guild = self.ctx.guild
if match is None: if match is None:
# not a mention # not a mention
if guild: if guild:
result = discord.utils.get(guild.channels, name=self.argument) result = discord.utils.get(guild.voice_channels, name=self.argument)
else: else:
result = discord.utils.get(bot.get_all_channels(), name=self.argument) def check(c):
return isinstance(c, discord.VoiceChannel) and c.name == self.argument
result = discord.utils.find(check, bot.get_all_channels())
else: else:
channel_id = int(match.group(1)) channel_id = int(match.group(1))
if guild: if guild:

4
discord/ext/commands/core.py

@ -85,7 +85,7 @@ class Command:
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 `False`. 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
@ -135,7 +135,7 @@ class Command:
self.brief = kwargs.get('brief') self.brief = kwargs.get('brief')
self.rest_is_raw = kwargs.get('rest_is_raw', False) self.rest_is_raw = kwargs.get('rest_is_raw', False)
self.aliases = kwargs.get('aliases', []) self.aliases = kwargs.get('aliases', [])
self.pass_context = kwargs.get('pass_context', False) self.pass_context = kwargs.get('pass_context', True)
self.description = inspect.cleandoc(kwargs.get('description', '')) self.description = inspect.cleandoc(kwargs.get('description', ''))
self.hidden = kwargs.get('hidden', False) self.hidden = kwargs.get('hidden', False)
signature = inspect.signature(callback) signature = inspect.signature(callback)

Loading…
Cancel
Save