diff --git a/README.md b/README.md index 8fd5fd72..6e0360b3 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,15 @@ def giveme(message, something): message.reply('Here is {}'.format(something)) ``` +You can use group name as kwargs: +```python +from slackbot.bot import respond_to + +@respond_to('Hello (?P.+)') +def say_hello(message, name): + message.reply('Hello! {}'.format(name) +``` + If you would like to have a command like 'stats' and 'stats start_date end_date', you can create reg ex like so: ```python diff --git a/slackbot/dispatcher.py b/slackbot/dispatcher.py index fff97c83..dd0675b5 100644 --- a/slackbot/dispatcher.py +++ b/slackbot/dispatcher.py @@ -48,11 +48,11 @@ def dispatch_msg(self, msg): def _dispatch_msg_handler(self, category, msg): responded = False - for func, args in self._plugins.get_plugins(category, msg.get('text', None)): + for func, args, kwargs in self._plugins.get_plugins(category, msg.get('text', None)): if func: responded = True try: - func(Message(self._client, msg), *args) + func(Message(self._client, msg), *args, **kwargs) except: logger.exception( 'failed to handle message %s with plugin "%s"', diff --git a/slackbot/manager.py b/slackbot/manager.py index 65a20ebe..298fd74d 100644 --- a/slackbot/manager.py +++ b/slackbot/manager.py @@ -69,8 +69,17 @@ def get_plugins(self, category, text): for matcher in self.commands[category]: m = matcher.search(text) if m: + kwargs = m.groupdict() + args = tuple( + v for i, v in enumerate(m.groups()) + if (i + 1) not in matcher.groupindex.values() + ) has_matching_plugin = True - yield self.commands[category][matcher], to_utf8(m.groups()) + kwargs_utf8 = { + to_utf8(k): to_utf8(v) + for k, v in kwargs.items() + } + yield self.commands[category][matcher], to_utf8(args), kwargs_utf8 if not has_matching_plugin: - yield None, None + yield None, None, None diff --git a/tests/unit/kwarg_plugin_module.py b/tests/unit/kwarg_plugin_module.py new file mode 100644 index 00000000..0d3f0d3d --- /dev/null +++ b/tests/unit/kwarg_plugin_module.py @@ -0,0 +1,6 @@ +from slackbot.bot import respond_to + + +@respond_to('Hello, (?P.+)') +def say_hello(message, name): + message.reply('Hello! {}'.format(name)) diff --git a/tests/unit/test_dispatcher.py b/tests/unit/test_dispatcher.py index 11ae4b87..00f39750 100644 --- a/tests/unit/test_dispatcher.py +++ b/tests/unit/test_dispatcher.py @@ -22,11 +22,11 @@ def default_okay(self, message): def get_plugins(self, category, message): if message == 'no_plugin_defined': - return [[None, None]] + return [[None, None, None]] if category == 'default_reply': - return [[getattr(self, 'default_'+message), []]] + return [[getattr(self, 'default_'+message), [], {}]] else: - return [[getattr(self, message), []]] + return [[getattr(self, message), [], {}]] class FakeClient: diff --git a/tests/unit/test_manager.py b/tests/unit/test_manager.py index 76450736..8825a8b5 100644 --- a/tests/unit/test_manager.py +++ b/tests/unit/test_manager.py @@ -18,10 +18,25 @@ def test_import_plugin_single_module(): assert 'fake_plugin_module' in sys.modules +def test_kwargs(): + pm = PluginsManager() + pm._load_plugins('kwarg_plugin_module') + + msg = { + 'category': 'respond_to', + 'text': 'Hello, Jeong Arm', + } + + func, args, kwargs = next(pm.get_plugins(msg['category'], msg['text'])) + assert not args + assert kwargs == {'name': 'Jeong Arm'} + + def test_get_plugins_none_text(): p = PluginsManager() p.commands['respond_to'][re.compile(r'^dummy regexp$')] = lambda x: x # Calling get_plugins() with `text == None` - for func, args in p.get_plugins('respond_to', None): + for func, args, kwargs in p.get_plugins('respond_to', None): assert func is None assert args is None + assert kwargs is None