[QGIS Commit] r9625 - trunk/qgis/python/plugins/plugin_installer

svn_qgis at osgeo.org svn_qgis at osgeo.org
Tue Nov 11 19:26:40 EST 2008


Author: borysiasty
Date: 2008-11-11 19:26:40 -0500 (Tue, 11 Nov 2008)
New Revision: 9625

Added:
   trunk/qgis/python/plugins/plugin_installer/version_compare.py
Modified:
   trunk/qgis/python/plugins/plugin_installer/__init__.py
   trunk/qgis/python/plugins/plugin_installer/i18n.cpp
   trunk/qgis/python/plugins/plugin_installer/installer_data.py
   trunk/qgis/python/plugins/plugin_installer/installer_gui.py
   trunk/qgis/python/plugins/plugin_installer/installer_plugin.py
Log:
Plugin Installer update: plugin compatibility checking


Modified: trunk/qgis/python/plugins/plugin_installer/__init__.py
===================================================================
--- trunk/qgis/python/plugins/plugin_installer/__init__.py	2008-11-11 15:30:31 UTC (rev 9624)
+++ trunk/qgis/python/plugins/plugin_installer/__init__.py	2008-11-12 00:26:40 UTC (rev 9625)
@@ -20,7 +20,7 @@
   return "perrygeo, borysiasty"
 
 def version():
-  return "Version 0.9"
+  return "Version 0.9.1"
 
 def classFactory(iface):
   from installer_plugin import InstallerPlugin

Modified: trunk/qgis/python/plugins/plugin_installer/i18n.cpp
===================================================================
--- trunk/qgis/python/plugins/plugin_installer/i18n.cpp	2008-11-11 15:30:31 UTC (rev 9624)
+++ trunk/qgis/python/plugins/plugin_installer/i18n.cpp	2008-11-12 00:26:40 UTC (rev 9625)
@@ -142,7 +142,8 @@
   tr("This plugin is installed, but I can't find it in any enabled repository")
   tr("This plugin is not installed and is seen for the first time")
   tr("This plugin is installed and is newer than its version available in a repository")
-  tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")
+  tr("This plugin is incompatible and probably won't work with your Quantum GIS version")
+  tr("This plugin probably depends on some components missing in your system\nIt has been installed, but can't be loaded")
   tr("not installed", "singular")
   tr("installed", "singular")
   tr("upgradeable", "singular")
@@ -158,8 +159,8 @@
   tr("That's the newest available version")
   tr("installed version")
   tr("There is no version available for download")
-  tr("This plugin seems to be invalid or have unfulfilled dependencies")
-  tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")
+  tr("This plugin is invalid or has unfulfilled dependencies")
+  tr("This plugin is designed for a higher version of Quantum GIS")
   tr("only locally available")
 
  // def treeClicked

Modified: trunk/qgis/python/plugins/plugin_installer/installer_data.py
===================================================================
--- trunk/qgis/python/plugins/plugin_installer/installer_data.py	2008-11-11 15:30:31 UTC (rev 9624)
+++ trunk/qgis/python/plugins/plugin_installer/installer_data.py	2008-11-12 00:26:40 UTC (rev 9625)
@@ -19,6 +19,7 @@
 from PyQt4.QtNetwork import *
 from qgis.core import *
 from unzip import unzip
+from version_compare import compareVersions, normalizeVersion
 
 
 """
@@ -37,7 +38,8 @@
                                 "desc_repo" string,
                                 "desc_local" string,
                                 "author" string,
-                                "status" string,    ("not installed", "installed", "upgradeable", "orphan", "new", "newer", "invalid")
+                                "status" string,      ("not installed", "installed", "upgradeable", "orphan", "new", "newer")
+                                "error" string,       ("", "broken", "incompatible" )
                                 "homepage" string,
                                 "url" string,
                                 "filename" string,
@@ -47,12 +49,12 @@
 """
 
 
-QGIS_VER = 1
 try:
-  if str(QGis.qgisVersion)[0] == "0": 
-    QGIS_VER = 0
+  QGIS_VER = QGis.qgisVersion
+  QGIS_MAJOR_VER = 0
 except:
-  pass
+  QGIS_VER = QGis.QGIS_VERSION
+  QGIS_MAJOR_VER = 1
 
 
 reposGroup = "/Qgis/plugin-repos"
