[TASK] Implement Mode,Topic and restructure the way parsing works.

This commit is contained in:
Jan Philipp Timme 2015-10-25 12:12:11 +01:00
parent 7b08f9512b
commit f5dba3f6ef
2 changed files with 111 additions and 45 deletions

3
bot.py
View File

@ -98,7 +98,6 @@ class IrcProtocol(ManagedProtocol):
self.send_data(data) self.send_data(data)
def msg_received(self, msg): def msg_received(self, msg):
print(str(msg), msg.data)
if isinstance(msg, irc.Ping): if isinstance(msg, irc.Ping):
self.send_msg(irc.Pong(msg)) self.send_msg(irc.Pong(msg))
if isinstance(msg, irc.Message) and msg.get('command') == "376": if isinstance(msg, irc.Message) and msg.get('command') == "376":
@ -111,7 +110,7 @@ class IrcProtocol(ManagedProtocol):
if msg.message.startswith("\x01") and msg.message.endswith("\x01"): if msg.message.startswith("\x01") and msg.message.endswith("\x01"):
text = msg.message.strip("\x01") text = msg.message.strip("\x01")
if text.upper() == "VERSION": if text.upper() == "VERSION":
self.send_msg(irc.Privmsg(msg.source, "\x01HalloWelt lustiger Client v0.0.1\x01")) self.send_msg(irc.Privmsg(msg.get("nick"), "\x01HalloWelt lustiger Client v0.0.1\x01"))
def ready(self): def ready(self):
for channel in self._config["channels"]: for channel in self._config["channels"]:

153
irc.py
View File

