Skip to content
This repository has been archived by the owner on Aug 1, 2021. It is now read-only.

Commit

Permalink
Replace all instances of keys/values/items, command group abbreviation
Browse files Browse the repository at this point in the history
  • Loading branch information
b1naryth1ef committed Oct 9, 2016
1 parent fc53496 commit d8bba96
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 36 deletions.
4 changes: 3 additions & 1 deletion disco/api/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import six

from disco.api.http import Routes, HTTPClient
from disco.util.logging import LoggingClass

Expand All @@ -15,7 +17,7 @@ def optional(**kwargs):
:returns: dict
"""
return {k: v for k, v in kwargs.items() if v is not None}
return {k: v for k, v in six.iteritems(kwargs) if v is not None}


class APIClient(LoggingClass):
Expand Down
3 changes: 2 additions & 1 deletion disco/api/http.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import requests
import random
import gevent
import six

from holster.enum import Enum

Expand Down Expand Up @@ -166,7 +167,7 @@ def call(self, route, args=None, **kwargs):
kwargs['headers'] = self.headers

# Build the bucket URL
filtered = {k: (v if v in ('guild', 'channel') else '') for k, v in args.items()}
filtered = {k: (v if v in ('guild', 'channel') else '') for k, v in six.iteritems(args)}
bucket = (route[0].value, route[1].format(**filtered))

# Possibly wait if we're rate limited
Expand Down
46 changes: 40 additions & 6 deletions disco/bot/bot.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import re
import os
import importlib
import six
import inspect
import importlib

from six.moves import reload_module
from holster.threadlocal import ThreadLocal
Expand Down Expand Up @@ -48,6 +49,10 @@ class BotConfig(Config):
commands_level_getter : function
If set, a function which when given a GuildMember or User, returns the
relevant :class:`disco.bot.commands.CommandLevels`.
commands_group_abbrev : function
If true, command groups may be abbreviated to the least common variation.
E.g. the grouping 'test' may be abbreviated down to 't', unless 'tag' exists,
in which case it may be abbreviated down to 'te'.
plugin_config_provider : Optional[function]
If set, this function will replace the default configuration loading
function, which normally attempts to load a file located at config/plugin_name.fmt
Expand All @@ -72,6 +77,7 @@ class BotConfig(Config):
commands_prefix = ''
commands_allow_edit = True
commands_level_getter = None
commands_group_abbrev = True

plugin_config_provider = None
plugin_config_format = 'yaml'
Expand Down Expand Up @@ -121,6 +127,7 @@ def __init__(self, client, config=None):
self.client.manhole_locals['bot'] = self

self.plugins = {}
self.group_abbrev = {}

# Only bind event listeners if we're going to parse commands
if self.config.commands_enabled:
Expand All @@ -140,7 +147,7 @@ def __init__(self, client, config=None):
self.add_plugin_module(plugin_mod)

# Convert level mapping
for k, v in self.config.levels.items():
for k, v in six.iteritems(self.config.levels):
self.config.levels[k] = CommandLevels.get(v)

@classmethod
Expand Down Expand Up @@ -169,10 +176,37 @@ def commands(self):
"""
Generator of all commands this bots plugins have defined
"""
for plugin in self.plugins.values():
for command in plugin.commands.values():
for plugin in six.itervalues(self.plugins):
for command in six.itervalues(plugin.commands):
yield command

def recompute(self):
"""
Called when a plugin is loaded/unloaded to recompute internal state.
"""
self.compute_group_abbrev()
if self.config.commands_group_abbrev:
self.compute_command_matches_re()

def compute_group_abbrev(self):
"""
Computes all possible abbreviations for a command grouping
"""
self.group_abbrev = {}
groups = set(command.group for command in self.commands if command.group)

for group in groups:
grp = group
while grp:
# If the group already exists, means someone else thought they
# could use it so we need to
if grp in list(six.itervalues(self.group_abbrev)):
self.group_abbrev = {k: v for k, v in six.iteritems(self.group_abbrev) if v != grp}
else:
self.group_abbrev[group] = grp

grp = grp[:-1]

def compute_command_matches_re(self):
"""
Computes a single regex which matches all possible command combinations.
Expand Down Expand Up @@ -340,7 +374,7 @@ def add_plugin(self, cls, config=None):

