forked from serpis/pynik
-
Notifications
You must be signed in to change notification settings - Fork 7
/
plugin_handler.py
103 lines (82 loc) · 2.32 KB
/
plugin_handler.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import os
import imp
import sys
import re
import error_handler
# TODO Is this deprecated module actually used? Can another one be used instead?
import sets
from copy import copy
# Run the following code only on first import
try:
plugins_module
except NameError:
prev = copy(sys.modules.values())
from plugins import *
new_modules = []
plugins_module = None
for module in sys.modules.values():
if not module:
continue
if module not in prev:
if module.__name__ == 'plugins':
plugins_module = module
if module.__name__ == 'plugins.plugins':
new_modules.insert(0, module)
elif module.__name__ == 'plugins.commands':
if len(new_modules) == 0 or new_modules[0].__name__ != 'plugins.plugins':
new_modules.insert(0, module)
else:
new_modules.insert(1, module)
else:
new_modules.append(module)
new_modules = filter(lambda x: re.match('^plugins\.', x.__name__), new_modules)
def reload_plugin_modules():
import traceback
for module in new_modules:
try:
reload(module)
except:
error_handler.output_message('error when reloading module ' + str(module.__name__) + ' ' + str(sys.exc_info()) + ' ' + str(traceback.extract_tb(sys.exc_info()[2])))
def search_for_subclasses(c):
l = [c]
for subclass in c.__subclasses__():
l.extend(search_for_subclasses(subclass))
return l
def get_plugins_by_hook(hook):
result = []
for plugin in search_for_subclasses(plugins.Plugin):
if hook in plugin.hooks:
result.append(plugin.instance)
return result
def all_plugins():
result = []
for plugin in search_for_subclasses(plugins.Plugin):
result.append(plugin.instance)
return result
def load_plugin(plugin):
import re
if plugin == "":
raise ImportError('No module named given')
package = plugins_module
name = package.__name__ + '.' + plugin
file, filename, description = imp.find_module(plugin, package.__path__)
try:
module = imp.load_module(name, file, filename, description)
new_modules.append(module)
except:
raise
finally:
if file != None:
file.close()
def plugins_on_load():
l = search_for_subclasses(plugins.Plugin)
for plugin in l:
plugin.instance = plugin()
for plugin in l:
plugin.instance.on_load()
def plugins_on_unload():
l = search_for_subclasses(plugins.Plugin)
for plugin in l:
plugin.instance.on_unload()
for plugin in l:
plugin.instance = None