diff options
| author | Lars-Dominik Braun <lars@6xq.net> | 2018-10-03 13:38:10 +0200 | 
|---|---|---|
| committer | Lars-Dominik Braun <lars@6xq.net> | 2018-10-03 13:38:10 +0200 | 
| commit | 1231e9066a3fcf49bcaa6499e2407ff879d14227 (patch) | |
| tree | 9eed1e17dd7ba47d45c570ad3d09e3867a04a346 | |
| parent | 0867960b134680205946bdc05713d07f89f47785 (diff) | |
| download | crocoite-1231e9066a3fcf49bcaa6499e2407ff879d14227.tar.gz crocoite-1231e9066a3fcf49bcaa6499e2407ff879d14227.tar.bz2 crocoite-1231e9066a3fcf49bcaa6499e2407ff879d14227.zip | |
irc: Fix mode parsing
Ignore unsupported modes, add tests.
| -rw-r--r-- | crocoite/irc.py | 30 | ||||
| -rw-r--r-- | crocoite/test_irc.py | 14 | 
2 files changed, 37 insertions, 7 deletions
| diff --git a/crocoite/irc.py b/crocoite/irc.py index 878bf5e..c955337 100644 --- a/crocoite/irc.py +++ b/crocoite/irc.py @@ -217,17 +217,33 @@ class ArgparseBot (bottom.Client):      async def onNameReply (self, target, channel_type, channel, users, **kwargs):          self.users[channel] = dict (map (lambda x: (x.name, x), map (User.fromName, users))) +    @staticmethod +    def parseMode (mode): +        """ Parse mode strings like +a, -b, +a-b, -b+a, … """ +        action = '+' +        ret = [] +        for c in mode: +            if c in {'+', '-'}: +                action = c +            else: +                ret.append ((action, c)) +        return ret +      async def onMode (self, nick, user, host, channel, modes, params, **kwargs):          if channel not in self.channels:              return -        op = modes[0] -        for m, nick in zip (map (NickMode.fromMode, modes[1:]), params): -            u = self.users[channel].get (nick, User (nick)) -            if op == '+': -                u.modes.add (m) -            elif op == '-': -                u.modes.remove (m) +        for (action, mode), nick in zip (self.parseMode (modes), params): +            try: +                m = NickMode.fromMode (mode) +                u = self.users[channel].get (nick, User (nick)) +                if action == '+': +                    u.modes.add (m) +                elif action == '-': +                    u.modes.remove (m) +            except KeyError: +                # unknown mode, ignore +                pass      async def onPart (self, nick, user, host, message, channel, **kwargs):          if channel not in self.channels: diff --git a/crocoite/test_irc.py b/crocoite/test_irc.py new file mode 100644 index 0000000..268c604 --- /dev/null +++ b/crocoite/test_irc.py @@ -0,0 +1,14 @@ +import pytest +from .irc import ArgparseBot + +def test_mode_parse (): +    assert ArgparseBot.parseMode ('+a') == [('+', 'a')] +    assert ArgparseBot.parseMode ('+ab') == [('+', 'a'), ('+', 'b')] +    assert ArgparseBot.parseMode ('+a+b') == [('+', 'a'), ('+', 'b')] +    assert ArgparseBot.parseMode ('-a') == [('-', 'a')] +    assert ArgparseBot.parseMode ('-ab') == [('-', 'a'), ('-', 'b')] +    assert ArgparseBot.parseMode ('-a-b') == [('-', 'a'), ('-', 'b')] +    assert ArgparseBot.parseMode ('+a-b') == [('+', 'a'), ('-', 'b')] +    assert ArgparseBot.parseMode ('-a+b') == [('-', 'a'), ('+', 'b')] +    assert ArgparseBot.parseMode ('-ab+cd') == [('-', 'a'), ('-', 'b'), ('+', 'c'), ('+', 'd')] + | 
