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('nephilim/plugins'): if file[-3:]=='.py' and file!='__init__.py': name=file[:-3] # name without ext mod='nephilim.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()