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 for pluginname in os_listdir(directory_category):
53 path = directory_category + "/" + pluginname
54 if os_path.isdir(path):
55 if fileExists(path + "/plugin.pyc") or fileExists(path + "/plugin.pyo") or fileExists(path + "/plugin.py"):
57 plugin = my_import('.'.join(["Plugins", c, pluginname, "plugin"]))
59 if not plugin.__dict__.has_key("Plugins"):
60 print "Plugin %s doesn't have 'Plugin'-call." % (pluginname)
63 plugins = plugin.Plugins(path=path)
64 except Exception, exc:
65 print "Plugin ", c + "/" + pluginname, "failed to load:", exc
66 print_exc(file=stdout)
67 print "skipping plugin."
68 self.warnings.append( (c + "/" + pluginname, str(exc)) )
71 # allow single entry not to be a list
72 if not isinstance(plugins, list):
80 if fileExists(path + "/keymap.xml"):
82 keymapparser.readKeymap(path + "/keymap.xml")
83 except Exception, exc:
84 print "keymap for plugin %s/%s failed to load: " % (c, pluginname), exc
85 self.warnings.append( (c + "/" + pluginname, str(exc)) )
87 # build a diff between the old list of plugins and the new one
88 # internally, the "fnc" argument will be compared with __eq__
89 plugins_added = [p for p in new_plugins if p not in self.pluginList]
90 plugins_removed = [p for p in self.pluginList if not p.internal and p not in new_plugins]
92 #ignore already installed but reloaded plugins
93 for p in plugins_removed:
94 for pa in plugins_added:
95 if pa.path == p.path and pa.where == p.where:
96 pa.needsRestart = False
98 for p in plugins_removed:
101 for p in plugins_added:
102 if self.firstRun or p.needsRestart is False:
105 for installed_plugin in self.installedPluginList:
106 if installed_plugin.path == p.path:
107 if installed_plugin.where == p.where:
108 p.needsRestart = False
112 self.firstRun = False
113 self.installedPluginList = self.pluginList
115 def getPlugins(self, where):
116 """Get list of plugins in a specific category"""
118 if not isinstance(where, list):
123 res.extend(self.plugins.get(x, [ ]))
124 res.sort(key=lambda x:x.weight)
127 def getPluginsForMenu(self, menuid):
129 for p in self.getPlugins(PluginDescriptor.WHERE_MENU):
133 def clearPluginList(self):
138 for p in self.pluginList[:]:
141 def resetWarnings(self):
144 def getNextWakeupTime(self):
146 for p in self.pluginList:
147 current = p.getWakeupTime()
148 if current > -1 and (wakeup > current or wakeup == -1):
152 plugins = PluginComponent()