1 from os import path as os_path, listdir as os_listdir
2 from traceback import print_exc
5 from Tools.Directories import fileExists
6 from Tools.Import import my_import
7 from Plugins.Plugin import PluginDescriptor
10 class PluginComponent:
12 restartRequired = False
17 self.installedPluginList = [ ]
18 self.setPluginPrefix("Plugins.")
21 def setPluginPrefix(self, prefix):
24 def addPlugin(self, plugin):
25 if self.firstRun or plugin.needsRestart is False:
26 self.pluginList.append(plugin)
27 for x in plugin.where:
28 self.plugins.setdefault(x, []).append(plugin)
29 if x == PluginDescriptor.WHERE_AUTOSTART:
32 self.restartRequired = True
34 def removePlugin(self, plugin):
35 self.pluginList.remove(plugin)
36 for x in plugin.where:
37 self.plugins[x].remove(plugin)
38 if x == PluginDescriptor.WHERE_AUTOSTART:
41 def readPluginList(self, directory):
42 """enumerates plugins"""
44 categories = os_listdir(directory)
49 directory_category = directory + c
50 if not os_path.isdir(directory_category):
52 open(directory_category + "/__init__.py", "a").close()
53 for pluginname in os_listdir(directory_category):
54 path = directory_category + "/" + pluginname
55 if os_path.isdir(path):
56 if fileExists(path + "/plugin.pyc") or fileExists(path + "/plugin.pyo") or fileExists(path + "/plugin.py"):
58 plugin = my_import('.'.join(["Plugins", c, pluginname, "plugin"]))
60 if not plugin.__dict__.has_key("Plugins"):
61 print "Plugin %s doesn't have 'Plugin'-call." % (pluginname)
64 plugins = plugin.Plugins(path=path)
65 except Exception, exc:
66 print "Plugin ", c + "/" + pluginname, "failed to load:", exc
67 print_exc(file=stdout)
68 print "skipping plugin."
69 self.warnings.append( (c + "/" + pluginname, str(exc)) )
72 # allow single entry not to be a list
73 if not isinstance(plugins, list):
81 if fileExists(path + "/keymap.xml"):
83 keymapparser.readKeymap(path + "/keymap.xml")
84 except Exception, exc:
85 print "keymap for plugin %s/%s failed to load: " % (c, pluginname), exc
86 self.warnings.append( (c + "/" + pluginname, str(exc)) )
88 # build a diff between the old list of plugins and the new one
89 # internally, the "fnc" argument will be compared with __eq__
90 plugins_added = [p for p in new_plugins if p not in self.pluginList]
91 plugins_removed = [p for p in self.pluginList if not p.internal and p not in new_plugins]
93 #ignore already installed but reloaded plugins
94 for p in plugins_removed:
95 for pa in plugins_added:
96 if pa.path == p.path and pa.where == p.where:
97 pa.needsRestart = False
99 for p in plugins_removed:
102 for p in plugins_added:
103 if self.firstRun or p.needsRestart is False:
106 for installed_plugin in self.installedPluginList:
107 if installed_plugin.path == p.path:
108 if installed_plugin.where == p.where:
109 p.needsRestart = False
113 self.firstRun = False
114 self.installedPluginList = self.pluginList
116 def getPlugins(self, where):
117 """Get list of plugins in a specific category"""
119 if not isinstance(where, list):
124 res.extend(self.plugins.get(x, [ ]))
128 def getPluginsForMenu(self, menuid):
130 for p in self.getPlugins(PluginDescriptor.WHERE_MENU):
134 def clearPluginList(self):
139 for p in self.pluginList[:]:
142 def resetWarnings(self):
145 def getNextWakeupTime(self):
147 for p in self.pluginList:
148 current = p.getWakeupTime()
149 if current > -1 and (wakeup > current or wakeup == -1):
153 plugins = PluginComponent()