@@ -134,14 +136,14 @@
     for i in self.all().values():
       presentURLs += [str(i["url"])]
     for i in knownRepos:
-      if i[QGIS_VER+1] and presentURLs.count(i[QGIS_VER+1]) == 0:
+      if i[QGIS_MAJOR_VER+1] and presentURLs.count(i[QGIS_MAJOR_VER+1]) == 0:
         settings = QSettings()
         settings.beginGroup(reposGroup)
         repoName = QString(i[0])
         if self.all().has_key(repoName):
           repoName = repoName + "(2)"
         # add to settings
-        settings.setValue(repoName+"/url", QVariant(i[QGIS_VER+1]))
+        settings.setValue(repoName+"/url", QVariant(i[QGIS_MAJOR_VER+1]))
         settings.setValue(repoName+"/enabled", QVariant(True))
 
 
@@ -208,15 +210,15 @@
     settings.beginGroup(reposGroup)
     # first, update the QSettings repositories if needed
     if len(settings.childGroups()) == 0: # add the default repository when there isn't any
-      settings.setValue(knownRepos[0][0]+"/url", QVariant(knownRepos[0][QGIS_VER+1]))
+      settings.setValue(knownRepos[0][0]+"/url", QVariant(knownRepos[0][QGIS_MAJOR_VER+1]))
     else: # else update invalid urls
       for key in settings.childGroups():
         url = settings.value(key+"/url", QVariant()).toString()
         allOk = True
         for repo in knownRepos:
-          if repo[3] == url or repo[4] == url or (repo[QGIS_VER+1] != url and repo[int(not QGIS_VER)+1] == url):
-            if repo[QGIS_VER+1]: #update the URL
-              settings.setValue(key+"/url", QVariant(repo[QGIS_VER+1]))
+          if repo[3] == url or repo[4] == url or (repo[QGIS_MAJOR_VER+1] != url and repo[int(not QGIS_MAJOR_VER)+1] == url):
+            if repo[QGIS_MAJOR_VER+1]: #update the URL
+              settings.setValue(key+"/url", QVariant(repo[QGIS_MAJOR_VER+1]))
               settings.setValue(key+"/valid", QVariant(True))
               allOk = False
             else: # mark as invalid
@@ -299,12 +301,14 @@
             "url"           : pluginNodes.item(i).firstChildElement("download_url").text().trimmed(),
             "filename"      : pluginNodes.item(i).firstChildElement("file_name").text().trimmed(),
             "status"        : "not installed",
+            "error"         : "",
             "version_inst"  : "",
             "repository"    : reposName,
             "localdir"      : name,
             "read-only"     : False}
-          plugins.addPlugin(plugin)
-
+          #if compatible, add the plugin to list
+          if compareVersions(QGIS_VER, pluginNodes.item(i).firstChildElement("qgis_minimum_version").text().trimmed()) < 2:
+            plugins.addPlugin(plugin)
         plugins.workarounds()
         self.mRepositories[reposName]["state"] = 2
       else:
@@ -361,114 +365,13 @@
 
 
   # ----------------------------------------- #
