From aed245779f417ed71586b2f582b432726a5389fb Mon Sep 17 00:00:00 2001 From: Jan Philipp Timme Date: Sat, 24 Oct 2015 23:55:08 +0200 Subject: [PATCH] [TASK] Begin implementing actual irc commands. --- bot.py | 26 ++++++++++++---- irc.py | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 103 insertions(+), 18 deletions(-) diff --git a/bot.py b/bot.py index 7dc6106..b1aad78 100644 --- a/bot.py +++ b/bot.py @@ -73,9 +73,8 @@ class IrcProtocol(ManagedProtocol): def connection_made(self, transport): super(IrcProtocol, self).connection_made(transport) - self.send_data(b"USER " + self.encode(self._config["user"]) + b" dummy dummy :" - + self.encode(self._config["realname"]) + b"\r\n") - self.send_data(b"NICK " + self.encode(self._config["nick"]) + b"\r\n") + self.send_msg(irc.User(self._config["ident"], self._config["realname"])) + self.send_msg(irc.Nick(self._config["nick"])) def data_received(self, data): super(IrcProtocol, self).data_received(data) @@ -86,9 +85,24 @@ class IrcProtocol(ManagedProtocol): while b"\r\n" in self._buffer: line, self._buffer = self._buffer.split(b"\r\n", 1) line = self.decode(line.strip()) - irc_line = irc.IrcLine.from_string(line) - print(self.encode(str(irc_line))) + msg = irc.Message.from_string(line) + self.msg_received(msg) + def send_msg(self, msg): + if isinstance(msg, irc.Message): + data = self.encode(str(msg)) + self.send_data(data) + + def msg_received(self, msg): + if isinstance(msg, irc.Ping): + self.send_msg(irc.Pong(msg)) + if isinstance(msg, irc.Message) and msg.get('command') == "376": + self.ready() + + def ready(self): + for channel in self._config["channels"]: + self.send_msg(irc.Join(channel)) + self.send_msg(irc.Privmsg(channel, "Hallo Welt!")) class ConnectionManager(object): """Takes care of known endpoints that a connections shall be established to. @@ -149,7 +163,7 @@ if __name__ == "__main__": connection_manager.add_endpoint(("irc.euirc.net", 6667), { "encoding": "utf-8", "nick": "Pb42", - "user": "foobar2000", + "ident": "foobar2000", "realname": "Baz McBatzen", "channels": ["#botted"] }) diff --git a/irc.py b/irc.py index 3760872..2458dba 100644 --- a/irc.py +++ b/irc.py @@ -18,24 +18,30 @@ def parse(line): params = middle[:] return {"prefix": prefix, "subject": subject, "command": command, "params": params, "trailing": trailing} + class Message(object): """Handles translation between strings and IrcLines """ _command_map = {} - def __init__(self, data={"prefix": "", "subject": "", "command": "", "params": "", "trailing": ""}): - self.data = data + def __init__(self): + self.data = { + "prefix": "", + "subject": "", + "command": "", + "params": "", + "trailing": "" + } @classmethod def from_string(cls, string): data = parse(string) - instance = cls._command_map.get(data["command"].upper(), cls)(data) - instance.data = data + instance = cls._command_map.get(data["command"].upper(), cls)() + instance.set_data(data) return instance def __repr__(self): data = self.data - print(data) e = [] if data["subject"]: e.append(data["subject"]) @@ -48,7 +54,13 @@ class Message(object): result = " ".join(e) if data["prefix"]: result = "".join([data["prefix"], result]) - return result + return result+"\r\n" + + def get(self, attr): + return self.data[attr] + + def set_data(self, data): + self.data = data def register_derivative(name, bases, attr): new_cls = type(name, bases, attr) @@ -61,18 +73,79 @@ def register_derivative(name, bases, attr): cmd_map[command] = new_cls return new_cls -class Privmsg(Message, metaclass=register_derivative): +class User(Message, metaclass=register_derivative): + def __init__(self, ident=None, realname=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.data.update({ + "command": "USER", + "params": [ident, "*", "*"], + "trailing": realname + }) + +class Nick(Message, metaclass=register_derivative): + def __init__(self, nick=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.data.update({ + "command": "NICK", + "trailing": nick + }) + +class Ping(Message, metaclass=register_derivative): pass +class Pong(Message, metaclass=register_derivative): + def __init__(self, ping=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.data.update({ + "command": "PONG", + "trailing": ping.data["trailing"] + }) + +class Privmsg(Message, metaclass=register_derivative): + def __init__(self, target=None, message=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.data.update({ + "command": "PRIVMSG", + "params": [target], + "trailing": message + }) + +class Notice(Message, metaclass=register_derivative): + def __init__(self, target=None, message=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.data.update({ + "command": "NOTICE", + "params": [target], + "trailing": message + }) + class Kick(Message, metaclass=register_derivative): def __init__(self, channel=None, user=None, message="KICK", *args, **kwargs): - super(Kick, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.data.update({ "command": "KICK", "params": [channel, user], "trailing": message }) +class Join(Message, metaclass=register_derivative): + def __init__(self, channel=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.data.update({ + "command": "JOIN", + "trailing": channel + }) + +class Part(Message, metaclass=register_derivative): + def __init__(self, channel=None, message="PART", *args, **kwargs): + super().__init__(*args, **kwargs) + self.data.update({ + "command": "PART", + "params": [channel], + "trailing": message + }) + + if __name__ == "__main__": l = Message.from_string(":JPT|NC!~AS@euirc-6f528752.pools.arcor-ip.net JOIN :#euirc") @@ -83,11 +156,9 @@ if __name__ == "__main__": print(str(l)) print() - line = Kick("#botted", "JPT", "Du Sack!") - print(str(line)) + line3 = Join("#botted") + print(str(line3)) - line2 = Message.from_string(str(line)) - print(str(line2)) exit()