self.plugins[cls.__name__] = cls(self, config)
self.plugins[cls.__name__].load()
self.compute_command_matches_re()
self.recompute()

def rmv_plugin(self, cls):
"""
Expand All @@ -356,7 +390,7 @@ def rmv_plugin(self, cls):

self.plugins[cls.__name__].unload()
del self.plugins[cls.__name__]
self.compute_command_matches_re()
self.recompute()

def reload_plugin(self, cls):
"""
Expand Down
17 changes: 12 additions & 5 deletions disco/bot/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,14 @@ class Command(object):
is_regex : Optional[bool]
Whether the triggers for this command should be treated as raw regex.
"""
def __init__(self, plugin, func, trigger, args=None, level=None,
aliases=None, group=None, is_regex=False):

def __init__(self, plugin, func, trigger, *args, **kwargs):
self.plugin = plugin
self.func = func
self.triggers = [trigger] + (aliases or [])
self.triggers = [trigger]
self.update(*args, **kwargs)

def update(self, args=None, level=None, aliases=None, group=None, is_regex=None):
self.triggers += aliases or []

def resolve_role(ctx, id):
return ctx.msg.guild.roles.get(id)
Expand Down Expand Up @@ -161,7 +163,12 @@ def regex(self):
if self.is_regex:
return REGEX_FMT.format('|'.join(self.triggers))
else:
group = self.group + ' ' if self.group else ''
group = ''
if self.group:
if self.group in self.plugin.bot.group_abbrev.get(self.group):
group = '{}(?:\w+)? '.format(self.group)
else:
group = self.group
return REGEX_FMT.format('|'.join(['^' + group + trigger for trigger in self.triggers]) + ARGS_REGEX)

def execute(self, event):
Expand Down
15 changes: 10 additions & 5 deletions disco/bot/plugin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import inspect
import functools
import six
import gevent
import inspect
import weakref
import functools

from holster.emitter import Priority

Expand Down Expand Up @@ -170,6 +171,7 @@ def bind_all(self):
if meta['type'] == 'listener':
self.register_listener(member, meta['what'], meta['desc'], meta['priority'])
elif meta['type'] == 'command':
meta['kwargs']['update'] = True
self.register_command(member, *meta['args'], **meta['kwargs'])
elif meta['type'] == 'schedule':
self.register_schedule(member, *meta['args'], **meta['kwargs'])
Expand Down Expand Up @@ -260,8 +262,11 @@ def register_command(self, func, *args, **kwargs):
Keyword arguments to pass onto the :class:`disco.bot.command.Command`
object.
"""
wrapped = functools.partial(self._dispatch, 'command', func)
self.commands[func.__name__] = Command(self, wrapped, *args, **kwargs)
if kwargs.pop('update', False) and func.__name__ in self.commands:
self.commands[func.__name__].update(*args, **kwargs)
else:
wrapped = functools.partial(self._dispatch, 'command', func)
self.commands[func.__name__] = Command(self, wrapped, *args, **kwargs)

