forked from Bytespeicher/Bytebot
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bytebotpluginloader.py
71 lines (62 loc) · 2.63 KB
/
bytebotpluginloader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from sys import exit
from twisted.internet import reactor
from bytebot_log import LOG_DEBUG, LOG_WARN, LOG_ERROR
from twisted.python import log
class ByteBotPluginLoader(object):
"""This class enables automatic loading and method calling for plugin
classes.
The class also catches faulty plugin code so if an exception is thrown
that is not handled in the plugin code itself it will be handled here
without crashing the whole bot."""
PLUGINS = {}
def __init__(self, plugins, plugin_path='plugins'):
"""
plugins: tupel with plugin names to register
plugin_path: path to plugins
MUST NOT end with a trailing slash
"""
path = plugin_path.replace('/', '.')
for plugin in plugins:
try:
self.PLUGINS[plugin] = getattr(
__import__("%s.%s" % (path, plugin)).__dict__[plugin],
plugin
)()
log.msg("Loaded plugin '%s'" % plugin)
except Exception as e:
log.msg("FATAL: Could not import plugin %s.%s" %
(path, plugin),
level=LOG_ERROR)
log.msg("FATAL: %s" % e, level=LOG_ERROR)
exit(255)
def run(self, fn, args={}, threaded=True):
"""Runs a specific function on all registered plugins
fn plugin method name to execute
args dictionary with arguments to call the method with
threaded if set to True, the functions will be run in a thread
"""
log.msg("Executing function %s on all plugins with args %s" %
(fn, args),
level=LOG_DEBUG)
for key, plugin in self.PLUGINS.iteritems():
try:
method = getattr(plugin, fn)
if not threaded:
log.msg("Execute | non-threaded | %s->%s" %
(plugin, method.__name__),
level=LOG_DEBUG)
method(**args)
else:
log.msg("Execute | threaded | %s->%s" %
(plugin, method.__name__),
level=LOG_DEBUG)
reactor.callInThread(method, **args)
except Exception as e:
log.msg(
"WARNING: An error occured while executing %s in %s " +
"with %s" % (fn, plugin, args),
level=LOG_WARN
)
log.msg("WARNING: %s" % e, level=LOG_DEBUG)