Skip to content

Commit 10c234c

Browse files
author
borysiasty
committed
Plugin Installer update: plugin compatibility checking
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@9625 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 83cf928 commit 10c234c

File tree

6 files changed

+251
-174
lines changed

6 files changed

+251
-174
lines changed

python/plugins/plugin_installer/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def author_name():
2020
return "perrygeo, borysiasty"
2121

2222
def version():
23-
return "Version 0.9"
23+
return "Version 0.9.1"
2424

2525
def classFactory(iface):
2626
from installer_plugin import InstallerPlugin

python/plugins/plugin_installer/i18n.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ QgsPluginInstallerDialog::foo()
142142
tr("This plugin is installed, but I can't find it in any enabled repository")
143143
tr("This plugin is not installed and is seen for the first time")
144144
tr("This plugin is installed and is newer than its version available in a repository")
145-
tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")
145+
tr("This plugin is incompatible and probably won't work with your Quantum GIS version")
146+
tr("This plugin probably depends on some components missing in your system\nIt has been installed, but can't be loaded")
146147
tr("not installed", "singular")
147148
tr("installed", "singular")
148149
tr("upgradeable", "singular")
@@ -158,8 +159,8 @@ QgsPluginInstallerDialog::foo()
158159
tr("That's the newest available version")
159160
tr("installed version")
160161
tr("There is no version available for download")
161-
tr("This plugin seems to be invalid or have unfulfilled dependencies")
162-
tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")
162+
tr("This plugin is invalid or has unfulfilled dependencies")
163+
tr("This plugin is designed for a higher version of Quantum GIS")
163164
tr("only locally available")
164165

165166
// def treeClicked

python/plugins/plugin_installer/installer_data.py

+51-140
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from PyQt4.QtNetwork import *
2020
from qgis.core import *
2121
from unzip import unzip
22+
from version_compare import compareVersions, normalizeVersion
2223

2324

2425
"""
@@ -37,7 +38,8 @@
3738
"desc_repo" string,
3839
"desc_local" string,
3940
"author" string,
40-
"status" string, ("not installed", "installed", "upgradeable", "orphan", "new", "newer", "invalid")
41+
"status" string, ("not installed", "installed", "upgradeable", "orphan", "new", "newer")
42+
"error" string, ("", "broken", "incompatible" )
4143
"homepage" string,
4244
"url" string,
4345
"filename" string,
@@ -47,12 +49,12 @@
4749
"""
4850

4951

50-
QGIS_VER = 1
5152
try:
52-
if str(QGis.qgisVersion)[0] == "0":
53-
QGIS_VER = 0
53+
QGIS_VER = QGis.qgisVersion
54+
QGIS_MAJOR_VER = 0
5455
except:
55-
pass
56+
QGIS_VER = QGis.QGIS_VERSION
57+
QGIS_MAJOR_VER = 1
5658

5759

5860
reposGroup = "/Qgis/plugin-repos"
@@ -134,14 +136,14 @@ def addKnownRepos(self):
134136
for i in self.all().values():
135137
presentURLs += [str(i["url"])]
136138
for i in knownRepos:
137-
if i[QGIS_VER+1] and presentURLs.count(i[QGIS_VER+1]) == 0:
139+
if i[QGIS_MAJOR_VER+1] and presentURLs.count(i[QGIS_MAJOR_VER+1]) == 0:
138140
settings = QSettings()
139141
settings.beginGroup(reposGroup)
140142
repoName = QString(i[0])
141143
if self.all().has_key(repoName):
142144
repoName = repoName + "(2)"
143145
# add to settings
144-
settings.setValue(repoName+"/url", QVariant(i[QGIS_VER+1]))
146+
settings.setValue(repoName+"/url", QVariant(i[QGIS_MAJOR_VER+1]))
145147
settings.setValue(repoName+"/enabled", QVariant(True))
146148

147149

