3 changed files with 163 additions and 116 deletions
@ -0,0 +1,155 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
""" |
|||
The MIT License (MIT) |
|||
|
|||
Copyright (c) 2015-2016 Rapptz |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a |
|||
copy of this software and associated documentation files (the "Software"), |
|||
to deal in the Software without restriction, including without limitation |
|||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|||
and/or sell copies of the Software, and to permit persons to whom the |
|||
Software is furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in |
|||
all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
DEALINGS IN THE SOFTWARE. |
|||
""" |
|||
|
|||
import discord |
|||
import asyncio |
|||
import re |
|||
|
|||
from .errors import BadArgument, NoPrivateMessage |
|||
|
|||
__all__ = [ 'Converter', 'MemberConverter', 'UserConverter', |
|||
'ChannelConverter', 'InviteConverter', 'RoleConverter', |
|||
'GameConverter', 'ColourConverter' ] |
|||
|
|||
class Converter: |
|||
"""The base class of custom converters that require the :class:`Context` |
|||
to be passed to be useful. |
|||
|
|||
This allows you to implement converters that function similar to the |
|||
special cased ``discord`` classes. |
|||
|
|||
Classes that derive from this should override the :meth:`convert` method |
|||
to do its conversion logic. This method could be a coroutine or a regular |
|||
function. |
|||
|
|||
Attributes |
|||
----------- |
|||
ctx: :class:`Context` |
|||
The invocation context that the argument is being used in. |
|||
argument: str |
|||
The argument that is being converted. |
|||
""" |
|||
def __init__(self, ctx, argument): |
|||
self.ctx = ctx |
|||
self.argument = argument |
|||
|
|||
def convert(self): |
|||
raise NotImplementedError('Derived classes need to implement this.') |
|||
|
|||
class MemberConverter(Converter): |
|||
def convert(self): |
|||
message = self.ctx.message |
|||
bot = self.ctx.bot |
|||
|
|||
match = re.match(r'<@!?([0-9]+)>$', self.argument) |
|||
server = message.server |
|||
result = None |
|||
if match is None: |
|||
# not a mention... |
|||
if server: |
|||
result = server.get_member_named(self.argument) |
|||
else: |
|||
result = self._get_from_servers(bot, 'get_member_named', self.argument) |
|||
else: |
|||
user_id = match.group(1) |
|||
if server: |
|||
result = server.get_member(user_id) |
|||
else: |
|||
result = self._get_from_servers(bot, 'get_member', user_id) |
|||
|
|||
if result is None: |
|||
raise BadArgument('Member "{}" not found'.format(self.argument)) |
|||
|
|||
return result |
|||
|
|||
UserConverter = MemberConverter |
|||
|
|||
class ChannelConverter(Converter): |
|||
def convert(self): |
|||
message = self.ctx.message |
|||
bot = self.ctx.bot |
|||
|
|||
match = re.match(r'<#([0-9]+)>$', self.argument) |
|||
result = None |
|||
server = message.server |
|||
if match is None: |
|||
# not a mention |
|||
if server: |
|||
result = discord.utils.get(server.channels, name=self.argument) |
|||
else: |
|||
result = discord.utils.get(bot.get_all_channels(), name=self.argument) |
|||
else: |
|||
channel_id = match.group(1) |
|||
if server: |
|||
result = server.get_channel(channel_id) |
|||
else: |
|||
result = self._get_from_servers(bot, 'get_channel', channel_id) |
|||
|
|||
if result is None: |
|||
raise BadArgument('Channel "{}" not found.'.format(self.argument)) |
|||
|
|||
return result |
|||
|
|||
class ColourConverter(Converter): |
|||
def convert(self): |
|||
arg = self.argument.replace('0x', '').lower() |
|||
|
|||
if arg[0] == '#': |
|||
arg = arg[1:] |
|||
try: |
|||
value = int(arg, base=16) |
|||
return discord.Colour(value=value) |
|||
except ValueError: |
|||
method = getattr(discord.Colour, arg, None) |
|||
if method is None or not inspect.ismethod(method): |
|||
raise BadArgument('Colour "{}" is invalid.'.format(arg)) |
|||
return method() |
|||
|
|||
class RoleConverter(Converter): |
|||
def convert(self): |
|||
server = self.ctx.message.server |
|||
if not server: |
|||
raise NoPrivateMessage() |
|||
|
|||
match = re.match(r'<@&([0-9]+)>$', self.argument) |
|||
params = dict(id=match.group(1)) if match else dict(name=self.argument) |
|||
result = discord.utils.get(server.roles, **params) |
|||
if result is None: |
|||
raise BadArgument('Role "{}" not found.'.format(self.argument)) |
|||
return result |
|||
|
|||
class GameConverter(Converter): |
|||
def convert(self): |
|||
return discord.Game(name=self.argument) |
|||
|
|||
class InviteConverter(Converter): |
|||
@asyncio.coroutine |
|||
def convert(self): |
|||
try: |
|||
invite = yield from self.ctx.bot.get_invite(self.argument) |
|||
return invite |
|||
except Exception as e: |
|||
raise BadArgument('Invite is invalid or expired') from e |
Loading…
Reference in new issue