From 1231e9066a3fcf49bcaa6499e2407ff879d14227 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Wed, 3 Oct 2018 13:38:10 +0200 Subject: irc: Fix mode parsing Ignore unsupported modes, add tests. --- crocoite/irc.py | 30 +++++++++++++++++++++++------- crocoite/test_irc.py | 14 ++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 crocoite/test_irc.py 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')] + -- cgit v1.2.3