]>
Commit | Line | Data |
---|---|---|
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 | try: | |
16 | mod = __import__(modname) | |
17 | reload(mod) #in case it's been previously loaded. | |
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 | ||
21 | ||
22 | if not hasattr(mod, 'modinfo'): | |
23 | return modlib.error('no modinfo') | |
24 | ||
25 | if parent.APIVERSION not in mod.modinfo['compatible']: | |
26 | return modlib.error('API-incompatible') | |
27 | ||
28 | modules[modname] = mod | |
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 | ||
39 | ret = mod.modstart(parent) | |
40 | if ret is not None and not ret: | |
41 | del modules[modname] | |
42 | del dependents[modname] | |
43 | for dep in mod.modinfo['depends']: | |
44 | dependents[dep].remove(modname) | |
45 | return ret | |
46 | else: #if not isloaded...else: | |
47 | return modlib.error('already loaded') | |
48 | ||
49 | def unload(parent, modname): | |
50 | if isloaded(modname): | |
51 | for dependent in dependents[modname]: | |
52 | unload(parent, dependent) | |
53 | for dep in dependents[modname]: | |
54 | dependents[dep].remove(modname) | |
55 | ret = modules[modname].modstop(parent) | |
56 | del modules[modname] | |
57 | return ret | |
58 | else: | |
59 | return modlib.error('already unloaded') | |
60 | ||
61 | def reloadmod(parent, modname): | |
62 | if isloaded(modname): | |
63 | if modhas(modname, 'modrestart'): modules[modname].modrestart(parent) | |
64 | else: modules[modname].modstop(parent) | |
65 | ||
66 | try: | |
67 | reload(modules[modname]) | |
68 | except BaseException as e: | |
69 | return modlib.error(e) | |
70 | ||
71 | if modhas(modname, 'modrestarted'): ret = modules[modname].modrestarted(parent) | |
72 | else: ret = modules[modname].modstart(parent) | |
73 | ||
74 | return ret | |
75 | else: | |
76 | return load(parent, modname) | |
77 | ||
78 | ||
79 | def loadall(parent, modlist): | |
80 | for m in modlist: load(parent, m) | |
81 | def unloadall(parent, modlist): | |
82 | for m in modlist: unload(parent, m) | |
83 | def reloadall(parent, modlist): | |
84 | for m in modlist: reloadmod(parent, m) | |
85 | ||
86 | sys.path.append('modules') |