Centralize configuration: there is no more XML files for module, juste one bot configuration file, also containing module configuration; fixes #56

This commit is contained in:
nemunaire 2014-08-28 12:26:02 +02:00
parent fdd4847f71
commit 97143a0182
6 changed files with 41 additions and 68 deletions

1
bot.py
View File

@ -52,6 +52,7 @@ class Bot:
# Keep global context: servers and modules # Keep global context: servers and modules
self.servers = dict() self.servers = dict()
self.modules = dict() self.modules = dict()
self.modules_configuration = dict()
# Context paths # Context paths
self.modules_path = mp self.modules_path = mp

View File

@ -10,19 +10,16 @@
</server> </server>
--> -->
<load path="cmd_server" /> <!--
<module name="ddg">
<wfaapi key="YOUR-APIKEY" />
</module>
-->
<load path="alias" /> <module name="cmd_server" />
<load path="birthday" />
<load path="ycc" /> <module name="alias" />
<load path="velib" /> <module name="ycc" />
<load path="watchWebsite" /> <module name="events" />
<load path="events" />
<load path="sleepytime" />
<load path="spell" />
<load path="syno" />
<load path="man" />
<load path="reddit" />
<load path="sap" />
</nemubotconfig> </nemubotconfig>

View File

@ -42,28 +42,22 @@ class ModuleFinder(Finder):
if path is None: if path is None:
for mpath in self.context.modules_path: for mpath in self.context.modules_path:
#print ("looking for", fullname, "in", mpath) #print ("looking for", fullname, "in", mpath)
if os.path.isfile(mpath + fullname + ".xml"): if (os.path.isfile(mpath + fullname + ".py") or
return ModuleLoader(self.context, self.prompt, fullname,
mpath, mpath + fullname + ".xml")
elif (os.path.isfile(mpath + fullname + ".py") or
os.path.isfile(mpath + fullname + "/__init__.py")): os.path.isfile(mpath + fullname + "/__init__.py")):
return ModuleLoader(self.context, self.prompt, return ModuleLoader(self.context, self.prompt,
fullname, mpath, None) fullname, mpath)
#print ("not found") #print ("not found")
return None return None
class ModuleLoader(SourceLoader): class ModuleLoader(SourceLoader):
def __init__(self, context, prompt, fullname, path, config_path): def __init__(self, context, prompt, fullname, path):
self.context = context self.context = context
self.prompt = prompt self.prompt = prompt
self.name = fullname self.name = fullname
self.config_path = config_path
if config_path is not None: if self.name in self.context.modules_configuration:
self.config = xmlparser.parse_file(config_path) self.config = self.context.modules_configuration[self.name]
if self.config.hasAttribute("name"):
self.name = self.config["name"]
else: else:
self.config = None self.config = None
@ -251,25 +245,8 @@ def register_hooks(module, context, prompt):
"""Register all available hooks""" """Register all available hooks"""
# Register decorated functions # Register decorated functions
for s, h in hooks.last_registered: for s, h in hooks.last_registered:
if s == "prompt_cmd":
prompt.add_cap_hook(h.name, h.call)
else:
context.hooks.add_hook(s, h, module) context.hooks.add_hook(s, h, module)
hooks.last_registered = [] hooks.last_registered = []
if module.CONF is not None:
# Register command hooks
if module.CONF.hasNode("command"):
for cmd in module.CONF.getNodes("command"):
if cmd.hasAttribute("name") and cmd.hasAttribute("call"):
add_cap_hook(prompt, module, cmd)
# Register message hooks
if module.CONF.hasNode("message"):
for msg in module.CONF.getNodes("message"):
context.hooks.register_hook(module, msg)
# Register legacy hooks
if hasattr(module, "parseanswer"):
context.hooks.add_hook("cmd_default", hooks.Hook(module.parseanswer), module)
if hasattr(module, "parseask"):
context.hooks.add_hook("ask_default", hooks.Hook(module.parseask), module)
if hasattr(module, "parselisten"):
context.hooks.add_hook("msg_default", hooks.Hook(module.parselisten), module)

View File

