diff --git a/piebot/irc.py b/piebot/irc.py index 49fade6..da3f364 100644 --- a/piebot/irc.py +++ b/piebot/irc.py @@ -2,20 +2,22 @@ def parse(line): prefix = "" + subject = "" + trailing = "" + command = "" + params = "" if line[0:1] == ":": prefix = ":" - subject, line = line.split(" ", 1) - subject = subject[1:] - else: - subject = "" + line = line[1:] + if " " in line: + subject, line = line.split(" ", 1) if " :" in line: - tmp_str, trailing = line.split(" :", 1) - tmp_args = tmp_str.split() + line, trailing = line.split(" :", 1) + if " " in line: + command, *middle = line.split() + params = middle[:] else: - trailing = "" - tmp_args = line.split() - command, *middle = tmp_args - params = middle[:] + command = line # Now prepare parsing the subject if possible. if subject != "" and "!" in subject: s_nick, s_identname = subject.split("!", 1) @@ -24,7 +26,7 @@ def parse(line): s_identname = s_identname.strip("~") else: s_nick = s_identname = s_host = subject - return { + result = { "prefix": prefix, "subject": subject, "command": command, @@ -34,6 +36,7 @@ def parse(line): "ident": s_identname, "host": s_host } + return result class Message(object): @@ -88,7 +91,7 @@ class Message(object): e.append(":{}".format(data["trailing"])) result = " ".join(e) if data["prefix"]: - result = "".join([data["prefix"], result]) + result = data["prefix"] + result return result def get(self, attr): @@ -142,16 +145,24 @@ class Nick(Message, metaclass=register_derivative): self.nick = self.get("trailing") class Ping(Message, metaclass=register_derivative): + def __init__(self, payload="", *args, **kwargs): + super().__init__(*args, **kwargs) + if "data" not in kwargs: + self.update({ + "command": "PING", + "trailing": payload + }) def parse(self): self.payload = self.get("trailing") class Pong(Message, metaclass=register_derivative): - def __init__(self, ping="", *args, **kwargs): + def __init__(self, ping="", payload="", *args, **kwargs): super().__init__(*args, **kwargs) if "data" not in kwargs: + if ping: payload = ping.data["trailing"] self.update({ "command": "PONG", - "trailing": ping.data["trailing"] + "trailing": payload }) def parse(self): self.payload = self.get("trailing") diff --git a/tests/test_message.py b/tests/test_message.py new file mode 100644 index 0000000..cbe3124 --- /dev/null +++ b/tests/test_message.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- + +import unittest +from piebot import irc + + +class Message(unittest.TestCase): + + def test_parse_user(self): + raw = "USER ident * * :real name" + msg = irc.Message.from_string(raw) + self.assertIsInstance(msg, irc.User, msg="Not a User!") + self.assertEqual(msg.ident, "ident") + self.assertEqual(msg.realname, "real name") + + def test_construct_user(self): + msg = irc.User(ident="hans", realname="peter blubber") + self.assertEqual(str(msg), "USER hans * * :peter blubber") + + + def test_parse_nick(self): + raw = ":oldnick!~somebody@internet.org NICK :newnick" + msg = irc.Message.from_string(raw) + self.assertIsInstance(msg, irc.Nick, msg="Not a Nick!") + self.assertEqual(msg.old_nick, "oldnick") + self.assertEqual(msg.nick, "newnick") + + def test_construct_nick(self): + msg = irc.Nick(nick="foobar") + self.assertEqual(str(msg), "NICK :foobar") + + + def test_parse_ping(self): + raw = "PING :payload" + msg = irc.Message.from_string(raw) + self.assertIsInstance(msg, irc.Ping, msg="Not a Ping!") + self.assertEqual(msg.payload, "payload") + + def test_construct_ping(self): + msg = irc.Ping("payload") + self.assertEqual(str(msg), "PING :payload") + + + def test_parse_pong(self): + raw = "PONG :doalyap" + msg = irc.Message.from_string(raw) + self.assertIsInstance(msg, irc.Pong, msg="Not a Pong!") + self.assertEqual(msg.payload, "doalyap") + + def test_construct_pong(self): + msg = irc.Pong(payload="payload") + self.assertEqual(str(msg), "PONG :payload") + + + def test_parse_privmsg(self): + raw = ":this!~is@spart.aaa PRIVMSG #target :whoop dee doo!" + msg = irc.Message.from_string(raw) + self.assertIsInstance(msg, irc.Privmsg, msg="Not a Privmsg!") + self.assertEqual(msg.source, "this") + self.assertEqual(msg.target, "#target") + self.assertEqual(msg.message, "whoop dee doo!") + + def test_construct_privmsg(self): + msg = irc.Privmsg(target="#example", message="How dee ho!") + self.assertEqual(str(msg), "PRIVMSG #example :How dee ho!") + + + def test_parse_notice(self): + raw = ":john!~secret@agents.de NOTICE this_is_you :bleep bleep!" + msg = irc.Message.from_string(raw) + self.assertIsInstance(msg, irc.Notice, msg="Not a Notice!") + self.assertEqual(msg.source, "john") + self.assertEqual(msg.target, "this_is_you") + self.assertEqual(msg.message, "bleep bleep!") + + def test_construct_notice(self): + msg = irc.Notice(target="#somewhere", message="wheee eee!") + self.assertEqual(str(msg), "NOTICE #somewhere :wheee eee!") + diff --git a/tests/test_parser.py b/tests/test_parser.py index 46bf3f1..d99f14f 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,10 +1,46 @@ +# -*- coding: utf-8 -*- + import unittest from piebot import irc -class TestParser(unittest.TestCase): - def test_test(self): - source = ":irc.inn.at.euirc.net 001 JPT|NC :Welcome to the euIRCnet IRC Network JPT|NC!~AS@dslc-082-082-091-237.pools.arcor-ip.net" - msg = irc.Message.from_string(source) - created = str(msg) - self.assertEqual(source, created) +class Parser(unittest.TestCase): + + def test_parse_generic_message_one(self): + raw = ":someserver.net 123 one two three :Let's parse a generic formatted msg!" + msg = irc.Message.from_string(raw) + self.assertEqual(str(msg), raw, msg="String representation does not match!") + self.assertEqual(msg.get("prefix"), ":", msg="Incorrect prefix!") + self.assertEqual(msg.get("subject"), "someserver.net", msg="Incorrect subject!") + self.assertEqual(msg.get("command"), "123", msg="Incorrect command!") + self.assertEqual(msg.get("params"), ["one", "two", "three"], msg="Incorrect params!") + self.assertEqual(msg.get("trailing"), "Let's parse a generic formatted msg!", msg="Incorrect trailing!") + self.assertEqual(msg.get("nick"), "someserver.net", msg="Incorrect nick!") + self.assertEqual(msg.get("ident"), "someserver.net", msg="Incorrect ident!") + self.assertEqual(msg.get("host"), "someserver.net", msg="Incorrect host!") + + def test_parse_generic_message_two(self): + raw = ":ralf!~wiggum@simpsons.net PRIVMSG #channel :duck duck duck duck" + msg = irc.Message.from_string(raw) + self.assertEqual(str(msg), raw, msg="String representation does not match!") + self.assertEqual(msg.get("prefix"), ":", msg="Incorrect prefix!") + self.assertEqual(msg.get("subject"), "ralf!~wiggum@simpsons.net", msg="Incorrect subject!") + self.assertEqual(msg.get("command"), "PRIVMSG", msg="Incorrect command!") + self.assertEqual(msg.get("params"), ["#channel"], msg="Incorrect params!") + self.assertEqual(msg.get("trailing"), "duck duck duck duck", msg="Incorrect trailing!") + self.assertEqual(msg.get("nick"), "ralf", msg="Incorrect nick!") + self.assertEqual(msg.get("ident"), "wiggum", msg="Incorrect ident!") + self.assertEqual(msg.get("host"), "simpsons.net", msg="Incorrect host!") + + def test_parse_generic_message_three(self): + raw = ":peter!~per@griffin.com MODE peter +ix" + msg = irc.Message.from_string(raw) + self.assertEqual(str(msg), raw, msg="String representation does not match!") + self.assertEqual(msg.get("prefix"), ":", msg="Incorrect prefix!") + self.assertEqual(msg.get("subject"), "peter!~per@griffin.com", msg="Incorrect subject!") + self.assertEqual(msg.get("command"), "MODE", msg="Incorrect command!") + self.assertEqual(msg.get("params"), ["peter", "+ix"], msg="Incorrect params!") + self.assertEqual(msg.get("trailing"), "", msg="Incorrect trailing!") + self.assertEqual(msg.get("nick"), "peter", msg="Incorrect nick!") + self.assertEqual(msg.get("ident"), "per", msg="Incorrect ident!") + self.assertEqual(msg.get("host"), "griffin.com", msg="Incorrect host!")