-  def normalizeVersion(self,ver):
-    """ remove the prefix from given version string """
-    if not ver:
-      return QString()
-    if ver.toUpper().left(7) == "VERSION":
-      ver.remove(0,7)
-    elif ver.toUpper().left(4) == "VER.":
-      ver.remove(0,4)
-    if ver[0] == " ":
-      ver.remove(0,1)
-    return ver
-
-
-  # ----------------------------------------- #
-  def compareVersions(self,a,b):
-    """ compare two plugin versions """
-    # -------- #
-    def classify(s):
-      if s in [".","-","_"," "]:
-        return 0
-      try:
-        float(s)
-        return 1
-      except:
-        return 2
-    # -------- #
-    def chop(s):
-      s2 = [s[0]]
-      for i in range(1,len(s)):
-        if classify(s[i]) == 0:
-          pass
-        elif classify(s[i]) == classify(s[i-1]):
-          s2[len(s2)-1] += s[i]
-        else:
-          s2 += [s[i]]
-      return s2
-    # -------- #
-    def compare(s1,s2):
-      # check if the matter is easy solvable:
-      if s1 == s2:
-        return 0
-      if not s1:
-        return 2
-      if not s2:
-        return 1
-      # try to compare as numeric values (but only if the first character is not 0):
-      if s1[0] != '0' and s2[0] != '0':
-        try:
-          if float(s1) == float(s2):
-            return 0
-          elif float(s1) > float(s2):
-            return 1
-          else:
-            return 2
-        except:
-          pass
-      # if the strings aren't numeric or start from 0, compare them as a strings:
-      # but first, set ALPHA < BETA < RC < FINAL < ANYTHING_ELSE
-      if s1 == 'FINAL':
-        s1 = 'Z' + s1
-      elif not s1 in ['ALPHA','BETA','RC']:
-        s1 = 'ZZ' + s1
-      if s2 == 'FINAL':
-        s2 = 'Z' + s2
-      elif not s2 in ['ALPHA','BETA','RC']:
-        s2 = 'ZZ' + s2
-      # the real test:
-      if s1 > s2:
-        return 1
-      else:
-        return 2
-    # -------- #
-    if not a or not b:
-      return 0
-    a = unicode(a).upper()
-    b = unicode(b).upper()
-    if a == b:
-      return 0
-
-    v1 = chop(a)
-    v2 = chop(b)
-    l = len(v1)
-    if l > len(v2):
-      l = len(v2)
-
-    for i in range(l):
-      if compare(v1[i],v2[i]):
-        return compare(v1[i],v2[i])
-
-    if len(v1) > l:
-      return compare(v1[l],u'')
-    if len(v2) > l:
-      return compare(u'',v2[l])
-    # if everything else fails...
-    if unicode(a) > unicode(b):
-      return 1
-    else:
-      return 2
-
-
-  # ----------------------------------------- #
   def addPlugin(self, plugins):
     """ add a plugin (first from given) to the mPlugins dict """
     key = plugins.keys()[0]
     plugin = plugins[key]
-    plugin["version_avail"] = self.normalizeVersion(QString(plugin["version_avail"]))
-    plugin["version_inst"] = self.normalizeVersion(QString(plugin["version_inst"]))
-    if not self.mPlugins.has_key(key) or self.compareVersions(self.mPlugins[key]["version_avail"],plugin["version_avail"]) == 2:
+    plugin["version_avail"] = normalizeVersion(plugin["version_avail"])
+    plugin["version_inst"] = normalizeVersion(plugin["version_inst"])
+    if not self.mPlugins.has_key(key) or compareVersions(self.mPlugins[key]["version_avail"],plugin["version_avail"]) == 2:
       self.mPlugins[key] = plugin # add the plugin if not present yet or if is newer than existing one
 
 
@@ -485,7 +388,7 @@
       path = QgsApplication.pkgDataPath()
     else:
       path = QgsApplication.qgisSettingsDirPath()
-    path = QDir.cleanPath(unicode(path) + "python/plugins/" + key)
+    path = QDir.cleanPath(unicode(path) + "/python/plugins/" + key)
     if not QDir(path).exists():
       return
     try:
@@ -510,15 +413,22 @@
         exec("homepage = %s.homepage()" % key)
       except:
         homepage = ""
-      stat = ""
+      try:
+        exec("qgisMinimumVersion = %s.qgisMinimumVersion()" % key)
+        if compareVersions(QGIS_VER, qgisMinimumVersion) == 2:
+          error = "incompatible"
+        else:
+          error = ""
+      except:
+        error = ""
     except:
       nam   = key
-      stat  = "invalid"
       ver   = ""
       desc  = ""
       auth  = ""
       homepage  = ""
-    normVer = self.normalizeVersion(QString(ver))
+      error = "broken"
+    normVer = normalizeVersion(ver)
     plugin = {
         "name"          : nam,
         "version_inst"  : normVer,
@@ -529,7 +439,8 @@
         "homepage"      : homepage,
         "url"           : path,
         "filename"      : "",
-        "status"        : stat,
+        "status"        : "",
+        "error"         : error,
         "repository"    : "",
         "localdir"      : key,
         "read-only"     : readOnly}
@@ -538,12 +449,11 @@
     else:
       self.mPlugins[key]["localdir"] = plugin["localdir"]
       self.mPlugins[key]["read-only"] = plugin["read-only"]