@ -4,7 +4,7 @@ def parse(line):
prefix = "" prefix = ""
if line[0:1] == ":": if line[0:1] == ":":
prefix = ":" prefix = ":"
subject, line = line.split(None, 1) subject, line = line.split(" ", 1)
subject = subject[1:] subject = subject[1:]
else: else:
subject = "" subject = ""
@ -21,6 +21,7 @@ def parse(line):
s_nick, s_identname = subject.split("!", 1) s_nick, s_identname = subject.split("!", 1)
if "@" in s_identname: if "@" in s_identname:
s_identname, s_host = s_identname.split("@", 1) s_identname, s_host = s_identname.split("@", 1)
s_identname = s_identname.strip("~")
else: else:
s_nick = s_identname = s_host = subject s_nick = s_identname = s_host = subject
return { return {
@ -40,24 +41,26 @@ class Message(object):
""" """
_command_map = {} _command_map = {}
def __init__(self): def __init__(self, data=None, *args, **kwargs):
self.data = { if data == None:
"prefix": "", self.data = {
"subject": "", "prefix": "",
"command": "", "subject": "",
"params": "", "command": "",
"trailing": "", "params": "",
"nick": "", "trailing": "",
"ident": "", "nick": "",
"host": "" "ident": "",
} "host": ""
}
else:
self.data = data
self.parse()
@classmethod @classmethod
def from_string(cls, string): def from_string(cls, string):
data = parse(string) data = parse(string)
print(data) instance = cls._command_map.get(data["command"].upper(), cls)(data=data)
instance = cls._command_map.get(data["command"].upper(), cls)()
instance.update(data)
return instance return instance
def __repr__(self): def __repr__(self):
@ -87,6 +90,7 @@ class Message(object):
self.data.update(data) self.data.update(data)
# Reparse self in order to get consistent data for subclasses # Reparse self in order to get consistent data for subclasses
self.data.update(parse(str(self))) self.data.update(parse(str(self)))
# Now have the subclass parse the relevant values out of the self-interpretation
self.parse() self.parse()
def register_derivative(name, bases, attr): def register_derivative(name, bases, attr):
@ -101,9 +105,9 @@ def register_derivative(name, bases, attr):
return new_cls return new_cls
class User(Message, metaclass=register_derivative): class User(Message, metaclass=register_derivative):
def __init__(self, ident=None, realname=None, *args, **kwargs): def __init__(self, ident="", realname="", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if ident != None and realname != None: if "data" not in kwargs:
self.update({ self.update({
"command": "USER", "command": "USER",
"params": [ident, "*", "*"], "params": [ident, "*", "*"],
@ -111,9 +115,9 @@ class User(Message, metaclass=register_derivative):
}) })
class Nick(Message, metaclass=register_derivative): class Nick(Message, metaclass=register_derivative):
def __init__(self, nick=None, *args, **kwargs): def __init__(self, nick="", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if nick != None: if "data" not in kwargs:
self.update({ self.update({
"command": "NICK", "command": "NICK",
"trailing": nick "trailing": nick
@ -124,9 +128,9 @@ class Ping(Message, metaclass=register_derivative):
self.payload = self.get("trailing") self.payload = self.get("trailing")
class Pong(Message, metaclass=register_derivative): class Pong(Message, metaclass=register_derivative):
def __init__(self, ping=None, *args, **kwargs): def __init__(self, ping="", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if ping != None: if "data" not in kwargs:
self.update({ self.update({
"command": "PONG", "command": "PONG",
"trailing": ping.data["trailing"] "trailing": ping.data["trailing"]
@ -135,37 +139,37 @@ class Pong(Message, metaclass=register_derivative):
self.payload = self.get("trailing") self.payload = self.get("trailing")
class Privmsg(Message, metaclass=register_derivative): class Privmsg(Message, metaclass=register_derivative):
def __init__(self, target=None, message=None, *args, **kwargs): def __init__(self, target="", message="", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if target != None and message != None: if "data" not in kwargs:
self.update({ self.update({
"command": "PRIVMSG", "command": "PRIVMSG",
"params": [target], "params": [target],
"trailing": message "trailing": message
}) })
def parse(self): def parse(self):
self.source = self.get("subject") self.source = self.get("nick")
self.target = self.get("params")[0] self.target = self.get("params")[0]
self.message = self.get("trailing") self.message = self.get("trailing")
class Notice(Message, metaclass=register_derivative): class Notice(Message, metaclass=register_derivative):
def __init__(self, target=None, message=None, *args, **kwargs): def __init__(self, target="", message="", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if target != None and message != None: if "data" not in kwargs:
self.update({ self.update({
"command": "NOTICE", "command": "NOTICE",
"params": [target], "params": [target],
"trailing": message "trailing": message
}) })
def parse(self): def parse(self):
self.source = self.get("subject") self.source = self.get("nick")
self.target = self.get("params")[0] self.target = self.get("params")[0]
self.message = self.get("trailing") self.message = self.get("trailing")
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="", user="", message="KICK", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if channel != None and user != None: if "data" not in kwargs:
self.update({ self.update({
"command": "KICK", "command": "KICK",
"params": [channel, user], "params": [channel, user],
@ -177,39 +181,102 @@ class Kick(Message, metaclass=register_derivative):
self.message = self.get("trailing") self.message = self.get("trailing")
class Join(Message, metaclass=register_derivative): class Join(Message, metaclass=register_derivative):
def __init__(self, channel=None, *args, **kwargs): def __init__(self, channel="", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if channel != None: if "data" not in kwargs:
self.update({ self.update({
"command": "JOIN", "command": "JOIN",
"trailing": channel "trailing": channel
}) })
def parse(self): def parse(self):
self.nick = self.get("subject") self.nick = self.get("nick")
self.channel = self.get("trailing") self.channel = self.get("trailing")
if self.channel.strip() == "":
self.channel = self.get("params")[0]
class Part(Message, metaclass=register_derivative): class Part(Message, metaclass=register_derivative):
def __init__(self, channel=None, message="PART", *args, **kwargs): def __init__(self, channel="", message="PART", *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if channel != None: if "data" not in kwargs:
self.update({ self.update({
"command": "PART", "command": "PART",
"params": [channel], "params": [channel],
"trailing": message "trailing": message
}) })
def parse(self):
self.nick = self.get("nick")
self.channel = self.get("params")[0]
self.message = self.get("trailing")
class Mode(Message, metaclass=register_derivative):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if "data" not in kwargs:
self.update({
"command": "MODE",
})
def parse(self):
self.usermode = False
self.source = self.get("nick")
self.subject = self.get("params")[0]
print(self.get("params"))
if(self.source == self.subject):
"""Parsing user modes here."""
self.usermode = True
flags = self.get("trailing")
flag_modifier = flags[0:1] is "+"
self.flags = []
for flag in flags[1:]:
self.flags.append((flag, flag_modifier))
elif(len(self.get("params")) == 2):
"""Parsing simple channel modes here."""
flags = self.get("params")[1]
flag_modifier = flags[0:1] is "+"
self.flags = []
for flag in flags[1:]:
self.flags.append((flag, flag_modifier))
else:
"""Parsing parameterized channel modes here."""
flags = self.get("params")[1]
flag_modifier = flags[0:1] is "+"
self.flags = []
i = 1
for flag in flags[1:]:
self.flags.append((flag, flag_modifier, self.get("params")[1+i]))
i += 1
class Topic(Message, metaclass=register_derivative):
def __init__(self, channel="", topic="", *args, **kwargs):
super().__init__(*args, **kwargs)
if "data" not in kwargs:
self.update({
"command": "TOPIC",
"params": [channel],
"trailing": topic
})
def parse(self):
self.source = self.get("nick")
self.channel = self.get("params")[0]
self.topic = self.get("trailing")
if __name__ == "__main__": if __name__ == "__main__":
l = Message.from_string(":JPT|NC!~AS@euirc-6f528752.pools.arcor-ip.net JOIN :#euirc") buffer = b":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\r\n:JPT|NC MODE JPT|NC :+ix\r\n:SpamScanner!service@central.euirc.net PRIVMSG JPT|NC :\x01VERSION\x01\r\n:JPT|NC!~AS@euirc-6f528752.pools.arcor-ip.net JOIN :#Tonari.\r\n:Lunlun!~l00n@euirc-e7be0d00.dip0.t-ipconnect.de JOIN :#Tonari.\r\n:ChanServ!services@euirc.net MODE #Tonari. +ao Lunlun Lunlun\r\n:Nitori!~kappa@chireiden.net PRIVMSG JPT|NC :\x01VERSION\x01\r\nPING :irc.inn.at.euirc.net\r\n:JPT|NC!~ADS@dslc-082-082-091-237.pools.arcor-ip.net JOIN #botted\r\n:JPT|NC!~ADS@dslc-082-082-091-237.pools.arcor-ip.net QUIT :Ping timeout: 272 seconds\r\nERROR :Closing Link: dslc-082-082-091-237.pools.arcor-ip.net (Ping timeout: 272 seconds)\r\n:JPT!~jpt@jpt.lu MODE #botted -h Pb42\r\n:JPT!~jpt@jpt.lu MODE #botted +v Pb42\r\n:JPT!~jpt@jpt.lu MODE #botted +o Pb42\r\n:JPT!~jpt@jpt.lu MODE #botted -vo Pb42 Pb42\r\n:JPT!~jpt@jpt.lu MODE #botted +b *illegal*!*@*\r\n:JPT!~jpt@jpt.lu MODE #botted -b *illegal*!*@*\r\n:JPT!~jpt@jpt.lu TOPIC #botted :#botted - edited\r\nPING :irc.hes.de.euirc.net\r\nPONG :irc.hes.de.euirc.net\r\n:JPT!~jpt@jpt.lu TOPIC #botted :#botted\r\n:JPT!~jpt@jpt.lu MODE #botted +i\r\n:JPT!~jpt@jpt.lu MODE #botted -i\r\n"
print(str(l)) while b"\r\n" in buffer:
print() line, buffer = buffer.split(b"\r\n", 1)
if line == b"":
continue
line = line.decode("utf-8")
msg = Message.from_string(line)
print(str(msg))
if msg.__class__.__name__ == 'Message':
print(msg.__dict__)
else:
d = msg.__dict__
del d["data"]
print(d)
l = Message.from_string(":ChanServ!services@euirc.net MODE #Tonari. +ao JPT JPT") print()
print(str(l))
print()
line3 = Join("#botted")
print(str(line3))
exit() exit()