]>
jfr.im git - erebus.git/blob - ctlmod.py
1 # Erebus IRC bot - Author: John Runyon
2 # module loading/unloading/tracking code
9 #dependents[modname] = [list of modules which depend on modname]
11 def isloaded(modname
): return modname
in modules
12 def modhas(modname
, attname
): return getattr(modules
[modname
], attname
, None) is not None
14 def load(parent
, modname
, dependent
=False):
15 #wrapper to call _load and print return
17 print "(Loading dependency %s..." % (modname
),
19 print "%09.3f [MOD] [?] Loading %s..." % (time
.time() % 100000, modname
),
20 modstatus
= _load(parent
, modname
, dependent
)
23 print "failed: %s)" % (modstatus
),
25 print "failed: %s." % (modstatus
)
26 elif modstatus
== True:
33 print "OK: %s)" % (modstatus
),
35 print "OK: %s." % (modstatus
)
38 def _load(parent
, modname
, dependent
=False):
40 if not isloaded(modname
):
42 mod
= __import__('modules.'+modname
, globals(), locals(), ['*'], -1)
43 # ^ fromlist doesn't actually do anything(?) but it means we don't have to worry about this returning the top-level "modules" object
44 reload(mod
) #in case it's been previously loaded.
45 except Exception as e
:
46 return modlib
.error(e
)
49 if not hasattr(mod
, 'modinfo'):
50 return modlib
.error('no modinfo')
52 if parent
.APIVERSION
not in mod
.modinfo
['compatible']:
53 return modlib
.error('API-incompatible')
55 modules
[modname
] = mod
56 dependents
[modname
] = []
58 for dep
in mod
.modinfo
['depends']:
59 if bool(int(parent
.cfg
.get('autoloads', dep
, default
=1))):
60 if dep
not in modules
:
61 depret
= load(parent
, dep
, dependent
=True)
62 if depret
is not None and not depret
:
65 return modlib
.error("dependent %s disabled" % (dep
))
66 dependents
[dep
].append(modname
)
68 for dep
in mod
.modinfo
['softdeps']:
69 if bool(int(parent
.cfg
.get('autoloads', dep
, default
=1))):
70 if dep
not in modules
:
71 depret
= load(parent
, dep
, dependent
=True)
72 if depret
is not None:
74 successstatus
.append("softdep %s failed" % (dep
))
76 successstatus
.append("softdep %s disabled" % (dep
))
77 #swallow errors loading - softdeps are preferred, not required
80 ret
= mod
.modstart(parent
)
85 del dependents
[modname
]
86 for dep
in mod
.modinfo
['depends']:
87 dependents
[dep
].remove(modname
)
89 successstatus
= ';'.join(successstatus
)
90 if len(successstatus
) > 0 and ret
:
94 return "%s (%s)" % (ret
, successstatus
)
97 else: #if not isloaded...else:
98 return modlib
.error('already loaded')
100 def unload(parent
, modname
):
101 if isloaded(modname
):
102 for dependent
in dependents
[modname
]:
103 unload(parent
, dependent
)
104 for dep
in modules
[modname
].modinfo
['depends']:
105 dependents
[dep
].remove(modname
)
106 ret
= modules
[modname
].modstop(parent
)
110 return modlib
.error('already unloaded')
112 def reloadmod(parent
, modname
):
113 if isloaded(modname
):
114 if modhas(modname
, 'modrestart'): modules
[modname
].modrestart(parent
)
115 else: modules
[modname
].modstop(parent
)
118 reload(modules
[modname
])
119 except BaseException
as e
:
120 return modlib
.error(e
)
122 if modhas(modname
, 'modrestarted'): ret
= modules
[modname
].modrestarted(parent
)
123 else: ret
= modules
[modname
].modstart(parent
)
127 return load(parent
, modname
)
130 def loadall(parent
, modlist
):
131 for m
in modlist
: load(parent
, m
)
132 def unloadall(parent
, modlist
):
133 for m
in modlist
: unload(parent
, m
)
134 def reloadall(parent
, modlist
):
135 for m
in modlist
: reloadmod(parent
, m
)