-      if plugin["status"] == "invalid":
-        self.mPlugins[key]["status"] = plugin["status"]
-      else:
-        self.mPlugins[key]["name"] = plugin["name"] # local name has higher priority, except invalid plugins
-        self.mPlugins[key]["version_inst"] = plugin["version_inst"]
-        self.mPlugins[key]["desc_local"] = plugin["desc_local"]
+      self.mPlugins[key]["error"] = plugin["error"]
+      if plugin["name"]:
+        self.mPlugins[key]["name"] = plugin["name"] # local name has higher priority
+      self.mPlugins[key]["version_inst"] = plugin["version_inst"]
+      self.mPlugins[key]["desc_local"] = plugin["desc_local"]
     # set status
     #
     # installed   available   status
@@ -553,16 +463,16 @@
     # same        same        "installed"
     # less        greater     "upgradeable"
     # greater     less        "newer"
-    # *marked as invalid*     "invalid"
-    if self.mPlugins[key]["status"] == "invalid":
-      pass
+    
+    if not self.mPlugins[key]["version_avail"]:
+      self.mPlugins[key]["status"] = "orphan"
+    elif self.mPlugins[key]["error"] == "broken":
+      self.mPlugins[key]["status"] = "installed"
     elif not self.mPlugins[key]["version_inst"]:
       self.mPlugins[key]["status"] = "not installed"
-    elif not self.mPlugins[key]["version_avail"]:
-      self.mPlugins[key]["status"] = "orphan"
-    elif self.compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
+    elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
       self.mPlugins[key]["status"] = "installed"
-    elif self.compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
+    elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
       self.mPlugins[key]["status"] = "upgradeable"
     else:
       self.mPlugins[key]["status"] = "newer"
@@ -576,12 +486,13 @@
       pluginDir = QDir.cleanPath(unicode(QgsApplication.pkgDataPath()) + "/python/plugins")
       pluginDir = QDir(pluginDir)
       pluginDir.setFilter(QDir.AllDirs)
+      for key in pluginDir.entryList():
+        key = str(key)
+        if not key in [".",".."]:
+          self.updatePlugin(key, True)
     except:
-      return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the system plugin directory")
-    for key in pluginDir.entryList():
-      key = str(key)
-      if not key in [".",".."]:
-        self.updatePlugin(key, True)
+      # return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the system plugin directory")
+      pass # it's not necessary to stop due to this error
     # ...then try to add locally installed ones
     try:
       pluginDir = QDir.cleanPath(unicode(QgsApplication.qgisSettingsDirPath()) + "/python/plugins")

Modified: trunk/qgis/python/plugins/plugin_installer/installer_gui.py
===================================================================
--- trunk/qgis/python/plugins/plugin_installer/installer_gui.py	2008-11-11 15:30:31 UTC (rev 9624)
+++ trunk/qgis/python/plugins/plugin_installer/installer_gui.py	2008-11-12 00:26:40 UTC (rev 9625)
@@ -363,7 +363,7 @@
         return False
     if self.comboFilter2.currentIndex() == 1 and not plugin["status"] in ["not installed","new"]:
       return False
-    if self.comboFilter2.currentIndex() == 2 and not plugin["status"] in ["installed","upgradeable","newer","orphan","invalid"]:
+    if self.comboFilter2.currentIndex() == 2 and not plugin["status"] in ["installed","upgradeable","newer","orphan"]:
       return False
     if self.comboFilter2.currentIndex() == 3 and not plugin["status"] in ["upgradeable","new"]:
       return False
@@ -381,47 +381,63 @@
   # ----------------------------------------- #
   def populatePluginTree(self):
     """ fill up the pluginTree """