@ -20,6 +20,7 @@ import traceback
import sys import sys
from networkbot import NetworkBot from networkbot import NetworkBot
from hooks import hook
nemubotversion = 3.4 nemubotversion = 3.4
NODATA = True NODATA = True
@ -33,6 +34,7 @@ def getserver(toks, context, prompt):
else: else:
return (None, toks) return (None, toks)
@hook("prompt_cmd", "close")
def close(data, toks, context, prompt): def close(data, toks, context, prompt):
"""Disconnect and forget (remove from the servers list) the server""" """Disconnect and forget (remove from the servers list) the server"""
if len(toks) > 1: if len(toks) > 1:
@ -48,6 +50,7 @@ def close(data, toks, context, prompt):
prompt.selectedServer = None prompt.selectedServer = None
return return
@hook("prompt_cmd", "connect")
def connect(data, toks, context, prompt): def connect(data, toks, context, prompt):
"""Make the connexion to a server""" """Make the connexion to a server"""
if len(toks) > 1: if len(toks) > 1:
@ -62,6 +65,7 @@ def connect(data, toks, context, prompt):
else: else:
print (" Please SELECT a server or give its name in argument.") print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "disconnect")
def disconnect(data, toks, context, prompt): def disconnect(data, toks, context, prompt):
"""Close the connection to a server""" """Close the connection to a server"""
if len(toks) > 1: if len(toks) > 1:
@ -78,6 +82,7 @@ def disconnect(data, toks, context, prompt):
else: else:
print (" Please SELECT a server or give its name in argument.") print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "discover")
def discover(data, toks, context, prompt): def discover(data, toks, context, prompt):
"""Discover a new bot on a server""" """Discover a new bot on a server"""
(srv, toks) = getserver(toks, context, prompt) (srv, toks) = getserver(toks, context, prompt)
@ -91,6 +96,7 @@ def discover(data, toks, context, prompt):
else: else:
print (" Please SELECT a server or give its name in first argument.") print (" Please SELECT a server or give its name in first argument.")
@hook("prompt_cmd", "hotswap")
def hotswap(data, toks, context, prompt): def hotswap(data, toks, context, prompt):
"""Reload a server class""" """Reload a server class"""
if len(toks) > 1: if len(toks) > 1:
@ -107,6 +113,7 @@ def hotswap(data, toks, context, prompt):
else: else:
print (" Please SELECT a server or give its name in argument.") print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "join")
def join(data, toks, context, prompt): def join(data, toks, context, prompt):
"""Join or leave a channel""" """Join or leave a channel"""
rd = 1 rd = 1
@ -136,6 +143,7 @@ def join(data, toks, context, prompt):
srv.leave(toks[rd]) srv.leave(toks[rd])
return return
@hook("prompt_cmd", "save")
def save_mod(data, toks, context, prompt): def save_mod(data, toks, context, prompt):
"""Force save module data""" """Force save module data"""
if len(toks) < 2: if len(toks) < 2:
@ -150,6 +158,7 @@ def save_mod(data, toks, context, prompt):
print ("save: no module named `%s´" % mod) print ("save: no module named `%s´" % mod)
return return
@hook("prompt_cmd", "send")
def send(data, toks, context, prompt): def send(data, toks, context, prompt):
"""Send a message on a channel""" """Send a message on a channel"""
rd = 1 rd = 1
@ -190,6 +199,7 @@ def send(data, toks, context, prompt):
srv.send_msg_final(chan, toks[rd]) srv.send_msg_final(chan, toks[rd])
return "done" return "done"
@hook("prompt_cmd", "zap")
def zap(data, toks, context, prompt): def zap(data, toks, context, prompt):
"""Hard change connexion state""" """Hard change connexion state"""
if len(toks) > 1: if len(toks) > 1:
@ -203,6 +213,7 @@ def zap(data, toks, context, prompt):
else: else:
print (" Please SELECT a server or give its name in argument.") print (" Please SELECT a server or give its name in argument.")
@hook("prompt_cmd", "top")
def top(data, toks, context, prompt): def top(data, toks, context, prompt):
"""Display consumers load information""" """Display consumers load information"""
print("Queue size: %d, %d thread(s) running (counter: %d)" % (context.cnsr_queue.qsize(), len(context.cnsr_thrd), context.cnsr_thrd_size)) print("Queue size: %d, %d thread(s) running (counter: %d)" % (context.cnsr_queue.qsize(), len(context.cnsr_thrd), context.cnsr_thrd_size))
@ -216,6 +227,7 @@ def top(data, toks, context, prompt):
print("################ Stack trace for thread %u ################" % th.ident) print("################ Stack trace for thread %u ################" % th.ident)
traceback.print_stack(sys._current_frames()[th.ident]) traceback.print_stack(sys._current_frames()[th.ident])
@hook("prompt_cmd", "netstat")
def netstat(data, toks, context, prompt): def netstat(data, toks, context, prompt):
"""Display sockets in use and many other things""" """Display sockets in use and many other things"""
if len(context.network) > 0: if len(context.network) > 0:

View File

@ -1,16 +0,0 @@
<?xml version="1.0" ?>
<nemubotmodule name="cmd_server">
<command name="close" call="close" />
<command name="connect" call="connect" />
<command name="discover" call="discover" />
<command name="disconnect" call="disconnect" />
<command name="hotswap" call="hotswap" />
<command name="join" call="join" />
<command name="leave" call="join" />
<command name="part" call="join" />
<command name="save" call="save_mod" />
<command name="send" call="send" />
<command name="zap" call="zap" />
<command name="top" call="top" />
<command name="netstat" call="netstat" />
</nemubotmodule>

View File

@ -77,13 +77,15 @@ def load_file(filename, context):
print("Server `%s:%s' already added, skiped." % print("Server `%s:%s' already added, skiped." %
(server["server"], server["port"])) (server["server"], server["port"]))
# Load files asked by the configuration file # Load module and their configuration
for load in config.getNodes("load"): for mod in config.getNodes("module"):
load_file(load["path"], context) context.modules_configuration[mod["name"]] = mod
if not mod.hasAttribute("autoload") or (mod["autoload"].lower() != "false" and mod["autoload"].lower() != "off"):
__import__(mod["name"])
# This is a nemubot module configuration file, load the module # Load files asked by the configuration file
elif config.getName() == "nemubotmodule": for load in config.getNodes("include"):
__import__(config["name"]) load_file(load["path"], context)
# Other formats # Other formats
else: else: