summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorjerous <jerous@gmail.com>2008-11-15 17:23:14 +0100
committerjerous <jerous@gmail.com>2008-11-15 17:23:14 +0100
commitb22148c1bf833464dfc87ce696b4184ae0184e16 (patch)
treebab8bee4a96817772a62a9f1b3b57249edc5d163 /plugins
parent536e8e3be5a5dcb0e9c6e0f8664e84b5eb65d796 (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.py3
-rw-r--r--plugins/PlayControl.py3
-rw-r--r--plugins/Playlist.py3
-rw-r--r--plugins/__init__.py92
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()