diff --git a/guppy.py b/guppy.py index 72e0f50e26944f6d1a6d3c9d608e2a7a1a8b626b..f750b1017fcadff4e290880526ad7a173e085eaa 100644 --- a/guppy.py +++ b/guppy.py @@ -20,13 +20,13 @@ import argparse import sys import os import ConfigParser +import asyncore import irc -import threading, time class main(object): def __init__(self): # Constant. - self.version = "0.4.0" + self.version = "0.4.1" print(" __ _ _ _ _ __ _ __ _ _ ") print(" / _` | | | | '_ \| '_ \| | | | http://repo.or.cz/w/guppy.git/summary") print("| (_| | |_| | |_) | |_) | |_| |") @@ -66,6 +66,7 @@ class main(object): self.config.read(self.configpath) def start(self): + self.clients = [] for section in self.config.sections(): server_config = {} server_config["network"] = section @@ -73,21 +74,14 @@ class main(object): for item,value in self.config.items(section): server_config[item] = value - # since IRC is a subclass of threading.Thread, using - # .start() on it will automatically run it in a new thread. - conn = irc.IRC(server_config) - conn.daemon = True - conn.start() + self.clients.append(irc.IRC(server_config)) - while threading.activeCount() > 1: - time.sleep(15) + asyncore.loop() def stop(self): - for client in threading.enumerate(): - if client.__class__.__name__ != "_MainThread": - client.doQuit("Keyboard interrupt.") - time.sleep(1) - client.pluginManager.unloadAllPlugins() + for client in self.clients: + client.doQuit("Keyboard interrupt.") + client.pluginManager.unloadAllPlugins() def my_raw(self,prompt="", default=""): ret = raw_input("%s [%s]: "%(prompt,default)) @@ -127,6 +121,7 @@ class main(object): self.set(currentNetwork,'ns_name',"NickServ username (if there is none, press ENTER)") self.set(currentNetwork,'ns_pwd',"NickServ password (if there is none, press ENTER)") self.set(currentNetwork,'port',"Port", "6667") + self.set(currentNetwork,'use_ssl','Use ssl (yes/no)', 'no') self.set(currentNetwork,"comchar","My command char", "-") self.set(currentNetwork,"plugins","Plugins to load on startup (comma-separated, no spaces)", "auth,printer,pluginloader") @@ -157,4 +152,3 @@ if __name__ == "__main__": print("Shutting down all connections...") c.stop() print("Quitting!") - time.sleep(2) # to let connections close diff --git a/irc.py b/irc.py index abd701a66b76c34c78035d99147f8b165e74734a..778932c4af35fb290243ab7f1a74cf9ff776de4e 100644 --- a/irc.py +++ b/irc.py @@ -1,4 +1,4 @@ -import socket, os, threading, re +import socket, os, threading, re, asynchat, traceback, ssl import plugins class User(str): @@ -33,6 +33,9 @@ class PluginManager(object): for command in handler_commands: self.handlers[event][command.lower()] = handler_func else: + if self.handlers.get(event, None) is None: + self.handlers[event] = [] + self.handlers[event].append(handler_func) def unhandle(self, event, handler_func, handler_commands=None): @@ -54,23 +57,17 @@ class PluginManager(object): def event(self, eventName, *args): eventName = eventName.lower() + if self.handlers.get(eventName, None) is None: return + if eventName == "command": handler = self.handlers[eventName].get(args[2].lower(), None) if handler is None: return #no such command - try: - handler(*args) - except Exception, e: - s = handler.__self__ - self.prnt("Plugin "+s.__class__.__name__+" "+e.__class__.__name__+": "+e.__str__()) + handler(*args) else: for handler in self.handlers[eventName]: - try: - handler(*args) - except Exception, e: - s = handler.__self__ - self.prnt("Plugin "+s.__class__.__name__+" "+e.__class__.__name__+": "+e.__str__()) + handler(*args) def loadedPlugin(self, pluginName): return pluginName.lower() in self.plugins @@ -82,27 +79,11 @@ class PluginManager(object): plugins.refresh() if not self.loadedPlugin(pluginName.lower()): if not self.pluginExists(pluginName.lower()): - err = "No such plugin." - return err + return - pClass = None - try: - pClass = plugins.getPlugin(pluginName.lower()) - except Exception, e: - err = "Cannot load plugin "+pluginName+" ("+e.__class__.__name__+": "+e.__str__()+")" - self.prnt(err) - return err + pClass = plugins.getPlugin(pluginName.lower()) - try: - self.plugins[pluginName.lower()] = pClass(self.server) - except Exception, e: - err = "Could not initialize "+pluginName+" ("+e.__class__.__name__+": "+e.__str__()+")" - self.prnt(err) - return err - - else: - err = "Module has already been loaded." - return err + self.plugins[pluginName.lower()] = pClass(self.server) def getPlugin(self, pluginName): try: @@ -131,7 +112,7 @@ class PluginManager(object): newList = {} for cmd,func in eList.items(): if func.__self__ == inst: - destructor = getattr(inst, "__del__", None) + destructor = getattr(inst, "destroy", None) if destructor is not None: destructor() else: @@ -141,7 +122,7 @@ class PluginManager(object): newList = [] for func in eList: if func.__self__ == inst: - destructor = getattr(inst, "__del__", None) + destructor = getattr(inst, "destroy", None) if destructor is not None: destructor() else: @@ -172,9 +153,9 @@ class PluginManager(object): return errs -class IRC(threading.Thread): +class IRC(asynchat.async_chat): def __init__(self, config): - super(IRC, self).__init__() + asynchat.async_chat.__init__(self) self.pluginManager = PluginManager(self) self.config = config self.handle = self.pluginManager.handle @@ -183,186 +164,176 @@ class IRC(threading.Thread): self.plugins = self.pluginManager.plugins self.getPlugin = self.pluginManager.getPlugin errs = self.pluginManager.loadAllPlugins() - if errs: - for k,v in errs.items(): - self.prnt("Plugin "+k+" error loading: "+v) - self.running = False self.userlist = { } - - def _readline(self): - ret = [] - while True: - c = self.conn.recv(1) - if c == '\n': - break - else: - if c != '\r': - ret.append(c) - return "".join(ret) + self.data = "" + self.set_terminator("\r\n") - def run(self): - self.conn = socket.socket() - self.conn.settimeout(60) - try: - self.conn.connect((self.config["host"], int(self.config["port"]))) - self.goodstart = True - except socket.error: - self.prnt("Cannot connect to server.") - self.goodstart = False + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if self.config["use_ssl"].lower().startswith("y"): + try: + self.ssl_sock = ssl.wrap_socket(self.sock) + self.ssl_sock.connect((self.config["host"], int(self.config["port"]))) + self.set_socket(self.ssl_sock) + except ssl.SSLError, error: + self.prnt('SSL Error connecting to server. (Are you using the right port?)') + raise ssl.SSLError(error) + except socket.error, error: + print('There was an error connecting to %s' % address) + return + else: + try: + self.sock.connect((self.config["host"], int(self.config["port"]))) + except socket.error, error: + print('There was an error connecting to %s' % address) + return + self.set_socket(self.sock) + + def _getData(self): + ret = self.data + self.data = '' + return ret + + def found_terminator(self): + data = self._getData() - if self.goodstart: - self.config["ident"] = ident = self.config["ident"] if self.config["ident"] != "" else self.config["nickname"] - self.sendLine("USER "+ident+" * * *") - self.sendLine("NICK "+self.config["nickname"]) + words = data.split(" ") - self.running = self.goodstart - while self.running: - try: - data = self._readline() - except socket.timeout: - self.sendLine("PING BACK") - try: - data = self._readline() - continue - except socket.timeout: - raise IOError("Connection was broken.") - - if not self.running: continue + if words[0] == "PING": + # The server pinged us, we need to pong or we'll be disconnected + # (make sure to send whatever follows the PING, in case they send a random hash) + self.sendLine("PONG " + data[5:]) + return + + # Takes the ':Nick!Ident@Host' chunk and assigns (nick,ident,host) to user + user = None + if words[0].find("!") != -1: + user = User(words[0][words[0].find(":") + 1:words[0].find('!')]) + user.ident = words[0][words[0].find('!') + 1:words[0].find('@')] + user.host = words[0][words[0].find('@') + 1:] + else: + #it's our nick, in the format ":NickName" + user = User(words[0][words[0].find(":") + 1:]) - if data == "": - self.prnt("Connection lost to server.") - self.running = False - continue + if words[1] == "433": + #There was a nick collision + self.config["nickname"] = self.config["nickname"] + "_" + self.sendLine("NICK "+self.config["nickname"]) + + elif words[1] == "422" or words[1] == "376": + # We successfully logged in, do post-login procedures + if self.config["ns_name"] != "" and self.config["ns_pass"] != "": + self.doMessage("NickServ", "IDENTIFY "+self.config["ns_name"]+" "+self.config["ns_pass"]) - words = data.split(" ") + self.pluginManager.event("connect", self.config["network"]) - if words[0] == "PING": - # The server pinged us, we need to pong or we'll be disconnected - # (make sure to send whatever follows the PING, in case they send a random hash) - self.sendLine("PONG " + data[5:]) - continue - elif words[0] == "ERROR": - #there was an error, we probably had a KeyboardInterrupt - self.prnt("Connection lost to server.") - self.running = False - continue + for chan in [k for k in self.config["channels"].split(",") if k != '']: + self.doJoin(chan) + + elif words[1] == "353": + #user list, if it's large, we only got part of it. + words = [k for k in data.replace(" =", "").split(" ") if k != ''] + if self.userlist.get(words[3], None) is None: + self.userlist[words[3]] = [] - # Takes the ':Nick!Ident@Host' chunk and assigns (nick,ident,host) to user - user = None - if words[0].find("!") != -1: - user = User(words[0][words[0].find(":") + 1:words[0].find('!')]) - user.ident = words[0][words[0].find('!') + 1:words[0].find('@')] - user.host = words[0][words[0].find('@') + 1:] + self.userlist[words[3]] += [u.strip(":") for u in words[3:]] + + elif words[1] == "PRIVMSG": + # We got a message + channel = (words[2] if words[2] != self.config["nickname"] else user) + message = data[data.find(":", data.find(channel[(channel.find("-") == -1 and 1 or channel.find("-")):]))+1:] + if message.find("\x01ACTION") == 0: + # String was found, it's an action + self.pluginManager.event("action", channel, user, message[8:-1]) + elif message.find(self.config["comchar"]) == 0: + # String was found, it's a command! + args = message.split(" ") + cmd = args[0][len(self.config["comchar"]):] + args.pop(0) + self.pluginManager.event("message", channel, user, message) + self.pluginManager.event("command", channel, user, cmd.lower(), args) else: - #it's our nick, in the format ":NickName" - user = User(words[0][words[0].find(":") + 1:]) - - if words[1] == "433": - #There was a nick collision - self.config["nickname"] = self.config["nickname"] + "_" - self.sendLine("NICK "+self.config["nickname"]) - - elif words[1] == "422" or words[1] == "376": - # We successfully logged in, do post-login procedures - if self.config["ns_name"] != "" and self.config["ns_pass"] != "": - self.doMessage("NickServ", "IDENTIFY "+self.config["ns_name"]+" "+self.config["ns_pass"]) - - self.pluginManager.event("connect", self.config["host"]) - - for chan in [k for k in self.config["channels"].split(",") if k != '']: - self.doJoin(chan) - - elif words[1] == "353": - #user list, if it's large, we only got part of it. - words = [k for k in data.replace(" =", "").split(" ") if k != ''] - if self.userlist.get(words[3], None) is None: - self.userlist[words[3]] = [] - - userlist = [u.strip(":") for u in words[3:]] - self.userlist[words[3]] += userlist - - elif words[1] == "PRIVMSG": - # We got a message - channel = (words[2] if words[2] != self.config["nickname"] else user) - message = data[data.find(":", data.find(channel[(channel.find("-") == -1 and 1 or channel.find("-")):]))+1:] - if message.find("\x01ACTION") == 0: - # String was found, it's an action - self.pluginManager.event("action", channel, user, message[8:-1]) - elif message.find(self.config["comchar"]) == 0: - # String was found, it's a command! + if re.match("^"+self.config["nickname"]+"[^A-Za-z0-9] .+$", message, flags=re.IGNORECASE): + #Someone addressed us, it's a command (probably) args = message.split(" ") - cmd = args[0][len(self.config["comchar"]):] - args.pop(0) + cmd = args[1] + args = args[2:] self.pluginManager.event("message", channel, user, message) self.pluginManager.event("command", channel, user, cmd.lower(), args) else: - if re.match("^"+self.config["nickname"]+"[^A-Za-z0-9] .+$", message): - #Someone addressed us, it's a command (probably) - args = message.split(" ") - cmd = args[1] - args = args[2:] - self.pluginManager.event("message", channel, user, message) - self.pluginManager.event("command", channel, user, cmd.lower(), args) - else: - #Nothing was found, it has to be a message - self.pluginManager.event("message", channel, user, message) - - elif words[1] == "JOIN": - # Someone joined a channel that we're in - if user != self.config["nickname"]: - self.pluginManager.event("join", words[2].strip(":"), user) - self.userlist[words[2].strip(":")].append(user) - - elif words[1] == "PART": - if user != self.config["nickname"]: - # Someone parted a channel we're in - if user in self.userlist[words[2].strip(":")]: - self.userlist[words[2]].remove(user) - self.pluginManager.event("part", words[2].strip(":"), user, " ".join(words[3:])) - - elif words[1] == "QUIT": - # Someone quit the server - for k in self.userlist.keys(): - if user in self.userlist[k]: - self.userlist[k].remove(user) - self.pluginManager.event("quit", user, " ".join(words[2:])[1:]) - - elif words[1] == "NICK": - # Someone changed their nickname - for k in self.userlist.keys(): - if user in self.userlist[k]: - self.userlist[k].remove(user) - self.userlist[k].append(words[2].strip(":")) - self.pluginManager.event("nick", user, words[2].strip(":")) + #Nothing was found, it has to be a message + self.pluginManager.event("message", channel, user, message) + + elif words[1] == "JOIN": + # Someone joined a channel that we're in + if user != self.config["nickname"]: + self.pluginManager.event("join", words[2].strip(":"), user) + self.userlist[words[2].strip(":")].append(user) + + elif words[1] == "PART": + if user != self.config["nickname"]: + # Someone parted a channel we're in + if user in self.userlist[words[2].strip(":")]: + self.userlist[words[2]].remove(user) + self.pluginManager.event("part", words[2].strip(":"), user, " ".join(words[3:])) + + elif words[1] == "QUIT": + # Someone quit the server + for k in self.userlist.keys(): + if user in self.userlist[k]: + self.userlist[k].remove(user) + self.pluginManager.event("quit", user, " ".join(words[2:])[1:]) + + elif words[1] == "NICK": + # Someone changed their nickname + for k in self.userlist.keys(): + if user in self.userlist[k]: + self.userlist[k].remove(user) + self.userlist[k].append(words[2].strip(":")) + self.pluginManager.event("nick", user, words[2].strip(":")) + + elif words[1] == "MODE": + # Someone set a mode + try: + self.pluginManager.event("mode", words[2], user, words[3], words[4]) + except IndexError: # words[4] is not valid, it wasn't set on a user + self.pluginManager.event("mode", words[2], user, words[3], "") + + elif words[1] == "KICK": + #someone kicked someone + if self.userlist.get(words[2].lower(), None) is not None: + self.userlist[words[2].lower()].remove(words[3]) + + self.pluginManager.event("kick", words[2], user, words[3], words[4][1:]) + + elif words[1] == "NOTICE": + self.pluginManager.event("notice", user, words[2], " ".join(words[3:]).strip(":")) - elif words[1] == "MODE": - # Someone set a mode - try: - self.pluginManager.event("mode", words[2], user, words[3], words[4]) - except IndexError: # words[4] is not valid, it wasn't set on a user - self.pluginManager.event("mode", words[2], user, words[3], "") + else: + self.pluginManager.event(words[1], data) - elif words[1] == "KICK": - #someone kicked someone - if self.userlist.get(words[2].lower(), None) is not None: - self.userlist[words[2].lower()].remove(words[3]) - - self.pluginManager.event("kick", words[2], user, words[3], words[4][1:]) - - #end of loop - if self.goodstart: - self.pluginManager.event("disconnect", self.config["host"]) + def collect_incoming_data(self, data): + self.data += data + def handle_connect(self): + self.config["ident"] = ident = self.config["ident"] if self.config["ident"] != "" else self.config["nickname"] + self.sendLine("USER "+ident+" * * *") + self.sendLine("NICK "+self.config["nickname"]) + + def handle_disconnect(self): + self.pluginManager.event("disconnect", self.config["network"]) + + def handle_error(self): + traceback.print_exc() + def prnt(self, line): - print("["+self.config["host"]+"] "+line) + print("["+self.config["network"]+"] "+line) def sendLine(self, line): - try: - self.conn.send(line+"\r\n") - except socket.error: - self.prnt("Connection lost to server.") - exit() + if line.endswith("\r\n"): + self.push(line) + else: + self.push(line+"\r\n") def doMessage(self, channel, message): self.sendLine("PRIVMSG "+channel+" :"+message) @@ -375,7 +346,7 @@ class IRC(threading.Thread): def doQuit(self, message=""): self.sendLine("QUIT :" + message) self.pluginManager.event("quit", User(self.config["nickname"]), message) - self.running = False + self.close_when_done() def doNotice(self, user, message): self.sendLine("NOTICE "+user+" :"+message) diff --git a/plugins/auth.py b/plugins/auth.py index 8bb45a654b81f6de5049f87d44db9f3600f5849e..1f16f237c04c0e45f8c1303fd9e308fc72c838cd 100644 --- a/plugins/auth.py +++ b/plugins/auth.py @@ -4,23 +4,18 @@ import os, ConfigParser class Auth(object): def __init__(self, server): self.server = server - self.commands = [ "addadmin", "addmod", "deladmin", "delmod", "admins", "mods", "owners", "passwd", "identify" ] + self.commands = [ "addowner", "delowner", "addadmin", "addmod", "deladmin", "delmod", "admins", "mods", "owners", "passwd", "identify" ] self.owners = {} - self.authed_owner_hosts = [] self.admins = {} - self.authed_admin_hosts = [] self.mods = {} - self.authed_mod_hosts = [] self.server.handle("command", self.handle_command, self.commands) self.server.handle("part", self.handle_part) self.server.handle("quit", self.handle_quit) self.server.handle("nick", self.handle_nick) - self.authdir = self.server.config["confdir"] + "network-auth-users/" - self.authfile = self.authdir + self.server.config["network"] + "-auth.cfg" + self.authfile = self.server.config["confdir"] + "auth.cfg" self._loadusers() def _checkAuth(self, user): - user = user[0] stillOn = False for ch in self.server.userlist.keys(): if user in self.server.userlist[ch]: @@ -42,7 +37,6 @@ class Auth(object): def handle_nick(self, oldnick, newnick): if self.isOwner(oldnick): - print self.owners self.owners[newnick.lower()] = self.owners[oldnick.lower()] del self.owners[oldnick.lower()] elif self.isAdmin(oldnick): @@ -66,7 +60,7 @@ class Auth(object): if len(args) < 1: self.server.doMessage(channel, user+": Not enough arguments.") return - + if len(args) >= 2: self.owners[user.lower()][0] = args[1] self.server.doMessage(channel, user+": Password successfully changed.") @@ -144,68 +138,75 @@ class Auth(object): self.server.doMessage(channel, user+": Not enough arguments.") return - if cmd == "addadmin": - if args[0] in self.admins.keys(): return - self.admins[args[0]] = ['', False] + if cmd == "addowner": + if args[0].lower() in self.owners.keys(): return + self.owners[args[0].lower()] = ['', True] + elif cmd == "addadmin": + if args[0].lower() in self.admins.keys(): return + self.admins[args[0].lower()] = ['', True] elif cmd == "addmod": - if args[0] in self.mods.keys(): return - self.mods[args[0]] = ['', False] + if args[0].lower() in self.mods.keys(): return + self.mods[args[0].lower()] = ['', True] + elif cmd == "delowner": + if args[0].lower() in self.owners.keys(): + del self.admins[args[0].lower()] elif cmd == "deladmin": - if args[0] in self.admins.keys(): - del self.admins[args[0]] + if args[0].lower() in self.admins.keys(): + del self.admins[args[0].lower()] elif cmd == "delmod": - if args[0] in self.mods.keys(): - del self.mods[args[0]] + if args[0].lower() in self.mods.keys(): + del self.mods[args[0].lower()] #save users - def __del__(self): - if not os.path.isdir(self.authdir): - os.mkdir(self.authdir) + def destroy(self): + self.configParser = ConfigParser.RawConfigParser() + + if os.path.isfile(self.authfile): + self.configParser.read(self.authfile) fh = open(self.authfile, "w") - if not self.configParser.has_section("owners"): - self.configParser.add_section("owners") - if not self.configParser.has_section("admins"): - self.configParser.add_section("admins") - if not self.configParser.has_section("mods"): - self.configParser.add_section("mods") + network = self.server.config["network"] + if not self.configParser.has_section(network): + self.configParser.add_section(network) - for user in self.owners.keys(): - self.configParser.set("owners",user,self.owners[user][0]) - for user in self.admins.keys(): - self.configParser.set("admins",user,self.admins[user][0]) - for user in self.mods.keys(): - self.configParser.set("mods",user,self.mods[user][0]) + self.configParser.set(self.server.config["network"],"owners",",".join( [k+":"+v[0] for k,v in self.owners.items()] )) + self.configParser.set(self.server.config["network"],"admins",",".join( [k+":"+v[0] for k,v in self.admins.items()] )) + self.configParser.set(self.server.config["network"],"mods",",".join( [k+":"+v[0] for k,v in self.mods.items()] )) self.configParser.write(fh) fh.close() - def _loadusers(self): + network = self.server.config["network"] + if os.path.isfile(self.authfile): self.configParser = ConfigParser.RawConfigParser() self.configParser.read(self.authfile) + + if self.configParser.has_section(network): + if self.configParser.has_option(network, "owners"): + olist = self.configParser.get(network, "owners").lower().split(",") + olist = [o for o in olist if o != ''] + for user in olist: + nick, pw = user.split(":") + self.owners[nick] = [pw, pw == ''] - for section in self.configParser.sections(): - if section == "owners": - for user,pswd in self.configParser.items(section): - self.owners[user.lower()] = [pswd, pswd == ''] - elif section == "admins": - for user,pswd in self.configParser.items(section): - self.admins[user.lower()] = [pswd, pswd == ''] - elif section == "mods": - for user,pswd in self.configParser.items(section): - self.mods[user.lower()] = [pswd, pswd == ''] + if self.configParser.has_option(network, "admins"): + alist = self.configParser.get(network, "admins").lower().split(",") + alist = [a for a in alist if a != ''] + for user in alist: + nick, pw = user.split(":") + self.admins[nick] = [pw, pw == ''] + + if self.configParser.has_option(network, "mods"): + mlist = self.configParser.get(network, "mods").lower().split(",") + mlist = [m for m in mlist if m != ''] + for user in mlist: + nick, pw = user.split(":") + self.mods[nick] = [pw, pw == ''] onick = self.server.config["owner_nick"].lower() if not onick in self.owners.keys(): - if getattr(self, "configParser", None) is None: - self.configParser = ConfigParser.RawConfigParser() - self.configParser.add_section("owners") - self.configParser.add_section("admins") - self.configParser.add_section("mods") - - self.configParser.set("owners", onick, '') self.owners[onick] = ['', True] def isOwner(self, user): diff --git a/plugins/channeltools.py b/plugins/channeltools.py index f19288ffe59491a332bbc42b3bef26a68546d226..92f3e6b1329ebc85f29c55dd4ad3657de70eafb7 100644 --- a/plugins/channeltools.py +++ b/plugins/channeltools.py @@ -7,7 +7,6 @@ class ChannelTools(object): self.server.handle("command", self.handle_command, self.commands) def handle_command(self, channel, user, cmd, args): - user = user[0] if self.server.getPlugin("auth").isAdmin(user): if len(args) < 1: self.server.doMessage(channel, user+": Not enough arguments.") diff --git a/plugins/ddg.py b/plugins/ddg.py index 85ad9b6fa8ee1585d4c947ccfe88d1e9721d401d..86ad9c49380036773bf1f041c5a5838bb5344b32 100644 --- a/plugins/ddg.py +++ b/plugins/ddg.py @@ -13,7 +13,6 @@ class ddg(object): self.server.handle("command", self.handle_command, self.commands) def handle_command(self, channel, user, cmd, args): - user = user[0] if cmd == "ddg": if len(args) < 1: self.server.doMessage(channel, user+": DuckDuckGo.com Zero-Click infoboxes search. Syntax: ddg <query>.") diff --git a/plugins/die.py b/plugins/die.py index 2d6c0a182bd39789495ef1c066ea276b4ae4fbf5..e5cffc1b07749e89f41857d98ed6af2391d102a7 100644 --- a/plugins/die.py +++ b/plugins/die.py @@ -8,7 +8,6 @@ class Die(object): self.server.handle("command", self.handle_command, self.commands) def handle_command(self, channel, user, cmd, args): - user = user[0] if self.server.getPlugin("auth").isOwner(user): self.server.doMessage(channel, user + " wants me to leave, but I'll be back!") self.server.doQuit() diff --git a/plugins/dns.py b/plugins/dns.py index 06e91d76da1ccf73e07e28e042c518331254cbd3..5967502b86cf86f323f478a1846903cfbabe3235 100644 --- a/plugins/dns.py +++ b/plugins/dns.py @@ -12,7 +12,6 @@ class dns(object): self.server.handle("command", self.handle_command, self.commands) def handle_command(self, channel, user, cmd, args): - user = user[0] if cmd == "dns": if len(args) < 1: self.server.doMessage(channel, user+": Return a fully qualified domain name for a list of space-separated IPs or hostnames.") diff --git a/plugins/dynacode.py b/plugins/dynacode.py index c2fb71ccf979ad1df5c3a1e656446806dbd15c1d..ecc80badc0966b3b73b4d3b88c2fc0ee1fb7b119 100644 --- a/plugins/dynacode.py +++ b/plugins/dynacode.py @@ -1,15 +1,12 @@ import sys -@plugin class DynaCode(object): def __init__(self, server): self.server = server self.commands = [ "py" ] - self.server.handle("command", getattr(self, "handle_command"), self.commands) - self.env = { } + self.server.handle("command", self.handle_command, self.commands) def handle_command(self, channel, user, cmd, args): - user = user[0] if self.server.getPlugin("auth").isOwner(user) and cmd == "py": if len(args) < 1: self.server.doMessage(channel, user+": Not enough arguments.") diff --git a/plugins/games.py b/plugins/games.py index a9bf939539941fd2654c42bfcc2d2f7af62e8e40..0955a4d37f64613270830b35458ea2270a7c61e6 100644 --- a/plugins/games.py +++ b/plugins/games.py @@ -2,7 +2,8 @@ import random UNODECK = ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'g0', 'g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7', 'g8', 'g9', 'g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7', 'g8', 'g9', 'y0', 'y1', 'y2', 'y3', 'y4', 'y5', 'y6', 'y7', 'y8', 'y9', 'y1', 'y2', 'y3', 'y4', 'y5', 'y6', 'y7', 'y8', 'y9', 'r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'rS', 'gS', 'bS', 'yS', 'rD2', 'gD2', 'bD2', 'yD2', 'rR', 'gR', 'bR', 'yR', 'wW', 'wW', 'wW', 'wW', 'wWD4', 'wWD4', 'wWD4', 'wWD4', 'rS', 'gS', 'bS', 'yS', 'rD2', 'gD2', 'bD2', 'yD2', 'rR', 'gR', 'bR', 'yR'] -@plugin +#commented out the decorator, as the plugin is not yet made +#@plugin class Uno(object): def __init__(self, server): self.server = server diff --git a/plugins/info.py b/plugins/info.py index 2dafe567b2c68b0e03bef8f85d7c04341dc8f1ec..b32631c6478cb7d14de4575c168b3d907492e4dc 100644 --- a/plugins/info.py +++ b/plugins/info.py @@ -17,7 +17,7 @@ class Info(object): k,v = line.split("\t") self.infodb[k] = v - def __del__(self): + def destroy(self): fh = open(self.dbfile+".tmp", "w") for k,v in self.infodb.items(): fh.write("%s\t%s\n" % (k,v)) diff --git a/plugins/ping.py b/plugins/ping.py index 1f5bd36a37774e4226075a4b6bcebbf3e2dbd2e0..ce16deba99788c52bfb1db341e0662af135c112e 100644 --- a/plugins/ping.py +++ b/plugins/ping.py @@ -7,7 +7,6 @@ class Ping(object): self.server.handle("command", self.handle_command, self.commands) def handle_command(self, channel, user, cmd, args): - user = user[0] if cmd == "ping": if len(args) > 0: self.server.doMessage(channel, user+": Pong "+" ".join(args)) diff --git a/plugins/printer.py b/plugins/printer.py index 2647c660e410a6410ac695ba5636c9228b860002..6708bb83c2802f6b374bd3dba42c79b580027389 100644 --- a/plugins/printer.py +++ b/plugins/printer.py @@ -5,11 +5,17 @@ class Printer(object): self.server = server self.prnt = server.prnt - #this is just so that we don't have to hard-code every event - for h in self.server.handlers: - func = getattr(self, "handle_"+h, None) - if func is not None: - self.server.handle(h, func) + self.server.handle("message", self.handle_message) + self.server.handle("kick", self.handle_kick) + self.server.handle("part", self.handle_part) + self.server.handle("join", self.handle_join) + self.server.handle("quit", self.handle_quit) + self.server.handle("mode", self.handle_mode) + self.server.handle("notice", self.handle_notice) + self.server.handle("connect", self.handle_connect) + self.server.handle("disconnect", self.handle_disconnect) + self.server.handle("action", self.handle_action) + self.server.handle("nick", self.handle_nick) def handle_connect(self, server): self.prnt("I have connected to %s" % server) @@ -24,7 +30,6 @@ class Printer(object): self.prnt("<%s> * %s %s" % (channel, user, action)) def handle_join(self, channel, user): - user = user[0] self.prnt("%s has joined %s" % (user, channel)) def handle_part(self, channel, user, message): @@ -39,5 +44,8 @@ class Printer(object): def handle_kick(self, channel, user, userkicked, message): self.prnt("%s has kicked %s from %s (%s)" % (user, userkicked, channel, message)) + def handle_notice(self, user, dest, message): + self.prnt("(%s) -%s- %s" % (dest, user, message)) + def handle_mode(self, channel, user, mode, otheruser): self.prnt("%s set mode %s on %s" % (user, mode, otheruser if otheruser != "" else channel)) diff --git a/plugins/rpn.py b/plugins/rpn.py index 79dab01d5464886f0899346c1e395fc825e3887a..16147fc7a3f441f972d4c90e03a389fefb171852 100644 --- a/plugins/rpn.py +++ b/plugins/rpn.py @@ -10,7 +10,6 @@ class rpn(object): self.server.handle("command", self.handle_command, self.commands) def handle_command(self, channel, user, cmd, args): - user = user[0] if cmd == "rpn": if len(args) < 1: self.server.doMessage(channel, user+": reverse-polish-notation calculator. syntax: rpn 2 4 1 + / gives 2/5.") diff --git a/plugins/smack.py b/plugins/smack.py index 27a631112badea0ebe5e1697241b610a4e99392a..f4b33b73d1a9bc2e08c10a8766dd7e9e290c5bb8 100644 --- a/plugins/smack.py +++ b/plugins/smack.py @@ -15,7 +15,6 @@ class Smack(object): ] def handle_command(self, channel, user, cmd, args): - user = user[0] if cmd == "smack" and len(args) > 0: self.server.doAction(channel, "smacks "+args[0]+" with a "+self.objects[random.Random().randint(0, len(self.objects)-1)]+"!") diff --git a/plugins/wikipedia.py b/plugins/wikipedia.py index c1db90759066581b473e6b613562861577026ff7..2186fe882b33085f27148c3ed57a8efe7a6ffc8c 100644 --- a/plugins/wikipedia.py +++ b/plugins/wikipedia.py @@ -12,7 +12,7 @@ class Wikipedia(object): user = user[0] if cmd == "wiki": if len(args) < 1: - self.server.doMessage(channel, user+": What should I search for on Wikipedia?") + self.server.doMessage(channel, user+": Not enough arguments.") return url = "http://en.wikipedia.org/w/api.php?action=opensearch&limit=3&namespace=0&format=xml&search=" @@ -25,8 +25,12 @@ class Wikipedia(object): self.server.doMessage(channel, user+": I/O Error retrieving the results: "+ioe) return - print data[0] - xmldoc = minidom.parseString(data[0]) + try: + xmldoc = minidom.parseString(data[0]) + except xml.parsers.expat.ExpatError: + self.server.doMessage(channel, user+": Error parsing the xml search results.") + return + searchResults = xmldoc.childNodes[0].childNodes[1].childNodes for result in searchResults: resultStr = ""