@@ -208,15 +210,15 @@ def load(self):
208210
settings.beginGroup(reposGroup)
209211
# first, update the QSettings repositories if needed
210212
if len(settings.childGroups()) == 0: # add the default repository when there isn't any
211-
settings.setValue(knownRepos[0][0]+"/url", QVariant(knownRepos[0][QGIS_VER+1]))
213+
settings.setValue(knownRepos[0][0]+"/url", QVariant(knownRepos[0][QGIS_MAJOR_VER+1]))
212214
else: # else update invalid urls
213215
for key in settings.childGroups():
214216
url = settings.value(key+"/url", QVariant()).toString()
215217
allOk = True
216218
for repo in knownRepos:
217-
if repo[3] == url or repo[4] == url or (repo[QGIS_VER+1] != url and repo[int(not QGIS_VER)+1] == url):
218-
if repo[QGIS_VER+1]: #update the URL
219-
settings.setValue(key+"/url", QVariant(repo[QGIS_VER+1]))
219+
if repo[3] == url or repo[4] == url or (repo[QGIS_MAJOR_VER+1] != url and repo[int(not QGIS_MAJOR_VER)+1] == url):
220+
if repo[QGIS_MAJOR_VER+1]: #update the URL
221+
settings.setValue(key+"/url", QVariant(repo[QGIS_MAJOR_VER+1]))
220222
settings.setValue(key+"/valid", QVariant(True))
221223
allOk = False
222224
else: # mark as invalid
@@ -299,12 +301,14 @@ def xmlDownloaded(self,nr,state):
299301
"url" : pluginNodes.item(i).firstChildElement("download_url").text().trimmed(),
300302
"filename" : pluginNodes.item(i).firstChildElement("file_name").text().trimmed(),
301303
"status" : "not installed",
304+
"error" : "",
302305
"version_inst" : "",
303306
"repository" : reposName,
304307
"localdir" : name,
305308
"read-only" : False}
306-
plugins.addPlugin(plugin)
307-
309+
#if compatible, add the plugin to list
310+
if compareVersions(QGIS_VER, pluginNodes.item(i).firstChildElement("qgis_minimum_version").text().trimmed()) < 2:
311+
plugins.addPlugin(plugin)
308312
plugins.workarounds()
309313
self.mRepositories[reposName]["state"] = 2
310314
else:
@@ -360,115 +364,14 @@ def clear(self):
360364
self.mPlugins = {}
361365

362366

363-
# ----------------------------------------- #
364-
def normalizeVersion(self,ver):
365-
""" remove the prefix from given version string """
366-
if not ver:
367-
return QString()
368-
if ver.toUpper().left(7) == "VERSION":
369-
ver.remove(0,7)
370-
elif ver.toUpper().left(4) == "VER.":
371-
ver.remove(0,4)
372-
if ver[0] == " ":
373-
ver.remove(0,1)
374-
return ver
375-
376-
377-
# ----------------------------------------- #
378-
def compareVersions(self,a,b):
379-
""" compare two plugin versions """
380-
# -------- #
381-
def classify(s):
382-
if s in [".","-","_"," "]:
383-
return 0
384-
try:
385-
float(s)
386-
return 1
387-
except:
388-
return 2
389-
# -------- #
390-
def chop(s):
391-
s2 = [s[0]]
392-
for i in range(1,len(s)):
393-
if classify(s[i]) == 0:
394-
pass
395-
elif classify(s[i]) == classify(s[i-1]):
396-
s2[len(s2)-1] += s[i]
397-
else:
398-
s2 += [s[i]]
399-
return s2
400-
# -------- #
401-
def compare(s1,s2):
402-
# check if the matter is easy solvable:
403-
if s1 == s2:
404-
return 0
405-
if not s1:
406-
return 2
407-
if not s2:
408-
return 1
409-
# try to compare as numeric values (but only if the first character is not 0):
410-
if s1[0] != '0' and s2[0] != '0':
411-
try:
412-
if float(s1) == float(s2):
413-
return 0
414-
elif float(s1) > float(s2):
415-
return 1
416-
else:
417-
return 2
418-
except:
419-
pass
420-
# if the strings aren't numeric or start from 0, compare them as a strings:
421-
# but first, set ALPHA < BETA < RC < FINAL < ANYTHING_ELSE
422-
if s1 == 'FINAL':
423-
s1 = 'Z' + s1
424-
elif not s1 in ['ALPHA','BETA','RC']:
425-
s1 = 'ZZ' + s1
426-
if s2 == 'FINAL':
427-
s2 = 'Z' + s2
428-
elif not s2 in ['ALPHA','BETA','RC']:
429-
s2 = 'ZZ' + s2
430-
# the real test:
431-
if s1 > s2:
432-
return 1
433-
else:
434-
return 2
435-
# -------- #
436-
if not a or not b:
437-
return 0
438-
a = unicode(a).upper()
439-
b = unicode(b).upper()
440-
if a == b:
441-
return 0
442-
443-
v1 = chop(a)
444-
v2 = chop(b)
445-
l = len(v1)
446-
if l > len(v2):
447-
l = len(v2)
448-
449-
for i in range(l):
450-
if compare(v1[i],v2[i]):
451-
return compare(v1[i],v2[i])
452-
453-
if len(v1) > l:
454-
return compare(v1[l],u'')
455-
if len(v2) > l:
456-
return compare(u'',v2[l])
457-
# if everything else fails...
458-
if unicode(a) > unicode(b):
459-
return 1
460-
else:
461-
return 2
462-
463-
464367
# ----------------------------------------- #
465368
def addPlugin(self, plugins):
466369
""" add a plugin (first from given) to the mPlugins dict """
467370
key = plugins.keys()[0]
468371
plugin = plugins[key]
469-
plugin["version_avail"] = self.normalizeVersion(QString(plugin["version_avail"]))
470-
plugin["version_inst"] = self.normalizeVersion(QString(plugin["version_inst"]))
471-
if not self.mPlugins.has_key(key) or self.compareVersions(self.mPlugins[key]["version_avail"],plugin["version_avail"]) == 2:
372+
plugin["version_avail"] = normalizeVersion(plugin["version_avail"])
373+
plugin["version_inst"] = normalizeVersion(plugin["version_inst"])
374+
if not self.mPlugins.has_key(key) or compareVersions(self.mPlugins[key]["version_avail"],plugin["version_avail"]) == 2:
472375
self.mPlugins[key] = plugin # add the plugin if not present yet or if is newer than existing one
473376

