add possible todo regarding mounted/ismount
[enigma2.git] / lib / python / Components / PluginComponent.py
1 from os import path as os_path, listdir as os_listdir
2 from traceback import print_exc
3 from sys import stdout
4
5 from Tools.Directories import fileExists
6 from Tools.Import import my_import
7 from Plugins.Plugin import PluginDescriptor
8
9 class PluginComponent:
10         def __init__(self):
11                 self.plugins = {}
12                 self.pluginList = [ ]
13                 self.setPluginPrefix("Plugins.")
14                 self.resetWarnings()
15
16         def setPluginPrefix(self, prefix):
17                 self.prefix = prefix
18
19         def addPlugin(self, plugin):
20                 self.pluginList.append(plugin)
21                 for x in plugin.where:
22                         self.plugins.setdefault(x, []).append(plugin)
23                         if x == PluginDescriptor.WHERE_AUTOSTART:
24                                 plugin(reason=0)
25
26         def removePlugin(self, plugin):
27                 self.pluginList.remove(plugin)
28                 for x in plugin.where:
29                         self.plugins[x].remove(plugin)
30                         if x == PluginDescriptor.WHERE_AUTOSTART:
31                                 plugin(reason=1)
32
33         def readPluginList(self, directory):
34                 """enumerates plugins"""
35                 
36                 categories = os_listdir(directory)
37                 
38                 new_plugins = [ ]
39                 
40                 for c in categories:
41                         directory_category = directory + c
42                         if not os_path.isdir(directory_category):
43                                 continue
44                         open(directory_category + "/__init__.py", "a").close()
45                         for pluginname in os_listdir(directory_category):
46                                 path = directory_category + "/" + pluginname
47                                 if os_path.isdir(path):
48                                         if fileExists(path + "/plugin.pyc") or fileExists(path + "/plugin.py"):
49                                                 try:
50                                                         plugin = my_import('.'.join(["Plugins", c, pluginname, "plugin"]))
51
52                                                         if not plugin.__dict__.has_key("Plugins"):
53                                                                 print "Plugin %s doesn't have 'Plugin'-call." % (pluginname)
54                                                                 continue
55
56                                                         plugins = plugin.Plugins(path=path)
57                                                 except Exception, exc:
58                                                         print "Plugin ", c + "/" + pluginname, "failed to load:", exc
59                                                         print_exc(file=stdout)
60                                                         print "skipping plugin."
61                                                         self.warnings.append( (c + "/" + pluginname, str(exc)) )
62                                                         continue
63
64                                                 # allow single entry not to be a list
65                                                 if type(plugins) is not list:
66                                                         plugins = [ plugins ]
67
68                                                 for p in plugins:
69                                                         p.updateIcon(path)
70                                                         new_plugins.append(p)
71
72                 # build a diff between the old list of plugins and the new one
73                 # internally, the "fnc" argument will be compared with __eq__
74                 plugins_added = [p for p in new_plugins if p not in self.pluginList]
75                 plugins_removed = [p for p in self.pluginList if p not in new_plugins]
76
77                 for p in plugins_removed:
78                         self.removePlugin(p)
79
80                 for p in plugins_added:
81                         self.addPlugin(p)
82
83         def getPlugins(self, where):
84                 """Get list of plugins in a specific category"""
85
86                 if type(where) is not list:
87                         where = [ where ]
88                 res = [ ]
89                 for x in where:
90                         for p in self.plugins.get(x, [ ]):
91                                 res.append(p)
92                 return res
93
94         def getPluginsForMenu(self, menuid):
95                 res = [ ]
96                 for p in self.getPlugins(PluginDescriptor.WHERE_SETUP):
97                         res += p(menuid)
98                 return res
99
100         def clearPluginList(self):
101                 self.pluginList = []
102                 self.plugins = {}
103
104         def shutdown(self):
105                 for p in self.pluginList[:]:
106                         self.removePlugin(p)
107
108         def resetWarnings(self):
109                 self.warnings = [ ]
110
111 plugins = PluginComponent()