-    descrip={"not installed" : self.tr("This plugin is not installed"),
+    statusTips={"not installed" : self.tr("This plugin is not installed"),
             "installed" : self.tr("This plugin is installed"),
             "upgradeable" : self.tr("This plugin is installed, but there is an updated version available"),
             "orphan" : self.tr("This plugin is installed, but I can't find it in any enabled repository"),
             "new" : self.tr("This plugin is not installed and is seen for the first time"),
             "newer" : self.tr("This plugin is installed and is newer than its version available in a repository"),
-            "invalid" : self.tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")}
-    status ={"not installed" : self.tr("not installed", "singular"),
+            "incompatible" : self.tr("This plugin is incompatible and probably won't work with your Quantum GIS version"),
+            "broken" : self.tr("This plugin probably depends on some components missing in your system\nIt has been installed, but can't be loaded")}
+    statuses ={"not installed" : self.tr("not installed", "singular"),
             "installed" : self.tr("installed", "singular"),
             "upgradeable" : self.tr("upgradeable", "singular"),
             "orphan" : self.tr("installed", "singular"),
             "new" : self.tr("new!", "singular"),
             "newer" : self.tr("installed", "singular"),
-            "invalid" : self.tr("invalid", "singular")}
-    order = ["invalid","upgradeable","new","not installed","installed","orphan","newer"]
+            "incompatible" : self.tr("invalid", "singular"),
+            "broken" : self.tr("invalid", "singular")}
+    orderInvalid = ["incompatible","broken"]
+    orderValid = ["upgradeable","new","not installed","installed","orphan","newer"]
     def addItem(p):
       if self.filterCheck(p):
-        statusTip = descrip[p["status"]]
+        statusTip=""
+        if p["error"]:
+          statusTip = statusTips[p["error"]]
+        else:
+          statusTip = statusTips[p["status"]]
         if p["read-only"]:
-          statusTip += "\n" + self.tr("Note that it's an uninsatallable core plugin")
+          statusTip = statusTip + "\n" + self.tr("Note that it's an uninsatallable core plugin")
+        installedVersion = p["version_inst"]
+        if not installedVersion:
+          installedVersion = "?"
+        availableVersion = p["version_avail"]
+        if not availableVersion:
+          availableVersion = "?"
         if p["status"] == "upgradeable":
-          ver = p["version_inst"] + " -> " + p["version_avail"]
+          ver = installedVersion + " -> " + availableVersion
         elif p["status"] ==  "newer":
-          ver = p["version_inst"] + " (" + p["version_avail"] + ")"
-        elif p["status"] in ["not installed", "new", "invalid"]:
-          ver = p["version_avail"]
+          ver = installedVersion + " (" + availableVersion + ")"
+        elif p["status"] in ["not installed", "new"]:
+          ver = availableVersion
         else:
-          ver = p["version_inst"]
+          ver = installedVersion
         if p["status"] in ["upgradeable","newer"]:
-          verTip = self.tr("installed version") + ": " + p["version_inst"] + "\n" + self.tr("available version") + ": " + p["version_avail"]
+          verTip = self.tr("installed version") + ": " + installedVersion + "\n" + self.tr("available version") + ": " + availableVersion
         elif p["status"] in ["not installed", "new"]:
-          verTip = self.tr("available version") + ": " + p["version_avail"]
+          verTip = self.tr("available version") + ": " + availableVersion
         elif p["status"] == "installed":
-          verTip = self.tr("installed version") + ": " + p["version_inst"] + "\n" + self.tr("That's the newest available version")
+          verTip = self.tr("installed version") + ": " + installedVersion + "\n" + self.tr("That's the newest available version")
         elif p["status"] == "orphan":
-          verTip = self.tr("installed version") + ": " + p["version_inst"] + "\n" + self.tr("There is no version available for download")
+          verTip = self.tr("installed version") + ": " + installedVersion + "\n" + self.tr("There is no version available for download")
         else:
           verTip = ""
-        if p["status"] == "invalid":
-          desc = self.tr("This plugin seems to be invalid or have unfulfilled dependencies")
-          descTip = self.tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")
+        if p["error"] == "broken":
+          desc = self.tr("This plugin is invalid or has unfulfilled dependencies")
+          descTip = statusTips[p["error"]]
+        elif p["error"] == "incompatible":
+          desc = self.tr("This plugin is designed for a higher version of Quantum GIS")
+          descTip = statusTips[p["error"]]
         else:
           desc = p["desc_local"]
           descTip = p["desc_repo"]
@@ -432,7 +448,10 @@
         else:
           repository = p["repository"]
         a = QTreeWidgetItem(self.treePlugins)
-        a.setText(0,status[p["status"]])
+        if p["error"]:
+          a.setText(0,statuses[p["error"]])
+        else:
+          a.setText(0,statuses[p["status"]])
         a.setToolTip(0,statusTip)
         a.setText(1,p["name"])
         a.setText(2,ver)
@@ -448,9 +467,9 @@
         a.setToolTip(5,p["url"])
         # set fonts and colours
         for i in [0,1,2,3,4,5]:
-          if p["status"] == "invalid":
+          if p["error"]:
             a.setForeground(i,QBrush(QColor(Qt.red)))
-          if p["status"] in ["new","upgradeable","invalid"]:
+          if p["status"] in ["new","upgradeable"] or p["error"]:
             font = QFont()
             font.setWeight(QFont.Bold)
             a.setFont(i,font)
@@ -458,10 +477,14 @@
     if not plugins.all():
       return
     self.treePlugins.clear()
-    for i in order:
+    for i in orderInvalid:
       for p in plugins.all().values():
-        if p["status"] == i:
+        if p["error"] == i:
           addItem(p)
+    for i in orderValid:
+      for p in plugins.all().values():
+        if p["status"] == i and not p["error"]:
+          addItem(p)
     # resize the columns
     for i in [0,1,2,3,4,5]:
       self.treePlugins.resizeColumnToContents(i)
@@ -482,8 +505,7 @@
             "upgradeable":(True,True,self.tr("Upgrade plugin")),
             "orphan":(False,True,self.tr("Install/upgrade plugin")),
             "new":(True, False,self.tr("Install plugin")),
-            "newer":(True,True,self.tr("Downgrade plugin")),
-            "invalid":(False,True,self.tr("Reinstall plugin"))}
+            "newer":(True,True,self.tr("Downgrade plugin"))}
     self.buttonInstall.setEnabled(False)
     self.buttonInstall.setText(self.tr("Install/upgrade plugin"))
     self.buttonUninstall.setEnabled(False)