def register_schedule(self, func, interval, repeat=True, init=True):
"""
Expand Down Expand Up @@ -303,7 +308,7 @@ def unload(self):
for listener in self.listeners:
listener.remove()

for schedule in self.schedules.values():
for schedule in six.itervalues(self.schedules):
schedule.kill()

def reload(self):
Expand Down
3 changes: 2 additions & 1 deletion disco/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from __future__ import print_function

import os
import six
import logging
import argparse

Expand Down Expand Up @@ -47,7 +48,7 @@ def disco_main(run=False):
else:
config = ClientConfig()

for k, v in vars(args).items():
for k, v in six.iteritems(vars(args)):
if hasattr(config, k) and v is not None:
setattr(config, k, v)

Expand Down
3 changes: 2 additions & 1 deletion disco/state.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import six
import inflection

from collections import defaultdict, deque, namedtuple
Expand Down Expand Up @@ -159,7 +160,7 @@ def on_guild_create(self, event):
self.guilds[event.guild.id] = event.guild
self.channels.update(event.guild.channels)

for member in event.guild.members.values():
for member in six.itervalues(event.guild.members):
self.users[member.user.id] = member.user

# Request full member list
Expand Down
4 changes: 2 additions & 2 deletions disco/types/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def __init__(self, *args, **kwargs):
else:
obj = kwargs

for name, field in self._fields.items():
for name, field in six.iteritems(self._fields):
if field.src_name not in obj or not obj[field.src_name]:
if field.has_default():
setattr(self, field.dst_name, field.default())
Expand Down Expand Up @@ -217,7 +217,7 @@ def create_map(cls, client, data):
@classmethod
def attach(cls, it, data):
for item in it:
for k, v in data.items():
for k, v in six.iteritems(data):
try:
setattr(item, k, v)
except:
Expand Down
12 changes: 6 additions & 6 deletions disco/types/channel.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from holster.enum import Enum
import six

from disco.types.base import Model, Field, snowflake, enum, listof, dictof, text
from disco.types.permissions import PermissionValue
from holster.enum import Enum

from disco.util.snowflake import to_snowflake
from disco.util.functional import cached_property, one_or_many, chunks
from disco.types.user import User
from disco.types.permissions import Permissions, Permissible
from disco.types.base import Model, Field, snowflake, enum, listof, dictof, text
from disco.types.permissions import Permissions, Permissible, PermissionValue
from disco.voice.client import VoiceClient


Expand Down Expand Up @@ -91,7 +91,7 @@ class Channel(Model, Permissible):
def __init__(self, *args, **kwargs):
super(Channel, self).__init__(*args, **kwargs)

self.attach(self.overwrites.values(), {'channel_id': self.id, 'channel': self})
self.attach(six.itervalues(self.overwrites), {'channel_id': self.id, 'channel': self})

def get_permissions(self, user):
"""
Expand All @@ -108,7 +108,7 @@ def get_permissions(self, user):
member = self.guild.members.get(user.id)
base = self.guild.get_permissions(user)

for ow in self.overwrites.values():
for ow in six.itervalues(self.overwrites):
if ow.id != user.id and ow.id not in member.roles:
continue

Expand Down
16 changes: 9 additions & 7 deletions disco/types/guild.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import six

from holster.enum import Enum

from disco.api.http import APIException
Expand All @@ -6,8 +8,8 @@
from disco.types.base import Model, Field, snowflake, listof, dictof, datetime, text, binary, enum
from disco.types.user import User
from disco.types.voice import VoiceState
from disco.types.permissions import PermissionValue, Permissions, Permissible
from disco.types.channel import Channel
from disco.types.permissions import PermissionValue, Permissions, Permissible


VerificationLevel = Enum(
Expand Down Expand Up @@ -243,11 +245,11 @@ class Guild(Model, Permissible):
def __init__(self, *args, **kwargs):
super(Guild, self).__init__(*args, **kwargs)

self.attach(self.channels.values(), {'guild_id': self.id})
self.attach(self.members.values(), {'guild_id': self.id})
self.attach(self.roles.values(), {'guild_id': self.id})
self.attach(self.emojis.values(), {'guild_id': self.id})
self.attach(self.voice_states.values(), {'guild_id': self.id})
self.attach(six.itervalues(self.channels), {'guild_id': self.id})
self.attach(six.itervalues(self.members), {'guild_id': self.id})
self.attach(six.itervalues(self.roles), {'guild_id': self.id})
self.attach(six.itervalues(self.emojis), {'guild_id': self.id})
self.attach(six.itervalues(self.voice_states), {'guild_id': self.id})

def get_permissions(self, user):
"""
Expand Down Expand Up @@ -281,7 +283,7 @@ def get_voice_state(self, user):
"""
user = to_snowflake(user)

for state in self.voice_states.values():
for state in six.itervalues(self.voice_states):
if state.user_id == user:
return state

Expand Down
2 changes: 1 addition & 1 deletion disco/util/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, *args, **kwargs):
self.emitter = Emitter(gevent.spawn)

# Hack to get events to emit
for var in self.__dict__.keys():
for var in six.iterkeys(self.__dict__):
if not var.startswith('on_'):
continue

Expand Down

0 comments on commit d8bba96

Please sign in to comment.