When can you need it?
For example, you have one sonata instance in /usr/bin for your wife, and
another one in ~/git/sonata.git - for you. In this case your version of
sonata will get double version of each plugin. Unless you apply this
patch, of course :-)
diff --git a/sonata/pluginsystem.py b/sonata/pluginsystem.py
index eea47f5..813cd81 100644
--- a/sonata/pluginsystem.py
+++ b/sonata/pluginsystem.py
@@ -1,6 +1,7 @@
 
 import os, re, StringIO
 import ConfigParser, pkgutil
+import traceback
 
 import sonata.plugins
 
@@ -88,6 +89,7 @@ class Plugin(object):
                 self._module = self._load()
             except Exception:
                 print "Failed to load plugin %s." % self.name
+                traceback.print_exc()
                 return None
         return self._module
 
@@ -143,6 +145,7 @@ class PluginSystem(object):
             plugin._enabled = state
 
     def find_plugins(self):
+        bestplugins = {}
         for path in sonata.plugins.__path__:
             if not os.path.isdir(path):
                 continue
@@ -151,10 +154,29 @@ class PluginSystem(object):
                     continue # __init__.py etc.
                 if entry.endswith('.py'):
                     try:
-                        self.load_info(path, entry[:-3])
+                        info = self.load_info(path, entry[:-3])
+                        name_internal = info.get('plugin', 'name')
+                        version = [ int(x) for x in info.get('plugin', 'version').split(', ') ]
+                        # add this to bestplugins if it's not there yet or this version is newer:
+                        if not name_internal in bestplugins or bestplugins[name_internal][0] < version:
+                            bestplugins[name_internal] = (version, info, path, entry[:-3])
                     except Exception:
                         print "Failed to load info:",
                         print os.path.join(path, entry)
+                        traceback.print_exc()
+        
+        # this sub creates proper surrounding scope for lambda
+        # otherwise it binds to local name variable, and we change it
+        def really_add(path, name, info):
+            plugin = Plugin(path, name, info,
+                    lambda:self.import_plugin(name))
+            self.plugin_infos.append(plugin)
+        
+        # now load only newest version of each name
+        for (name_internal, (version, info, path, name)) in bestplugins.items():
+            really_add(path, name, info)
+            if not info.options('capabilities'):
+                print "Warning: No capabilities in plugin %s." % name
 
     def load_info(self, path, name):
         f = open(os.path.join(path, name+".py"), "rt")
@@ -168,14 +190,8 @@ class PluginSystem(object):
         info = ConfigParser.SafeConfigParser()
         info.readfp(StringIO.StringIO(uncommented))
 
-        # XXX add only newest version of each name
-        plugin = Plugin(path, name, info,
-                lambda:self.import_plugin(name))
+        return info
 
-        self.plugin_infos.append(plugin)
-
-        if not info.options('capabilities'):
-            print "Warning: No capabilities in plugin %s." % name
 
     def import_plugin(self, name):
         # XXX load from a .py file - no .pyc etc.
_______________________________________________
Sonata-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/sonata-users

Reply via email to