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
|
import os
import sys
import logging
# { className => [module, className, instance, msg] }
_plugins=None
PLUGIN_MODULE=0
PLUGIN_CLASS=1
PLUGIN_INSTANCE=2
PLUGIN_MSG=3
class IPlaylist:
def ensureVisible(self, song_id):
raise Exception("TODO implement")
def loadPlugins():
"""(Re)load all modules in the plugins directory."""
global _plugins
_plugins={}
for file in os.listdir('plugins'):
if file[-3:]=='.py' and file!='__init__.py':
name=file[:-3] # name without ext
mod='plugins.%s'%(name) # mod name
className='plugin%s'%(name) # classname
_plugins[className.lower()]=[mod, className, None, None]
loadPlugin(className, None)
def setPluginMessage(name, msg):
global _plugins
try:
_plugins[name.lower()][PLUGIN_MSG]=msg
except:
try:
_plugins["plugin%s"%(name.lower())][PLUGIN_MODULE]=msg
except:
pass
def getPlugin(name):
global _plugins
try:
return _plugins[name.lower()][PLUGIN_INSTANCE]
except:
try:
return _plugins["plugin%s"%(name.lower())][PLUGIN_INSTANCE]
except:
return None
def loadPlugin(className, parent):
"""Constructs a plugin."""
global _plugins
entry=_plugins[className.lower()]
mod=entry[PLUGIN_MODULE]
# ensure we get the latest version
try:
try:
sys.modules[mod]
reimport=True
except:
reimport=False
if reimport:
reload(sys.modules[mod])
else:
module=__import__(mod, globals(), locals(), className, -1)
except Exception, e:
_plugins[className.lower()][PLUGIN_MSG]=str(e)
_plugins[className.lower()][PLUGIN_INSTANCE]=None
logging.warning("Failed to load plugin %s: %s %s"%(className, str(type(e)), str(e)))
return None
module=sys.modules[mod]
_plugins[className.lower()][PLUGIN_MSG]=None
if parent:
# instantiate the plugin
_plugins[className.lower()][PLUGIN_INSTANCE]=module.__dict__[className](parent)
else:
_plugins[className.lower()][PLUGIN_INSTANCE]=None
return _plugins[className.lower()][PLUGIN_INSTANCE]
def listImplementors(interface, loaded = True):
"""Return a list of plugin-instances that implement an interface"""
global _plugins
return map(lambda plugin: plugin[PLUGIN_INSTANCE]
, filter(lambda plugin: isinstance(plugin[PLUGIN_INSTANCE], interface)
and ((loaded != None and plugin[PLUGIN_INSTANCE].loaded == loaded) or (loaded == None)), _plugins.values()))
def listPlugins():
"""Get the list of plugins available as { className => [mod, className, instance, msg] }."""
global _plugins
return _plugins
loadPlugins()
|