aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jesopo2018-09-24 13:10:39 +0100
committerGravatar jesopo2018-09-24 13:10:39 +0100
commitb7f7c9342b7b23b5c04bc9974403e6e96ce8bec2 (patch)
tree73462913493ddaa5f058d5bb675c020eab7f4d85
parentMerge pull request #23 from dngfx/master (diff)
signature
Better communicate issues with load/unload/reload of modules
-rw-r--r--ModuleManager.py61
-rw-r--r--modules/modules.py46
2 files changed, 65 insertions, 42 deletions
diff --git a/ModuleManager.py b/ModuleManager.py
index 1ecb1f7a..a9d9f7d4 100644
--- a/ModuleManager.py
+++ b/ModuleManager.py
@@ -2,6 +2,23 @@ import glob, imp, inspect, os, sys, uuid
BITBOT_HOOKS_MAGIC = "__bitbot_hooks"
+class ModuleException(Exception):
+ pass
+class ModuleWarning(Exception):
+ pass
+
+class ModuleNotFoundException(ModuleException):
+ pass
+class ModuleNameCollisionException(ModuleException):
+ pass
+class ModuleLoadException(ModuleException):
+ pass
+class ModuleUnloadException(ModuleException):
+ pass
+
+class ModuleNotLoadedWarning(ModuleWarning):
+ pass
+
class BaseModule(object):
def __init__(self, bot, events, exports):
pass
@@ -33,28 +50,32 @@ class ModuleManager(object):
# this is a hashflag
if line == "#--ignore":
# nope, ignore this module.
- return None
+ raise ModuleNotLoadedWarning("module ignored")
elif line_split[0] == "#--require-config" and len(
line_split) > 1:
if not line_split[1].lower() in self.bot.config or not self.bot.config[
line_split[1].lower()]:
# nope, required config option not present.
- return None
+ raise ModuleNotLoadedWarning(
+ "required config not present")
elif line_split[0] == "#--require-module" and len(
line_split) > 1:
if not "bitbot_%s" % line_split[1].lower() in sys.modules:
if not line_split[1].lower() in self.waiting_requirement:
self.waiting_requirement[line_split[1].lower()] = set([])
self.waiting_requirement[line_split[1].lower()].add(path)
- return None
+ raise ModuleNotLoadedWarning(
+ "waiting for requirement")
else:
break
module = imp.load_source(name, path)
if not hasattr(module, "Module"):
- raise ImportError("module '%s' doesn't have a Module class.")
+ raise ModuleLoadException("module '%s' doesn't have a "
+ "'Module' class.")
if not inspect.isclass(module.Module):
- raise ImportError("module '%s' has a Module attribute but it is not a class.")
+ raise ModuleLoadException("module '%s' has a 'Module' attribute "
+ "but it is not a class.")
context = str(uuid.uuid4())
context_events = self.events.new_context(context)
@@ -83,26 +104,32 @@ class ModuleManager(object):
def load_module(self, name):
try:
module = self._load_module(name)
- except ImportError as e:
- self.bot.log.error("failed to load module \"%s\": %s",
- [name, e.msg])
- return
- if module:
- self.modules[module._import_name] = module
- if name in self.waiting_requirement:
- for requirement_name in self.waiting_requirement:
- self.load_module(requirement_name)
- self.bot.log.info("Module '%s' loaded", [name])
- else:
+ except ModuleWarning as warning:
self.bot.log.error("Module '%s' not loaded", [name])
+ raise
+ except Exception as e:
+ self.bot.log.error("Failed to load module \"%s\": %s",
+ [name, e.msg])
+ raise
+
+ self.modules[module._import_name] = module
+ if name in self.waiting_requirement:
+ for requirement_name in self.waiting_requirement:
+ self.load_module(requirement_name)
+ self.bot.log.info("Module '%s' loaded", [name])
def load_modules(self, whitelist=[], blacklist=[]):
for path in self.list_modules():
name = self._module_name(path)
if name in whitelist or (not whitelist and not name in blacklist):
- self.load_module(name)
+ try:
+ self.load_module(name)
+ except ModuleWarning:
+ pass
def unload_module(self, name):
+ if not name in self.modules:
+ raise ModuleNotFoundException()
module = self.modules[name]
del self.modules[name]
diff --git a/modules/modules.py b/modules/modules.py
index 109baeff..154a1765 100644
--- a/modules/modules.py
+++ b/modules/modules.py
@@ -1,10 +1,8 @@
-
+import ModuleManager
class Module(object):
def __init__(self, bot, events, exports):
self.bot = bot
- self.module_name = False
- self.silent = False
events.on("received.command.loadmodule").hook(self.load,
min_args=1, permission="load-module", help="Load a module",
@@ -43,37 +41,35 @@ class Module(object):
self.bot.modules.unload_module(name)
event["stdout"].write("Unloaded '%s'" % name)
- def reload(self, event):
- name = self.module_name if self.module_name != False else event[
- "args_split"][0].lower()
- if not name in self.bot.modules.modules:
- if self.silent == False:
- event["stderr"].write("Module '%s' isn't loaded" % name)
- return
+ def _reload(self, name):
self.bot.modules.unload_module(name)
self.bot.modules.load_module(name)
- if self.silent == False:
- event["stdout"].write("Reloaded '%s'" % name)
+ def reload(self, event):
+ name = event["args_split"][0].lower()
+ try:
+ self._reload(name)
+ except ModuleManager.ModuleNotFoundException:
+ event["stderr"].write("Module '%s' isn't loaded" % name)
+ return
+ event["stdout"].write("Reloaded '%s'" % name)
def reload_all(self, event):
- modules_reloaded = []
- self.silent = True
-
- for name, value in self.bot.modules.modules.items():
- if name in modules_reloaded:
- pass
-
- self.module_name = name
- self.reload(event)
- modules_reloaded.append(name)
+ reloaded = []
+ failed = []
+ for name in self.bot.modules.modules.keys():
+ try:
+ self._reload(name)
+ except ModuleManager.ModuleNotFoundException:
+ failed.append
+ if not self._reload(event):
+ failed.append(name)
+ else:
+ reloaded.append(name)
event["stdout"].write("Reloaded modules: %s" % \
" ".join(modules_reloaded))
- self.silent = False
- self.module_name = False
-
def enable(self, event):
name = event["args_split"][0].lower()
blacklist = self.bot.get_setting("module-blacklist", [])