]> jfr.im git - erebus.git/blob - ctlmod.py
fix crashbug in !modreload / ctlmod.reloadmod
[erebus.git] / ctlmod.py
1 # Erebus IRC bot - Author: John Runyon
2 # module loading/unloading/tracking code
3
4 import sys
5 import modlib
6
7 modules = {}
8 dependents = {}
9
10 def isloaded(modname): return modname in modules
11 def modhas(modname, attname): return getattr(modules[modname], attname, None) is not None
12
13 def load(parent, modname):
14 if not isloaded(modname):
15 mod = __import__(modname)
16 reload(mod)
17
18 if not hasattr(mod, 'modinfo'):
19 return modlib.error('no modinfo')
20
21 if parent.APIVERSION not in mod.modinfo['compatible']:
22 return modlib.error('API-incompatible')
23
24 modules[modname] = mod
25 dependents[modname] = []
26
27 for dep in mod.modinfo['depends']:
28 if dep not in modules:
29 depret = load(parent, dep)
30 if not depret:
31 return
32 dependents[dep].append(modname)
33
34
35 ret = mod.modstart(parent)
36 if ret is not None and not ret:
37 del modules[modname]
38 del dependents[modname]
39 for dep in mod.modinfo['depends']:
40 dependents[dep].remove(modname)
41 return ret
42 else: #if not isloaded...else:
43 return modlib.error('already loaded')
44
45 def unload(parent, modname):
46 if isloaded(modname):
47 for dependent in dependents[modname]:
48 unload(parent, dependent)
49 for dep in dependents[modname]:
50 dependents[dep].remove(modname)
51 ret = modules[modname].modstop(parent)
52 del modules[modname]
53 return ret
54 else:
55 return modlib.error('already unloaded')
56
57 def reloadmod(parent, modname):
58 if isloaded(modname):
59 if modhas(modname, 'modrestart'): modules[modname].modrestart(parent)
60 else: modules[modname].modstop(parent)
61
62 try:
63 return reload(modules[modname])
64 except BaseException, e:
65 return modlib.error(e)
66
67 if modhas(modname, 'modrestarted'): modules[modname].modrestarted(parent)
68 else: modules[modname].modstart(parent)
69
70 else:
71 return load(parent, modname)
72
73
74 def loadall(parent, modlist):
75 for m in modlist: load(parent, m)
76 def unloadall(parent, modlist):
77 for m in modlist: unload(parent, m)
78 def reloadall(parent, modlist):
79 for m in modlist: reloadmod(parent, m)
80
81 sys.path.append('modules')