Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regex group support #130

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<name>.+)')
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
Expand Down
4 changes: 2 additions & 2 deletions slackbot/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -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['text']):
for func, args, kwargs in self._plugins.get_plugins(category, msg['text']):
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"',
Expand Down
8 changes: 7 additions & 1 deletion slackbot/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,14 @@ def get_plugins(self, category, text):
for matcher in self.commands[category]:
m = matcher.search(text)
if m:
kwargs = m.groupdict()
args = (
m.group(i)
for i in range(1, m.last_index + 1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re match objects don't have a last_index.

if i not in matcher.groupindex.values()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe sth. like:

args = (v for i, v in enumerate(m.groups()) if (i + 1) not in pattern.groupindex.values())

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also worth moving this to helper function in utils.py, e.g.

def extract_positional_and_named_groups(pattern, s):
    if isinstance(pattern, basestring):
        pattern = re.compile(pattern)
    m = re.match(pattern, s)
    kw = m.groupdict()
    a = [v for i, v in enumerate(m.groups()) if (i + 1) not in pattern.groupindex.values()]
    return a, kw

)
has_matching_plugin = True
yield self.commands[category][matcher], to_utf8(m.groups())
yield self.commands[category][matcher], to_utf8(args), to_utf8(kwargs)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to_utf8 for now can only handle single string or list/tuple/set of strings, so you need to extend it to also handle dicts whose values are strings.


if not has_matching_plugin:
yield None, None
5 changes: 5 additions & 0 deletions tests/unit/kw_arg_plugin_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from slackbot.bot import respond_to

@respond_to('Hello, (?P<name>.+)')
def say_hello(message, name):
message.reply('Hello! {}'.format(name))
14 changes: 14 additions & 0 deletions tests/unit/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,17 @@ def test_import_plugin_single_module():
assert 'fake_plugin_module' not in sys.modules
PluginsManager()._load_plugins('fake_plugin_module')
assert 'fake_plugin_module' in sys.modules


def test_kwargs():
pm = PluginsManager()
pm._load_plugins('kwarg_plugin_module')

msg = {
'category': 'default_reply',
'text': 'Hello, Jeong Arm',
}

func, args, kwargs = pm.get_plugins(msg['category'], msg['text'])
assert args == ()
assert kwargs == {'name': 'Jeong Arm'}