@@ -557,7 +579,7 @@
     if not plugin:
       return
     warning = self.tr("Are you sure you want to uninstall the following plugin?") + "\n" + plugin["name"]
-    if plugin["status"] == "orphan":
+    if plugin["status"] == "orphan" and not plugin["error"]:
       warning += "\n\n"+self.tr("Warning: this plugin isn't available in any accessible repository!")
     if QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), warning , QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
       return

Modified: trunk/qgis/python/plugins/plugin_installer/installer_plugin.py
===================================================================
--- trunk/qgis/python/plugins/plugin_installer/installer_plugin.py	2008-11-11 15:30:31 UTC (rev 9624)
+++ trunk/qgis/python/plugins/plugin_installer/installer_plugin.py	2008-11-12 00:26:40 UTC (rev 9625)
@@ -26,7 +26,7 @@
   # ----------------------------------------- #
   def __init__(self, iface):
     self.iface = iface
-    if QGIS_VER: # new plugin API
+    if QGIS_MAJOR_VER: # new plugin API
       self.mainWindow = self.iface.mainWindow
     else: # old plugin API
       self.mainWindow = self.iface.getMainWindow
@@ -37,7 +37,7 @@
     self.action = QAction(QIcon(":/plugins/installer/plugin_installer.png"), QCoreApplication.translate("QgsPluginInstaller","Fetch Python Plugins..."), self.mainWindow())
     self.action.setWhatsThis(QCoreApplication.translate("QgsPluginInstaller","Install more plugins from remote repositories"))
     self.action.setStatusTip(QCoreApplication.translate("QgsPluginInstaller","Install more plugins from remote repositories"))
-    if QGIS_VER: # new plugin API
+    if QGIS_MAJOR_VER: # new plugin API
       nextAction = self.iface.actionManagePlugins()
       self.iface.pluginMenu().insertAction(nextAction,self.action)
     else: # old plugin API

