diff --git a/prompt.py b/prompt.py deleted file mode 100644 index a561ae0..0000000 --- a/prompt.py +++ /dev/null @@ -1,477 +0,0 @@ -import imp -import os -import shlex -import sys -import traceback - -server = __import__("server") -imp.reload(server) - -xmlparser = __import__("module_states_file") -imp.reload(xmlparser) -server.xmlparser = xmlparser -server.message.xmlparser = xmlparser -xmlparser.module_state.xmlparser = xmlparser - -selectedServer = None -modules_path = "./modules/" -datas_path = "./datas/" - -MODS = list() - -def parsecmd(msg): - """Parse the command line""" - try: - cmds = shlex.split(msg) - if len(cmds) > 0: - cmds[0] = cmds[0].lower() - return cmds - except: - exc_type, exc_value, exc_traceback = sys.exc_info() - sys.stdout.write (traceback.format_exception_only(exc_type, exc_value)[0]) - return None - -def run(cmds, servers): - """Launch the command""" - if cmds[0] in CAPS: - return CAPS[cmds[0]](cmds, servers) - else: - print ("Unknown command: `%s'" % cmds[0]) - return "" - -def getPS1(): - """Get the PS1 associated to the selected server""" - if selectedServer is None: - return "nemubot" - else: - return selectedServer.id - -def launch(servers): - """Launch the prompt""" - global MODS - if MODS is None: - MODS = list() - - #Load messages module - server.message.load(datas_path + "general.xml") - - #Update launched servers - for srv in servers: - servers[srv].update_mods(MODS) - - ret = "" - cmds = list() - while ret != "quit" and ret != "reset" and ret != "refresh": - sys.stdout.write("\033[0;33m%s§\033[0m " % getPS1()) - sys.stdout.flush() - #TODO: Don't split here, a ; in a quoted string will be splited :s - try: - d = sys.stdin.readline().strip() - except KeyboardInterrupt: - print("") - d = "quit" - for k in d.split(";"): - try: - cmds = parsecmd(k) - except: - exc_type, exc_value, exc_traceback = sys.exc_info() - sys.stdout.write (traceback.format_exception_only(exc_type, exc_value)[0]) - if cmds is not None and len(cmds) > 0: - try: - ret = run(cmds, servers) - except: - exc_type, exc_value, exc_traceback = sys.exc_info() - sys.stdout.write (traceback.format_exception_only(exc_type, exc_value)[0]) - #Don't shutdown at refresh - if ret == "refresh": - return True - #Save and shutdown modules - for m in MODS: - m.save() - try: - m.close() - except AttributeError: - pass - MODS = None - return ret == "reset" - - -########################## -# # -# Module functions # -# # -########################## - -def mod_save(mod, datas_path): - mod.DATAS.save(datas_path + "/" + mod.name + ".xml") - mod.print ("Saving!") - -def mod_has_access(mod, config, msg): - if config is not None and config.hasNode("channel"): - for chan in config.getNodes("channel"): - if (chan["server"] is None or chan["server"] == msg.srv.id) and (chan["channel"] is None or chan["channel"] == msg.channel): - return True - return False - else: - return True - -########################## -# # -# Permorming functions # -# # -########################## - -def load_module_from_name(name, servers, config=None): - try: - #Import the module code - loaded = False - for md in MODS: - if md.name == name: - mod = imp.reload(md) - loaded = True - try: - mod.reload() - except AttributeError: - pass - break - if not loaded: - mod = __import__(name) - imp.reload(mod) - try: - if mod.nemubotversion < 3.0: - print (" Module `%s' is not compatible with this version." % name) - return - - #Set module common functions and datas - mod.name = name - mod.print = lambda msg: print("[%s] %s"%(mod.name, msg)) - mod.DATAS = xmlparser.parse_file(datas_path + "/" + name + ".xml") - mod.CONF = config - mod.SRVS = servers - mod.has_access = lambda msg: mod_has_access(mod, config, msg) - mod.save = lambda: mod_save(mod, datas_path) - - #Load dependancies - if mod.CONF is not None and mod.CONF.hasNode("dependson"): - mod.MODS = dict() - for depend in mod.CONF.getNodes("dependson"): - for md in MODS: - if md.name == depend["name"]: - mod.MODS[md.name] = md - break - if depend["name"] not in mod.MODS: - print ("\033[1;31mERROR:\033[0m in module `%s', module `%s' require by this module but is not loaded." % (mod.name,depend["name"])) - return - - try: - test = mod.parseask - except AttributeError: - print ("\033[1;35mWarning:\033[0m in module `%s', no function parseask defined." % mod.name) - mod.parseask = lambda x: False - - try: - test = mod.parseanswer - except AttributeError: - print ("\033[1;35mWarning:\033[0m in module `%s', no function parseanswer defined." % mod.name) - mod.parseanswer = lambda x: False - - try: - test = mod.parselisten - except AttributeError: - print ("\033[1;35mWarning:\033[0m in module `%s', no function parselisten defined." % mod.name) - mod.parselisten = lambda x: False - - try: - mod.load() - print (" Module `%s' successfully loaded." % name) - except AttributeError: - print (" Module `%s' successfully added." % name) - #TODO: don't append already running modules - exitsts = False - for md in MODS: - if md.name == name: - exitsts = True - break - if not exitsts: - MODS.append(mod) - except AttributeError : - print (" Module `%s' is not a nemubot module." % name) - for srv in servers: - servers[srv].update_mods(MODS) - except IOError: - print (" Module `%s' not loaded: unable to find module implementation." % name) - except ImportError: - print ("\033[1;31mERROR:\033[0m Module attached to the file `%s' not loaded. Is this file existing?" % name) - exc_type, exc_value, exc_traceback = sys.exc_info() - traceback.print_exception(exc_type, exc_value, exc_traceback) - -def load_module(config, servers): - global MODS - if config.hasAttribute("name"): - load_module_from_name(config["name"], servers, config) - -def load_file(filename, servers): - """Realy load a file""" - global MODS - if os.path.isfile(filename): - config = xmlparser.parse_file(filename) - if config.getName() == "nemubotconfig" or config.getName() == "config": - #Preset each server in this file - for serveur in config.getNodes("server"): - srv = server.Server(serveur, config["nick"], config["owner"], config["realname"]) - if srv.id not in servers: - servers[srv.id] = srv - print (" Server `%s' successfully added." % srv.id) - else: - print (" Server `%s' already added, skiped." % srv.id) - if srv.autoconnect: - srv.launch(MODS) - #Load files asked by the configuration file - for load in config.getNodes("load"): - load_file(load["path"], servers) - elif config.getName() == "nemubotmodule": - load_module(config, servers) - else: - print (" Can't load `%s'; this is not a valid nemubot configuration file." % filename) - elif os.path.isfile(filename + ".xml"): - load_file(filename + ".xml", servers) - elif os.path.isfile("./modules/" + filename + ".xml"): - load_file("./modules/" + filename + ".xml", servers) - else: - load_module_from_name(filename, servers) - - -def load(cmds, servers): - """Load an XML configuration file""" - if len(cmds) > 1: - for f in cmds[1:]: - load_file(f, servers) - else: - print ("Not enough arguments. `load' takes an filename.") - return - -def unload(cmds, servers): - """Unload a module""" - global MODS - if len(cmds) == 2 and cmds[1] == "all": - for mod in MODS: - try: - mod.unload() - except AttributeError: - continue - while len(MODS) > 0: - MODS.pop() - elif len(cmds) > 1: - print("Ok") - -def close(cmds, servers): - """Disconnect and forget (remove from the servers list) the server""" - global selectedServer - if len(cmds) > 1: - for s in cmds[1:]: - if s in servers: - servers[s].disconnect() - del servers[s] - else: - print ("close: server `%s' not found." % s) - elif selectedServer is not None: - selectedServer.disconnect() - del servers[selectedServer.id] - selectedServer = None - return - -def select(cmds, servers): - """Select the current server""" - global selectedServer - if len(cmds) == 2 and cmds[1] != "None" and cmds[1] != "nemubot" and cmds[1] != "none": - if cmds[1] in servers: - selectedServer = servers[cmds[1]] - else: - print ("select: server `%s' not found." % cmds[1]) - else: - selectedServer = None - return - -def liste(cmds, servers): - """Show some lists""" - if len(cmds) > 1: - for l in cmds[1:]: - l = l.lower() - if l == "server" or l == "servers": - for srv in servers.keys(): - print (" - %s ;" % srv) - elif l == "mod" or l == "mods" or l == "module" or l == "modules": - for mod in MODS: - print (" - %s ;" % mod.name) - elif l == "ban" or l == "banni": - for ban in server.message.BANLIST: - print (" - %s ;" % ban) - elif l == "credit" or l == "credits": - for name in server.message.CREDITS.keys: - print (" - %s: %s ;" % (name, server.message.CREDITS[name])) - elif l == "chan" or l == "channel" or l == "channels": - if selectedServer is not None: - for chn in selectedServer.channels: - print (" - %s: %s ;" % (chn, selectedServer.channels[chn].people.keys())) - else: - print (" Please SELECT a server before ask for channels list.") - else: - print (" Unknown list `%s'" % l) - else: - print (" Please give a list to show: servers, ...") - -def connect(cmds, servers): - """Make the connexion to a server""" - if len(cmds) > 1: - for s in cmds[1:]: - if s in servers: - servers[s].launch(MODS) - else: - print ("connect: server `%s' not found." % s) - - elif selectedServer is not None: - selectedServer.launch(MODS) - else: - print (" Please SELECT a server or give its name in argument.") - -def hotswap(cmds, servers): - """Reload a server class""" - global MODS, selectedServer - if len(cmds) > 1: - print ("hotswap: apply only on selected server") - elif selectedServer is not None: - del servers[selectedServer.id] - srv = server.Server(selectedServer.node, selectedServer.nick, selectedServer.owner, selectedServer.realname, selectedServer.s) - srv.update_mods(MODS) - servers[srv.id] = srv - selectedServer.kill() - selectedServer = srv - selectedServer.start() - else: - print (" Please SELECT a server or give its name in argument.") - -def join(cmds, servers): - """Join or leave a channel""" - rd = 1 - if len(cmds) <= rd: - print ("%s: not enough arguments." % cmds[0]) - return - - if cmds[rd] in servers: - srv = servers[cmds[rd]] - rd += 1 - elif selectedServer is not None: - srv = selectedServer - else: - print (" Please SELECT a server or give its name in argument.") - return - - if len(cmds) <= rd: - print ("%s: not enough arguments." % cmds[0]) - return - - if cmds[0] == "join": - if len(cmds) > rd + 1: - srv.join(cmds[rd], cmds[rd + 1]) - else: - srv.join(cmds[rd]) - elif cmds[0] == "leave" or cmds[0] == "part": - srv.leave(cmds[rd]) - -def send(cmds, servers): - """Built-on that send a message on a channel""" - rd = 1 - if len(cmds) <= rd: - print ("send: not enough arguments.") - return - - if cmds[rd] in servers: - srv = servers[cmds[rd]] - rd += 1 - elif selectedServer is not None: - srv = selectedServer - else: - print (" Please SELECT a server or give its name in argument.") - return - - if len(cmds) <= rd: - print ("send: not enough arguments.") - return - - #Check the server is connected - if not srv.connected: - print ("send: server `%s' not connected." % srv.id) - return - - if cmds[rd] in srv.channels: - chan = cmds[rd] - rd += 1 - else: - print ("send: channel `%s' not authorized in server `%s'." % (cmds[rd], srv.id)) - return - - if len(cmds) <= rd: - print ("send: not enough arguments.") - return - - srv.send_msg_final(chan, cmds[rd]) - return "done" - -def disconnect(cmds, servers): - """Close the connection to a server""" - if len(cmds) > 1: - for s in cmds[1:]: - if s in servers: - if not servers[s].disconnect(): - print ("disconnect: server `%s' already disconnected." % s) - else: - print ("disconnect: server `%s' not found." % s) - elif selectedServer is not None: - if not selectedServer.disconnect(): - print ("disconnect: server `%s' already disconnected." % selectedServer.id) - else: - print (" Please SELECT a server or give its name in argument.") - -def zap(cmds, servers): - """Hard change connexion state""" - if len(cmds) > 1: - for s in cmds[1:]: - if s in servers: - servers[s].connected = not servers[s].connected - else: - print ("disconnect: server `%s' not found." % s) - elif selectedServer is not None: - selectedServer.connected = not selectedServer.connected - else: - print (" Please SELECT a server or give its name in argument.") - -def end(cmds, servers): - """Quit the prompt for reload or exit""" - if cmds[0] == "refresh": - return "refresh" - elif cmds[0] == "reset": - return "reset" - else: - for srv in servers.keys(): - servers[srv].disconnect() - return "quit" - -#Register build-ins -CAPS = { - 'quit': end, #Disconnect all server and quit - 'exit': end, #Alias for quit - 'reset': end, #Reload the prompt - 'refresh': end, #Reload the prompt but save modules - 'load': load, #Load a servers or module configuration file - 'hotswap': hotswap, #Reload the server class without closing the socket - 'close': close, #Disconnect and remove a server from the list - 'unload': unload, #Unload a module and remove it from the list - 'select': select, #Select a server - 'list': liste, #Show lists - 'connect': connect, #Connect to a server - 'join': join, #Join a new channel - 'leave': join, #Leave a channel - 'send': send, #Send a message on a channel - 'disconnect': disconnect, #Disconnect from a server - 'zap': zap, #Reverse internal connection state without check -}