diff options
author | jerous <jerous@gmail.com> | 2008-11-15 17:23:14 +0100 |
---|---|---|
committer | jerous <jerous@gmail.com> | 2008-11-15 17:23:14 +0100 |
commit | b22148c1bf833464dfc87ce696b4184ae0184e16 (patch) | |
tree | bab8bee4a96817772a62a9f1b3b57249edc5d163 /plugins | |
parent | 536e8e3be5a5dcb0e9c6e0f8664e84b5eb65d796 (diff) |
redesign of plugin-handling
plugin-handling is performed in plugins/__init__.py (instead of winMain)
robustness against plugins containing errors (like syntax etc)
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Notify.py | 3 | ||||
-rw-r--r-- | plugins/PlayControl.py | 3 | ||||
-rw-r--r-- | plugins/Playlist.py | 3 | ||||
-rw-r--r-- | plugins/__init__.py | 92 |
4 files changed, 80 insertions, 21 deletions
diff --git a/plugins/Notify.py b/plugins/Notify.py index d039617..14e35af 100644 --- a/plugins/Notify.py +++ b/plugins/Notify.py @@ -6,6 +6,7 @@ import format from misc import * from clMonty import monty from clPlugin import * +import plugins NOTIFY_SONGFORMAT_DEFAULT='$if($artist,$artist)$if($album, - [$album #$track])\n$title ($timems)'; NOTIFY_TIMER_DEFAULT=3 @@ -79,7 +80,7 @@ class winNotify(QtGui.QWidget): # album cover width=0 try: - cover=self.winMain.getPlugin('albumcover') + cover=plugins.getPlugin('albumcover') img=cover.getWidget().getIMG() if img: width=128 diff --git a/plugins/PlayControl.py b/plugins/PlayControl.py index e903c2f..0876af0 100644 --- a/plugins/PlayControl.py +++ b/plugins/PlayControl.py @@ -6,6 +6,7 @@ from clPlugin import * import clSong from thread import start_new_thread from random import randint +import plugins # Some predefined constants. # Note that REPEAT precedes RANDOM. E.g. if repeat @@ -151,7 +152,7 @@ class wgPlayControl(QtGui.QWidget): self.cmbShuffle.setItemText(PC_RANDOM_QUEUE, "Queue (%i)"%(len(self.queuedSongs))) def onBtnJmpCurrentClick(self): - self.p.getWinMain().getPlugin("Playlist").getPlaylist().ensureVisible(monty.getCurrentSong().getID()) + plugins.getPlugin("Playlist").getPlaylist().ensureVisible(monty.getCurrentSong().getID()) def onStateChange(self, params): newState=monty.getStatus()['state'] diff --git a/plugins/Playlist.py b/plugins/Playlist.py index 0e45ea6..3cb812b 100644 --- a/plugins/Playlist.py +++ b/plugins/Playlist.py @@ -4,6 +4,7 @@ from clPlugin import * from misc import * from wgPlaylist import Playlist from wgSongList import clrRowSel +import plugins PLAYLIST_MODES_DEFAULT='$artist\n'\ '$artist/$date - $album\n'\ @@ -55,7 +56,7 @@ class pluginPlaylist(Plugin): elif event.key()==QtCore.Qt.Key_Q: # queue selected songs # Hoho, this one needs the playcontrol plugin! - self.getWinMain().getPlugin('playcontrol').addSongsToQueue(self.o.selectedIds()) + plugins.getPlugin('playcontrol').addSongsToQueue(self.o.selectedIds()) return QtGui.QWidget.keyPressEvent(self.o, event) def onSongChange(self, params): diff --git a/plugins/__init__.py b/plugins/__init__.py index cd1a378..69e8a4c 100644 --- a/plugins/__init__.py +++ b/plugins/__init__.py @@ -1,22 +1,78 @@ -def listPlugins(): +import os +import sys +import log + +# { className => [module, className, instance, msg] } +_plugins=None +PLUGIN_MODULE=0 +PLUGIN_CLASS=1 +PLUGIN_INSTANCE=2 +PLUGIN_MSG=3 + + +def loadPlugins(): + """(Re)load all modules in the plugins directory.""" global _plugins - return _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) -_plugins=[] -import os -#for file in ('Library.py', 'Playlist.py'): #os.listdir('plugins'): -for file in os.listdir('plugins'): - if file[-3:]=='.py' and file!='__init__.py': - name=file[:-3] # name without ext - pkg='plugins.%s'%(name) # pkg name - pluginName='plugin%s'%(name) # classname - - module=__import__(pkg, globals(), locals(), pluginName, -1) +def getPlugin(name): + global _plugins + try: + return _plugins[name.lower()][PLUGIN_INSTANCE] + except: try: - #check here if the file contains an entity (let's hope - #a class!) with $pluginName! - module.__dict__[pluginName] - _plugins.append([pkg, pluginName]) + return _plugins["plugin%s"%(name.lower())][PLUGIN_INSTANCE] except: - #print "Failed to load plugin "+pluginName - pass + 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) + log.important("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 listPlugins(): + """Get the list of plugins available as { className => [mod, className, instance, msg] }.""" + global _plugins + return _plugins + + +loadPlugins() |