From 492b26326ae6ee2b3932a59c2521cb1f8ec17f0d Mon Sep 17 00:00:00 2001 From: Andrei Date: Sun, 20 Nov 2016 21:37:47 -0600 Subject: [PATCH] More hashmaps, cleanup and fixes --- disco/api/client.py | 6 +++--- disco/api/http.py | 2 +- disco/bot/bot.py | 3 ++- disco/bot/command.py | 2 +- disco/bot/plugin.py | 4 ++-- disco/types/base.py | 7 ++++++- disco/types/message.py | 33 ++++++++++++++++++++------------- disco/types/user.py | 2 +- 8 files changed, 36 insertions(+), 23 deletions(-) diff --git a/disco/api/client.py b/disco/api/client.py index c8fe702..a478b9b 100644 --- a/disco/api/client.py +++ b/disco/api/client.py @@ -193,7 +193,7 @@ class APIClient(LoggingClass): def guilds_channels_list(self, guild): r = self.http(Routes.GUILDS_CHANNELS_LIST, dict(guild=guild)) - return Channel.create_map(self.client, r.json(), guild_id=guild) + return Channel.create_hash(self.client, 'id', r.json(), guild_id=guild) def guilds_channels_create(self, guild, **kwargs): r = self.http(Routes.GUILDS_CHANNELS_CREATE, dict(guild=guild), json=kwargs) @@ -207,7 +207,7 @@ class APIClient(LoggingClass): def guilds_members_list(self, guild): r = self.http(Routes.GUILDS_MEMBERS_LIST, dict(guild=guild)) - return GuildMember.create_map(self.client, r.json(), guild_id=guild) + return GuildMember.create_hash(self.client, 'id', r.json(), guild_id=guild) def guilds_members_get(self, guild, member): r = self.http(Routes.GUILDS_MEMBERS_GET, dict(guild=guild, member=member)) @@ -224,7 +224,7 @@ class APIClient(LoggingClass): def guilds_bans_list(self, guild): r = self.http(Routes.GUILDS_BANS_LIST, dict(guild=guild)) - return User.create_map(self.client, r.json()) + return User.create_hash(self.client, 'id', r.json()) def guilds_bans_create(self, guild, user, delete_message_days): self.http(Routes.GUILDS_BANS_CREATE, dict(guild=guild, user=user), params={ diff --git a/disco/api/http.py b/disco/api/http.py index 2ebf941..10dcd22 100644 --- a/disco/api/http.py +++ b/disco/api/http.py @@ -211,7 +211,7 @@ class HTTPClient(LoggingClass): # Make the actual request url = self.BASE_URL + route[1].format(**args) - self.log.info('%s %s', route[0].value, url) + self.log.info('%s %s (%s)', route[0].value, url, kwargs.get('params')) r = requests.request(route[0].value, url, **kwargs) # Update rate limiter diff --git a/disco/bot/bot.py b/disco/bot/bot.py index 451000a..fccda64 100644 --- a/disco/bot/bot.py +++ b/disco/bot/bot.py @@ -214,7 +214,8 @@ class Bot(object): """ Computes a single regex which matches all possible command combinations. """ - re_str = '|'.join(command.regex for command in self.commands) + commands = list(self.commands) + re_str = '|'.join(command.regex for command in commands) if re_str: self.command_matches_re = re.compile(re_str) else: diff --git a/disco/bot/command.py b/disco/bot/command.py index a9118b8..6623a86 100644 --- a/disco/bot/command.py +++ b/disco/bot/command.py @@ -5,7 +5,7 @@ from holster.enum import Enum from disco.bot.parser import ArgumentSet, ArgumentError from disco.util.functional import cached_property -REGEX_FMT = '({})' +REGEX_FMT = '{}' ARGS_REGEX = '( ((?:\n|.)*)$|$)' USER_MENTION_RE = re.compile('<@!?([0-9]+)>') diff --git a/disco/bot/plugin.py b/disco/bot/plugin.py index a99f532..e8a0b9d 100644 --- a/disco/bot/plugin.py +++ b/disco/bot/plugin.py @@ -258,7 +258,7 @@ class Plugin(LoggingClass, PluginDeco): self.ctx['user'] = event.author for pre in self._pre[typ]: - event = pre(event, args, kwargs) + event = pre(func, event, args, kwargs) if event is None: return False @@ -266,7 +266,7 @@ class Plugin(LoggingClass, PluginDeco): result = func(event, *args, **kwargs) for post in self._post[typ]: - post(event, args, kwargs, result) + post(func, event, args, kwargs, result) return True diff --git a/disco/types/base.py b/disco/types/base.py index 4bee934..0c81e70 100644 --- a/disco/types/base.py +++ b/disco/types/base.py @@ -74,7 +74,6 @@ class Field(object): try: return self.deserializer(raw, client) except Exception as e: - raise six.reraise(ConversionError, ConversionError(self, raw, e)) @staticmethod @@ -337,6 +336,12 @@ class Model(six.with_metaclass(ModelMeta, AsyncChainable)): def create_map(cls, client, data, **kwargs): return list(map(functools.partial(cls.create, client, **kwargs), data)) + @classmethod + def create_hash(cls, client, key, data, **kwargs): + return HashMap({ + getattr(item, key): cls.create(client, item, **kwargs) for item in data + }) + @classmethod def attach(cls, it, data): for item in it: diff --git a/disco/types/message.py b/disco/types/message.py index 500428f..53276c7 100644 --- a/disco/types/message.py +++ b/disco/types/message.py @@ -1,5 +1,7 @@ import re +import six import functools +import unicodedata from holster.enum import Enum @@ -105,7 +107,7 @@ class MessageEmbed(SlottedModel): title = Field(text) type = Field(str, default='rich') description = Field(text) - url = Field(str) + url = Field(text) timestamp = Field(lazy_datetime) color = Field(int) footer = Field(MessageEmbedFooter) @@ -139,8 +141,8 @@ class MessageAttachment(SlottedModel): """ id = Field(str) filename = Field(text) - url = Field(str) - proxy_url = Field(str) + url = Field(text) + proxy_url = Field(text) size = Field(int) height = Field(int) width = Field(int) @@ -327,13 +329,13 @@ class Message(SlottedModel): @cached_property def with_proper_mentions(self): def replace_user(u): - return '@' + str(u) + return u'@' + six.text_type(u) def replace_role(r): - return '@' + str(r) + return u'@' + six.text_type(r) def replace_channel(c): - return str(c) + return six.text_type(c) return self.replace_mentions(replace_user, replace_role, replace_channel) @@ -382,25 +384,28 @@ class Message(SlottedModel): class MessageTable(object): - def __init__(self, sep=' | ', codeblock=True, header_break=True): + def __init__(self, sep=' | ', codeblock=True, header_break=True, language=None): self.header = [] self.entries = [] self.size_index = {} self.sep = sep self.codeblock = codeblock self.header_break = header_break + self.language = language def recalculate_size_index(self, cols): for idx, col in enumerate(cols): - if idx not in self.size_index or len(col) > self.size_index[idx]: - self.size_index[idx] = len(col) + size = len(unicodedata.normalize('NFC', col)) + if idx not in self.size_index or size > self.size_index[idx]: + self.size_index[idx] = size def set_header(self, *args): + args = list(map(six.text_type, args)) self.header = args self.recalculate_size_index(args) def add(self, *args): - args = list(map(lambda v: v if isinstance(v, basestring) else str(v), args)) + args = list(map(six.text_type, args)) self.entries.append(args) self.recalculate_size_index(args) @@ -414,15 +419,17 @@ class MessageTable(object): return data.rstrip() def compile(self): - data = [self.compile_one(self.header)] + data = [] + if self.header: + data = [self.compile_one(self.header)] - if self.header_break: + if self.header and self.header_break: data.append('-' * (sum(self.size_index.values()) + (len(self.header) * len(self.sep)) + 1)) for row in self.entries: data.append(self.compile_one(row)) if self.codeblock: - return '```' + '\n'.join(data) + '```' + return '```{}'.format(self.language if self.language else '') + '\n'.join(data) + '```' return '\n'.join(data) diff --git a/disco/types/user.py b/disco/types/user.py index c2bac79..51bbfbf 100644 --- a/disco/types/user.py +++ b/disco/types/user.py @@ -28,7 +28,7 @@ class User(SlottedModel, with_equality('id'), with_hash('id')): return '<@{}>'.format(self.id) def __str__(self): - return u'{}#{}'.format(self.username, self.discriminator) + return u'{}#{}'.format(self.username, str(self.discriminator).zfill(4)) def __repr__(self): return u''.format(self.id, self)