[TASK] Begin implementing actual irc commands.

This commit is contained in:
Jan Philipp Timme 2015-10-24 23:55:08 +02:00
parent ae23383e15
commit aed245779f
2 changed files with 103 additions and 18 deletions

26
bot.py
View File

@ -73,9 +73,8 @@ class IrcProtocol(ManagedProtocol):
def connection_made(self, transport): def connection_made(self, transport):
super(IrcProtocol, self).connection_made(transport) super(IrcProtocol, self).connection_made(transport)
self.send_data(b"USER " + self.encode(self._config["user"]) + b" dummy dummy :" self.send_msg(irc.User(self._config["ident"], self._config["realname"]))
+ self.encode(self._config["realname"]) + b"\r\n") self.send_msg(irc.Nick(self._config["nick"]))
self.send_data(b"NICK " + self.encode(self._config["nick"]) + b"\r\n")
def data_received(self, data): def data_received(self, data):
super(IrcProtocol, self).data_received(data) super(IrcProtocol, self).data_received(data)
@ -86,9 +85,24 @@ class IrcProtocol(ManagedProtocol):
while b"\r\n" in self._buffer: while b"\r\n" in self._buffer:
line, self._buffer = self._buffer.split(b"\r\n", 1) line, self._buffer = self._buffer.split(b"\r\n", 1)
line = self.decode(line.strip()) line = self.decode(line.strip())
irc_line = irc.IrcLine.from_string(line) msg = irc.Message.from_string(line)
print(self.encode(str(irc_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): class ConnectionManager(object):
"""Takes care of known endpoints that a connections shall be established to. """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), { connection_manager.add_endpoint(("irc.euirc.net", 6667), {
"encoding": "utf-8", "encoding": "utf-8",
"nick": "Pb42", "nick": "Pb42",
"user": "foobar2000", "ident": "foobar2000",
"realname": "Baz McBatzen", "realname": "Baz McBatzen",
"channels": ["#botted"] "channels": ["#botted"]
}) })

95
irc.py
View File

@ -18,24 +18,30 @@ def parse(line):
params = middle[:] params = middle[:]
return {"prefix": prefix, "subject": subject, "command": command, "params": params, "trailing": trailing} return {"prefix": prefix, "subject": subject, "command": command, "params": params, "trailing": trailing}
class Message(object): class Message(object):
"""Handles translation between strings and IrcLines """Handles translation between strings and IrcLines
""" """
_command_map = {} _command_map = {}
def __init__(self, data={"prefix": "", "subject": "", "command": "", "params": "", "trailing": ""}): def __init__(self):
self.data = data self.data = {
"prefix": "",
"subject": "",
"command": "",
"params": "",
"trailing": ""
}
@classmethod @classmethod
def from_string(cls, string): def from_string(cls, string):
data = parse(string) data = parse(string)
instance = cls._command_map.get(data["command"].upper(), cls)(data) instance = cls._command_map.get(data["command"].upper(), cls)()
instance.data = data instance.set_data(data)
return instance return instance
def __repr__(self): def __repr__(self):
data = self.data data = self.data
print(data)
e = [] e = []
if data["subject"]: if data["subject"]:
e.append(data["subject"]) e.append(data["subject"])
@ -48,7 +54,13 @@ class Message(object):
result = " ".join(e) result = " ".join(e)
if data["prefix"]: if data["prefix"]:
result = "".join([data["prefix"], result]) 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): def register_derivative(name, bases, attr):
new_cls = type(name, bases, attr) new_cls = type(name, bases, attr)
@ -61,18 +73,79 @@ def register_derivative(name, bases, attr):
cmd_map[command] = new_cls cmd_map[command] = new_cls
return 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 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): class Kick(Message, metaclass=register_derivative):
def __init__(self, channel=None, user=None, message="KICK", *args, **kwargs): def __init__(self, channel=None, user=None, message="KICK", *args, **kwargs):
super(Kick, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.data.update({ self.data.update({
"command": "KICK", "command": "KICK",
"params": [channel, user], "params": [channel, user],
"trailing": message "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__": if __name__ == "__main__":
l = Message.from_string(":JPT|NC!~AS@euirc-6f528752.pools.arcor-ip.net JOIN :#euirc") 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(str(l))
print() print()
line = Kick("#botted", "JPT", "Du Sack!") line3 = Join("#botted")
print(str(line)) print(str(line3))
line2 = Message.from_string(str(line))
print(str(line2))
exit() exit()