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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
from os import path as os_path, listdir as os_listdir
from traceback import print_exc
from sys import stdout
from Tools.Directories import fileExists
from Tools.Import import my_import
from Plugins.Plugin import PluginDescriptor
import keymapparser
class PluginComponent:
firstRun = True
restartRequired = False
def __init__(self):
self.plugins = {}
self.pluginList = [ ]
self.installedPluginList = [ ]
self.setPluginPrefix("Plugins.")
self.resetWarnings()
def setPluginPrefix(self, prefix):
self.prefix = prefix
def addPlugin(self, plugin):
if self.firstRun or plugin.needsRestart is False:
self.pluginList.append(plugin)
for x in plugin.where:
self.plugins.setdefault(x, []).append(plugin)
if x == PluginDescriptor.WHERE_AUTOSTART:
plugin(reason=0)
else:
self.restartRequired = True
def removePlugin(self, plugin):
self.pluginList.remove(plugin)
for x in plugin.where:
self.plugins[x].remove(plugin)
if x == PluginDescriptor.WHERE_AUTOSTART:
plugin(reason=1)
def readPluginList(self, directory):
"""enumerates plugins"""
categories = os_listdir(directory)
new_plugins = [ ]
for c in categories:
directory_category = directory + c
if not os_path.isdir(directory_category):
continue
open(directory_category + "/__init__.py", "a").close()
for pluginname in os_listdir(directory_category):
path = directory_category + "/" + pluginname
if os_path.isdir(path):
if fileExists(path + "/plugin.pyc") or fileExists(path + "/plugin.pyo") or fileExists(path + "/plugin.py"):
try:
plugin = my_import('.'.join(["Plugins", c, pluginname, "plugin"]))
if not plugin.__dict__.has_key("Plugins"):
print "Plugin %s doesn't have 'Plugin'-call." % (pluginname)
continue
plugins = plugin.Plugins(path=path)
except Exception, exc:
print "Plugin ", c + "/" + pluginname, "failed to load:", exc
print_exc(file=stdout)
print "skipping plugin."
self.warnings.append( (c + "/" + pluginname, str(exc)) )
continue
# allow single entry not to be a list
if not isinstance(plugins, list):
plugins = [ plugins ]
for p in plugins:
p.path = path
p.updateIcon(path)
new_plugins.append(p)
if fileExists(path + "/keymap.xml"):
try:
keymapparser.readKeymap(path + "/keymap.xml")
except Exception, exc:
print "keymap for plugin %s/%s failed to load: " % (c, pluginname), exc
self.warnings.append( (c + "/" + pluginname, str(exc)) )
# build a diff between the old list of plugins and the new one
# internally, the "fnc" argument will be compared with __eq__
plugins_added = [p for p in new_plugins if p not in self.pluginList]
plugins_removed = [p for p in self.pluginList if not p.internal and p not in new_plugins]
#ignore already installed but reloaded plugins
for p in plugins_removed:
for pa in plugins_added:
if pa.path == p.path and pa.where == p.where:
pa.needsRestart = False
for p in plugins_removed:
self.removePlugin(p)
for p in plugins_added:
if self.firstRun or p.needsRestart is False:
self.addPlugin(p)
else:
for installed_plugin in self.installedPluginList:
if installed_plugin.path == p.path:
if installed_plugin.where == p.where:
p.needsRestart = False
self.addPlugin(p)
if self.firstRun:
self.firstRun = False
self.installedPluginList = self.pluginList
def getPlugins(self, where):
"""Get list of plugins in a specific category"""
if not isinstance(where, list):
where = [ where ]
res = [ ]
for x in where:
res.extend(self.plugins.get(x, [ ]))
res.sort(key=lambda x:x.weight)
return res
def getPluginsForMenu(self, menuid):
res = [ ]
for p in self.getPlugins(PluginDescriptor.WHERE_MENU):
res += p(menuid)
return res
def clearPluginList(self):
self.pluginList = []
self.plugins = {}
def shutdown(self):
for p in self.pluginList[:]:
self.removePlugin(p)
def resetWarnings(self):
self.warnings = [ ]
def getNextWakeupTime(self):
wakeup = -1
for p in self.pluginList:
current = p.getWakeupTime()
if current > -1 and (wakeup > current or wakeup == -1):
wakeup = current
return int(wakeup)
plugins = PluginComponent()
|