def __init__(self): self.buf = b"" self.event = Events() self.event.add("data", self.ondata) self.event.add("line", self.onrecvline) self.event.add("msg", self.onmsg)
class Client(object): def __init__(self, nick): self.parser = Parser() self.writer = Writer() self.conn = Connection() self.event = Events() self.conn.event.add("recv", self.parser.event.notify, "data") self.writer.event.add("data", self.conn.event.notify, "send") self.parser.event.add("nick", self.onnick) self.parser.event.add("ping", self.onping) self.parser.event.add("privmsg", self.onprivmsg) self._nick = nick self._quit = False def start(self, server, port): self.conn.connect(server, port) self.writer.nick(self._nick) self.writer.user("ignored", "ignored", "ignored", "ignored") self.conn.recvloop() def onprivmsg(self, nick, user, host, mask, msg): if mask == self._nick: mask = None elif not mask.startswith("#"): return msg = ChatMessage(self, nick, user, host, msg, mask) self.event.notify("chatmsg", msg) def onping(self, token): self.writer.pong(token) def onnick(self, nick, user, host, new): if nick == self._nick: self._nick = new
class Writer(object): def __init__(self): self.lock = threading.RLock() # (use "with"-block to lock writer) self.event = Events() self.messagetokens = TokenBucket(6, 16) # 5 Messages per 16 seconds self.event.add("line", self.onwriteline) def onwriteline(self, line): with self.lock: self.event.notify("data", line + b"\r\n") def command(self, command, args): if(len(args) != 0): args[-1] = b":" + args[-1] argstr = b" ".join(args) else: argstr = b"" command = command.encode("iso-8859-1") line = command + b" " + argstr self.event.notify("line", line) def join(self, chan): chan = chan.encode("iso-8859-1") self.command("JOIN", [chan]) def part(self, chan): self.command("PART", [chan]) def quit(self, msg): self._quit = True self.command("QUIT", [msg]) def nick(self, nick): nick = nick.encode("iso-8859-1") self.command("NICK", [nick]) def user(self, username, hostname, servername, realname): username = username.encode("iso-8859-1") hostname = hostname.encode("iso-8859-1") servername = servername.encode("iso-8859-1") realname = realname.encode("utf-8") self.command("USER", [username, hostname, servername, realname]) def pong(self, msg): self.command("PONG", [msg]) def msgline(self, recipient, msg, blocking=True): return self.msglines(recipient, [msg], blocking) def msglines(self, recipient, lines, blocking=True): recipient = recipient.encode("iso-8859-1") if self.messagetokens.consume(len(lines), blocking): for line in lines: line = line.encode("utf-8") self.command("PRIVMSG", [recipient, line]) return True return False
def __init__(self, nick): self.parser = Parser() self.writer = Writer() self.conn = Connection() self.event = Events() self.conn.event.add("recv", self.parser.event.notify, "data") self.writer.event.add("data", self.conn.event.notify, "send") self.parser.event.add("nick", self.onnick) self.parser.event.add("ping", self.onping) self.parser.event.add("privmsg", self.onprivmsg) self._nick = nick self._quit = False
class Connection(object): def __init__(self): self.socket = socket.socket() self.event = Events() self.event.add("send", self.onsend) def connect(self, server, port): self.socket.connect((server, port)) def recvloop(self): while True: data = self.socket.recv(4096) if data == "": self.event.notify("disconnect") return self.event.notify("recv", data) def onsend(self, data): self.socket.sendall(data)
class Parser(object): def __init__(self): self.buf = b"" self.event = Events() self.event.add("data", self.ondata) self.event.add("line", self.onrecvline) self.event.add("msg", self.onmsg) def reset(self): self.buf = b"" def ondata(self, data): self.buf += data lines = self.buf.split(b"\r\n") self.buf = lines.pop() for line in lines: self.event.notify("line", line) def onrecvline(self, line): match = message_matcher.match(line) if match == None: return servername = match.group(3) nick = match.group(5) user = match.group(6) host = match.group(7) command = match.group(8) params = match.group(12).split(b" ")[1:] trailparam = match.group(15) servername = servername and servername.decode("iso-8859-1", "ignore") nick = nick and nick.decode("iso-8859-1", "ignore") user = user and user.decode("iso-8859-1", "ignore") host = host and host.decode("iso-8859-1", "ignore") command = command and command.decode("iso-8859-1", "ignore") if trailparam != None: params += [trailparam] self.event.notify("msg", servername, nick, user, host, command, params) def onmsg(self, servername, nick, user, host, command, args): if(command == "332"): self.event.notify("topic", nick, user, host, args[0], args[1], args[2]) elif(command == "PING"): self.event.notify("ping", args[0]) elif(command == "NICK"): nick, = args nick = nick.decode("iso-8859-1", "ignore") self.event.notify("nick", nick, user, host, args[0]) elif(command == "NOTICE"): mask, message = args mask = mask.decode("iso-8859-1", "ignore") message = message.decode("utf-8", "ignore") self.event.notify("notice", nick, user, host, mask, message) elif(command == "PRIVMSG"): mask, message = args mask = mask.decode("iso-8859-1", "ignore") message = message.decode("utf-8", "ignore") self.event.notify("privmsg", nick, user, host, mask, message) elif(command == "376"): self.event.notify("endofmotd", nick, user, host, args[0])
def __init__(self): self.socket = socket.socket() self.event = Events() self.event.add("send", self.onsend)
def __init__(self): self.lock = threading.RLock() # (use "with"-block to lock writer) self.event = Events() self.messagetokens = TokenBucket(6, 16) # 5 Messages per 16 seconds self.event.add("line", self.onwriteline)