Added: trunk/qgis/python/plugins/plugin_installer/version_compare.py
===================================================================
--- trunk/qgis/python/plugins/plugin_installer/version_compare.py	                        (rev 0)
+++ trunk/qgis/python/plugins/plugin_installer/version_compare.py	2008-11-12 00:26:40 UTC (rev 9625)
@@ -0,0 +1,143 @@
+"""
+This is a Python module to compare version numbers. It's case insensitive
+and recognizes all major notations, prefixes (ver. and version), delimiters
+(. - and _) and suffixes (alpha, beta, rc, preview and final).
+
+Usage: compareVersions(version1, version2)
+
+The function accepts arguments of any type convertable to unicode string
+and returns integer value:
+0 - the versions are equal
+1 - version 1 is higher
+2 - version 2 is higher
+
+-----------------------------------------------------------------------------
+HOW IT WORKS...
+First, both arguments are converted to uppercase unicode and stripped of
+'VERSION' or 'VER.' prefix. Then they are chopped into a list of particular
+numeric and alphabetic elements. The dots, dashes and underlines are recognized
+as delimiters. Also numbers and non numbers are separated. See example below:
+
+'Ver 0.03-120_rc7foo' is converted to ['0','03','120','RC','7','FOO']
+
+Then every pair of elements, from left to right, is compared as string
+or as number to provide the best result (you know, 11>9 but also '03'>'007').
+The comparing stops when one of elements is greater. If comparing achieves
+the end of the shorter list and the matter is still unresolved, the longer
+list is usually recognized as higher, except following suffixes:
+ALPHA, BETA, RC and PREVIEW which make the version number lower.
+
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2008-11-11 Borys Jurgiel                                *
+ *                                                                         *
+ ***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+"""
+
+# ------------------------------------------------------------------------ #
+def normalizeVersion(s):
+  """ remove possible prefix from given string and convert to uppercase """
+  if not s:
+    return unicode()
+  s = unicode(s).upper()
+  s = s.replace('VERSION','')
+  s = s.replace('VER.','')
+  s = s.replace('VER','')
+  s = s.lstrip()
+  return s
+
+
+# ------------------------------------------------------------------------ #
+def classifyCharacter(c):
+  """ return 0 for delimiter, 1 for digit and 2 for alphabetic character """
+  if c in [".","-","_"," "]:
+    return 0
+  if c.isdigit():
+    return 1
+  else:
+    return 2
+
+
+# ------------------------------------------------------------------------ #
+def chopString(s):
+  """ convert string to list of numbers and words """
+  l = [s[0]]
+  for i in range(1,len(s)):
+    if classifyCharacter(s[i]) == 0:
+      pass
+    elif classifyCharacter(s[i]) == classifyCharacter(s[i-1]):
+      l[len(l)-1] += s[i]
+    else:
+      l += [s[i]]
+  return l
+
+
+# ------------------------------------------------------------------------ #
+def compareElements(s1,s2):
+  """ compare two particular elements """
+  # check if the matter is easy solvable:
+  if s1 == s2:
+    return 0
+  # try to compare as numeric values (but only if the first character is not 0):
+  if s1 and s2 and s1.isnumeric() and s2.isnumeric() and s1[0] != '0' and s2[0] != '0':
+    if float(s1) == float(s2):
+      return 0
+    elif float(s1) > float(s2):
+      return 1
+    else:
+      return 2
+  # if the strings aren't numeric or start from 0, compare them as a strings:
+  # but first, set ALPHA < BETA < PREVIEW < RC < FINAL < [NOTHING] < [ANYTHING_ELSE]
+  if s1 == 'FINAL':
+    s1 = 'Z' + s1
+  elif not s1 in ['ALPHA','BETA','PREVIEW','RC']:
+    s1 = 'ZZ' + s1
+  if s2 == 'FINAL':
+    s2 = 'Z' + s2
+  elif not s2 in ['ALPHA','BETA','PREVIEW','RC']:
+    s2 = 'ZZ' + s2
+  # the final test:
+  if s1 > s2:
+    return 1
+  else:
+    return 2
+
+
+# ------------------------------------------------------------------------ #
+def compareVersions(a,b):
+  """ Compare two version numbers. Return 0 if a==b or error, 1 if a<b and 2 if b>a """
+  if not a or not b:
+    return 0
+  a = normalizeVersion(a)
+  b = normalizeVersion(b)
+  if a == b:
+    return 0
+  # convert the strings to the lists
+  v1 = chopString(a)
+  v2 = chopString(b)
+  # set the shorter string as a base
+  l = len(v1)
+  if l > len(v2):
+    l = len(v2)
+  # try to determine within the common length
+  for i in range(l):
+    if compareElements(v1[i],v2[i]):
+      return compareElements(v1[i],v2[i])
+  # if the lists are identical till the end of the shorther string, try to compare the odd tail
+  #with the simple space (because the 'alpha', 'beta', 'preview' and 'rc' are LESS then nothing)
+  if len(v1) > l:
+    return compareElements(v1[l],u' ')
+  if len(v2) > l:
+    return compareElements(u' ',v2[l])
+  # if everything else fails...
+  if a > b:
+    return 1
+  else:
+    return 2



More information about the QGIS-commit mailing list