]>
Commit | Line | Data |
---|---|---|
931c88a4 | 1 | # Erebus IRC bot - Author: John Runyon |
2 | # module loading/unloading/tracking code | |
3 | ||
db50981b | 4 | import sys |
e4255e70 | 5 | import modlib |
db50981b | 6 | |
7 | modules = {} | |
e4255e70 | 8 | dependents = {} |
db50981b | 9 | |
10 | def isloaded(modname): return modname in modules | |
d431e543 | 11 | def modhas(modname, attname): return getattr(modules[modname], attname, None) is not None |
db50981b | 12 | |
13 | def load(parent, modname): | |
14 | if not isloaded(modname): | |
96d0b31e | 15 | try: |
16 | mod = __import__(modname) | |
17 | reload(mod) | |
18 | except BaseException as e: #we don't want even sys.exit() to crash us (in case of malicious module) so use BaseException | |
19 | return modlib.error(e) | |
20 | ||
e4255e70 | 21 | |
6b2c681d | 22 | if not hasattr(mod, 'modinfo'): |
23 | return modlib.error('no modinfo') | |
24 | ||
a76c4bd8 | 25 | if parent.APIVERSION not in mod.modinfo['compatible']: |
e4255e70 | 26 | return modlib.error('API-incompatible') |
27 | ||
db50981b | 28 | modules[modname] = mod |
e4255e70 | 29 | dependents[modname] = [] |
30 | ||
31 | for dep in mod.modinfo['depends']: | |
32 | if dep not in modules: | |
33 | depret = load(parent, dep) | |
34 | if not depret: | |
35 | return | |
36 | dependents[dep].append(modname) | |
37 | ||
38 | ||
db50981b | 39 | ret = mod.modstart(parent) |
e4255e70 | 40 | if ret is not None and not ret: |
db50981b | 41 | del modules[modname] |
e4255e70 | 42 | del dependents[modname] |
43 | for dep in mod.modinfo['depends']: | |
44 | dependents[dep].remove(modname) | |
db50981b | 45 | return ret |
e4255e70 | 46 | else: #if not isloaded...else: |
47 | return modlib.error('already loaded') | |
db50981b | 48 | |
49 | def unload(parent, modname): | |
50 | if isloaded(modname): | |
e4255e70 | 51 | for dependent in dependents[modname]: |
52 | unload(parent, dependent) | |
53 | for dep in dependents[modname]: | |
54 | dependents[dep].remove(modname) | |
5a81c82b | 55 | ret = modules[modname].modstop(parent) |
56 | del modules[modname] | |
57 | return ret | |
db50981b | 58 | else: |
e4255e70 | 59 | return modlib.error('already unloaded') |
db50981b | 60 | |
61 | def reloadmod(parent, modname): | |
62 | if isloaded(modname): | |
d431e543 | 63 | if modhas(modname, 'modrestart'): modules[modname].modrestart(parent) |
64 | else: modules[modname].modstop(parent) | |
db50981b | 65 | |
e3878612 | 66 | try: |
65b86c90 | 67 | reload(modules[modname]) |
96d0b31e | 68 | except BaseException as e: |
e3878612 | 69 | return modlib.error(e) |
db50981b | 70 | |
d431e543 | 71 | if modhas(modname, 'modrestarted'): modules[modname].modrestarted(parent) |
72 | else: modules[modname].modstart(parent) | |
db50981b | 73 | |
74 | else: | |
e3878612 | 75 | return load(parent, modname) |
76 | ||
db50981b | 77 | |
78 | def loadall(parent, modlist): | |
79 | for m in modlist: load(parent, m) | |
80 | def unloadall(parent, modlist): | |
81 | for m in modlist: unload(parent, m) | |
82 | def reloadall(parent, modlist): | |
83 | for m in modlist: reloadmod(parent, m) | |
84 | ||
85 | sys.path.append('modules') |