]> jfr.im git - erebus.git/blame - ctlmod.py
trivia - updated example json
[erebus.git] / ctlmod.py
CommitLineData
931c88a4 1# Erebus IRC bot - Author: John Runyon
2# module loading/unloading/tracking code
3
b9c6eb1d 4import sys, time
e4255e70 5import modlib
db50981b 6
7modules = {}
e4255e70 8dependents = {}
a8553c45 9#dependents[modname] = [list of modules which depend on modname]
db50981b 10
11def isloaded(modname): return modname in modules
d431e543 12def modhas(modname, attname): return getattr(modules[modname], attname, None) is not None
db50981b 13
b9c6eb1d 14def load(parent, modname, dependent=False):
15 #wrapper to call _load and print return
16 if dependent:
a8553c45 17 print "(Loading dependency %s..." % (modname),
b9c6eb1d 18 else:
a8553c45 19 print "%09.3f [MOD] [?] Loading %s..." % (time.time() % 100000, modname),
b9c6eb1d 20 modstatus = _load(parent, modname, dependent)
21 if not modstatus:
22 print str(modstatus)
23 elif modstatus == True:
24 if dependent:
a8553c45 25 print "OK)",
b9c6eb1d 26 else:
27 print "OK."
28 else:
29 print modstatus
30 return modstatus
31
32def _load(parent, modname, dependent=False):
db50981b 33 if not isloaded(modname):
96d0b31e 34 try:
83ed3882 35 mod = __import__('modules.'+modname, globals(), locals(), ['*'], -1)
36 # ^ fromlist doesn't actually do anything(?) but it means we don't have to worry about this returning the top-level "modules" object
8ba56606 37 reload(mod) #in case it's been previously loaded.
83ed3882 38 except Exception as e:
96d0b31e 39 return modlib.error(e)
20df9fbb 40
e4255e70 41
6b2c681d 42 if not hasattr(mod, 'modinfo'):
43 return modlib.error('no modinfo')
44
a76c4bd8 45 if parent.APIVERSION not in mod.modinfo['compatible']:
e4255e70 46 return modlib.error('API-incompatible')
47
db50981b 48 modules[modname] = mod
e4255e70 49 dependents[modname] = []
50
51 for dep in mod.modinfo['depends']:
52 if dep not in modules:
b9c6eb1d 53 depret = load(parent, dep, dependent=True)
a8553c45 54 if depret is not None and not depret:
55 return depret #TODO FIXME
e4255e70 56 dependents[dep].append(modname)
57
58
db50981b 59 ret = mod.modstart(parent)
e4255e70 60 if ret is not None and not ret:
db50981b 61 del modules[modname]
e4255e70 62 del dependents[modname]
63 for dep in mod.modinfo['depends']:
64 dependents[dep].remove(modname)
db50981b 65 return ret
e4255e70 66 else: #if not isloaded...else:
67 return modlib.error('already loaded')
db50981b 68
69def unload(parent, modname):
70 if isloaded(modname):
e4255e70 71 for dependent in dependents[modname]:
72 unload(parent, dependent)
a8553c45 73 for dep in modules[modname].modinfo['depends']:
e4255e70 74 dependents[dep].remove(modname)
5a81c82b 75 ret = modules[modname].modstop(parent)
76 del modules[modname]
77 return ret
db50981b 78 else:
e4255e70 79 return modlib.error('already unloaded')
db50981b 80
81def reloadmod(parent, modname):
82 if isloaded(modname):
d431e543 83 if modhas(modname, 'modrestart'): modules[modname].modrestart(parent)
84 else: modules[modname].modstop(parent)
db50981b 85
e3878612 86 try:
65b86c90 87 reload(modules[modname])
96d0b31e 88 except BaseException as e:
e3878612 89 return modlib.error(e)
db50981b 90
8ba56606 91 if modhas(modname, 'modrestarted'): ret = modules[modname].modrestarted(parent)
92 else: ret = modules[modname].modstart(parent)
db50981b 93
8ba56606 94 return ret
db50981b 95 else:
e3878612 96 return load(parent, modname)
97
db50981b 98
99def loadall(parent, modlist):
100 for m in modlist: load(parent, m)
101def unloadall(parent, modlist):
102 for m in modlist: unload(parent, m)
103def reloadall(parent, modlist):
104 for m in modlist: reloadmod(parent, m)