474377

@@ -485,7 +388,7 @@ def updatePlugin(self, key, readOnly):
485388
path = QgsApplication.pkgDataPath()
486389
else:
487390
path = QgsApplication.qgisSettingsDirPath()
488-
path = QDir.cleanPath(unicode(path) + "python/plugins/" + key)
391+
path = QDir.cleanPath(unicode(path) + "/python/plugins/" + key)
489392
if not QDir(path).exists():
490393
return
491394
try:
@@ -510,15 +413,22 @@ def updatePlugin(self, key, readOnly):
510413
exec("homepage = %s.homepage()" % key)
511414
except:
512415
homepage = ""
513-
stat = ""
416+
try:
417+
exec("qgisMinimumVersion = %s.qgisMinimumVersion()" % key)
418+
if compareVersions(QGIS_VER, qgisMinimumVersion) == 2:
419+
error = "incompatible"
420+
else:
421+
error = ""
422+
except:
423+
error = ""
514424
except:
515425
nam = key
516-
stat = "invalid"
517426
ver = ""
518427
desc = ""
519428
auth = ""
520429
homepage = ""
521-
normVer = self.normalizeVersion(QString(ver))
430+
error = "broken"
431+
normVer = normalizeVersion(ver)
522432
plugin = {
523433
"name" : nam,
524434
"version_inst" : normVer,
@@ -529,7 +439,8 @@ def updatePlugin(self, key, readOnly):
529439
"homepage" : homepage,
530440
"url" : path,
531441
"filename" : "",
532-
"status" : stat,
442+
"status" : "",
443+
"error" : error,
533444
"repository" : "",
534445
"localdir" : key,
535446
"read-only" : readOnly}
@@ -538,12 +449,11 @@ def updatePlugin(self, key, readOnly):
538449
else:
539450
self.mPlugins[key]["localdir"] = plugin["localdir"]
540451
self.mPlugins[key]["read-only"] = plugin["read-only"]
541-
if plugin["status"] == "invalid":
542-
self.mPlugins[key]["status"] = plugin["status"]
543-
else:
544-
self.mPlugins[key]["name"] = plugin["name"] # local name has higher priority, except invalid plugins
545-
self.mPlugins[key]["version_inst"] = plugin["version_inst"]
546-
self.mPlugins[key]["desc_local"] = plugin["desc_local"]
452+
self.mPlugins[key]["error"] = plugin["error"]
453+
if plugin["name"]:
454+
self.mPlugins[key]["name"] = plugin["name"] # local name has higher priority
455+
self.mPlugins[key]["version_inst"] = plugin["version_inst"]
456+
self.mPlugins[key]["desc_local"] = plugin["desc_local"]
547457
# set status
548458
#
549459
# installed available status
@@ -553,16 +463,16 @@ def updatePlugin(self, key, readOnly):
553463
# same same "installed"
554464
# less greater "upgradeable"
555465
# greater less "newer"
556-
# *marked as invalid* "invalid"
557-
if self.mPlugins[key]["status"] == "invalid":
558-
pass
466+
467+
if not self.mPlugins[key]["version_avail"]:
468+
self.mPlugins[key]["status"] = "orphan"
469+
elif self.mPlugins[key]["error"] == "broken":
470+
self.mPlugins[key]["status"] = "installed"
559471
elif not self.mPlugins[key]["version_inst"]:
560472
self.mPlugins[key]["status"] = "not installed"
561-
elif not self.mPlugins[key]["version_avail"]:
562-
self.mPlugins[key]["status"] = "orphan"
563-
elif self.compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
473+
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
564474
self.mPlugins[key]["status"] = "installed"
565-
elif self.compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
475+
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
566476
self.mPlugins[key]["status"] = "upgradeable"
567477
else:
568478
self.mPlugins[key]["status"] = "newer"
@@ -576,12 +486,13 @@ def getAllInstalled(self):
576486
pluginDir = QDir.cleanPath(unicode(QgsApplication.pkgDataPath()) + "/python/plugins")
577487
pluginDir = QDir(pluginDir)
578488
pluginDir.setFilter(QDir.AllDirs)
489+
for key in pluginDir.entryList():
490+
key = str(key)
491+
if not key in [".",".."]:
492+
self.updatePlugin(key, True)
579493
except:
580-
return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the system plugin directory")
581-
for key in pluginDir.entryList():
582-
key = str(key)
583-
if not key in [".",".."]:
584-
self.updatePlugin(key, True)
494+
# return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the system plugin directory")
495+
pass # it's not necessary to stop due to this error
585496
# ...then try to add locally installed ones
586497
try:
587498
pluginDir = QDir.cleanPath(unicode(QgsApplication.qgisSettingsDirPath()) + "/python/plugins")

0 commit comments

Comments
 (0)