aboutsummaryrefslogtreecommitdiff
path: root/lib/python/Components/PluginComponent.py
blob: 6e357cd0431aa3367f10ad4a71644625b7e37ab4 (plain)
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
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:
	def __init__(self):
		self.plugins = {}
		self.pluginList = [ ]
		self.setPluginPrefix("Plugins.")
		self.resetWarnings()

	def setPluginPrefix(self, prefix):
		self.prefix = prefix

	def addPlugin(self, plugin):
		self.pluginList.append(plugin)
		for x in plugin.where:
			self.plugins.setdefault(x, []).append(plugin)
			if x == PluginDescriptor.WHERE_AUTOSTART:
				plugin(reason=0)

	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.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.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]

		for p in plugins_removed:
			self.removePlugin(p)

		for p in plugins_added:
			self.addPlugin(p)

	def getPlugins(self, where):
		"""Get list of plugins in a specific category"""

		if not isinstance(where, list):
			where = [ where ]
		res = [ ]

		for x in where:
			for p in self.plugins.get(x, [ ]):
				res.append(p)
		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:
				wakeup = current
		return int(wakeup)

plugins = PluginComponent()