Skip to content

Commit 5f9d23c

Browse files
author
borysiasty
committed
Plugin Installer update: cleaning and smarter error handling
git-svn-id: http://svn.osgeo.org/qgis/trunk@9634 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent bf87209 commit 5f9d23c

File tree

4 files changed

+138
-71
lines changed

4 files changed

+138
-71
lines changed

python/plugins/plugin_installer/__init__.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@
1313
def name():
1414
return "Plugin Installer"
1515

16+
def version():
17+
return "Version 0.9.2"
18+
1619
def description():
1720
return "Downloads and installs QGIS python plugins"
1821

19-
def author_name():
22+
def qgisMinimumVersion():
23+
return "0.9"
24+
25+
def authorName():
2026
return "perrygeo, borysiasty"
2127

22-
def version():
23-
return "Version 0.9.1"
28+
def homepage():
29+
return "http://bwj.aster.net.pl/qgis/"
2430

2531
def classFactory(iface):
2632
from installer_plugin import InstallerPlugin

python/plugins/plugin_installer/i18n.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,10 @@ QgsPluginInstallerDialog::foo()
141141
tr("This plugin is installed, but I can't find it in any enabled repository")
142142
tr("This plugin is not installed and is seen for the first time")
143143
tr("This plugin is installed and is newer than its version available in a repository")
144-
tr("This plugin is incompatible and probably won't work with your Quantum GIS version")
145-
tr("This plugin probably depends on some components missing in your system\nIt has been installed, but can't be loaded")
144+
tr("This plugin is incompatible with your Quantum GIS version and probably won't work")
145+
tr("The Python module is missing on your system.\nFor more information, please visit its homepage")
146+
tr("This plugin seems to be broken\nIt has been installed, but can't be loaded")
147+
146148
tr("not installed", "singular")
147149
tr("installed", "singular")
148150
tr("upgradeable", "singular")
@@ -158,8 +160,9 @@ QgsPluginInstallerDialog::foo()
158160
tr("That's the newest available version")
159161
tr("installed version")
160162
tr("There is no version available for download")
161-
tr("This plugin is invalid or has unfulfilled dependencies")
162-
tr("This plugin is designed for a higher version of Quantum GIS")
163+
tr("This plugin is broken")
164+
tr("This plugin requires a newer version of Quantum GIS")
165+
tr("This plugin requires a missing module")
163166
tr("only locally available")
164167

165168
// def treeClicked
@@ -180,8 +183,11 @@ QgsPluginInstallerDialog::foo()
180183
tr("The plugin seems to have been installed but I don't know where. Probably the plugin package contained a wrong named directory.\nPlease search the list of installed plugins. I'm nearly sure you'll find the plugin there, but I just can't determine which of them it is. It also means that I won't be able to determine if this plugin is installed and inform you about available updates. However the plugin may work. Please contact the plugin author and submit this issue.")
181184
tr("Plugin installed successfully")
182185
tr("Python plugin installed.\nYou have to enable it in the Plugin Manager.")
183-
tr("Plugin installed successfully")
186+
tr("Plugin reinstalled successfully")
184187
tr("Python plugin reinstalled.\nYou have to restart Quantum GIS to reload it.")
188+
tr("The plugin is designed for a newer version of Quantum GIS. The minimum required version is:")
189+
tr("The plugin depends on some components missing on your system. Please install the following Python module:")
190+
tr("The plugin is broken. Python said:")
185191
tr("Plugin uninstall failed")
186192

187193
// def uninstallPlugin

python/plugins/plugin_installer/installer_data.py

+45-21
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"desc_local" string,
4040
"author" string,
4141
"status" string, ("not installed", "installed", "upgradeable", "orphan", "new", "newer")
42-
"error" string, ("", "broken", "incompatible" )
42+
"error" string, ("", "broken", "incompatible", "dependent")
43+
"error_details" string,
4344
"homepage" string,
4445
"url" string,
4546
"filename" string,
@@ -51,7 +52,10 @@
5152

5253
try:
5354
QGIS_VER = QGis.qgisVersion
54-
QGIS_MAJOR_VER = 0
55+
if QGIS_VER[0] == "1":
56+
QGIS_MAJOR_VER = 1
57+
else:
58+
QGIS_MAJOR_VER = 0
5559
except:
5660
QGIS_VER = QGis.QGIS_VERSION
5761
QGIS_MAJOR_VER = 1
@@ -302,6 +306,7 @@ def xmlDownloaded(self,nr,state):
302306
"filename" : pluginNodes.item(i).firstChildElement("file_name").text().trimmed(),
303307
"status" : "not installed",
304308
"error" : "",
309+
"error_details" : "",
305310
"version_inst" : "",
306311
"repository" : reposName,
307312
"localdir" : name,
@@ -391,47 +396,63 @@ def updatePlugin(self, key, readOnly):
391396
path = QDir.cleanPath(unicode(path) + "/python/plugins/" + key)
392397
if not QDir(path).exists():
393398
return
399+
nam = ""
400+
ver = ""
401+
desc = ""
402+
auth = ""
403+
homepage = ""
404+
error = ""
405+
errorDetails = ""
394406
try:
395407
exec("import "+ key)
396408
try:
397409
exec("nam = %s.name()" % key)
398410
except:
399-
nam = ""
411+
pass
400412
try:
401413
exec("ver = %s.version()" % key)
402414
except:
403-
ver = ""
415+
pass
404416
try:
405417
exec("desc = %s.description()" % key)
406418
except:
407-
desc = ""
419+
pass
408420
try:
409-
exec("auth = %s.author_name()" % key)
421+
exec("auth = %s.authorName()" % key)
410422
except:
411-
auth = ""
423+
pass
412424
try:
413425
exec("homepage = %s.homepage()" % key)
414426
except:
415-
homepage = ""
427+
pass
416428
try:
417429
exec("qgisMinimumVersion = %s.qgisMinimumVersion()" % key)
418430
if compareVersions(QGIS_VER, qgisMinimumVersion) == 2:
419431
error = "incompatible"
420-
else:
421-
error = ""
432+
errorDetails = qgisMinimumVersion
422433
except:
423-
error = ""
424-
except:
425-
nam = key
426-
ver = ""
427-
desc = ""
428-
auth = ""
429-
homepage = ""
434+
pass
435+
#try:
436+
# exec ("%s.classFactory(QgisInterface)" % key)
437+
#except Exception, error:
438+
# error = error.message
439+
except Exception, error:
440+
error = error.message
441+
442+
if not nam:
443+
nam = key
444+
if error[:16] == "No module named ":
445+
mona = error.replace("No module named ","")
446+
if mona != key:
447+
error = "dependent"
448+
errorDetails = mona
449+
if not error in ["", "dependent", "incompatible"]:
450+
errorDetails = error
430451
error = "broken"
431-
normVer = normalizeVersion(ver)
452+
432453
plugin = {
433454
"name" : nam,
434-
"version_inst" : normVer,
455+
"version_inst" : normalizeVersion(ver),
435456
"version_avail" : "",
436457
"desc_local" : desc,
437458
"desc_repo" : "",
@@ -441,16 +462,19 @@ def updatePlugin(self, key, readOnly):
441462
"filename" : "",
442463
"status" : "",
443464
"error" : error,
465+
"error_details" : errorDetails,
444466
"repository" : "",
445467
"localdir" : key,
446468
"read-only" : readOnly}
469+
447470
if not self.mPlugins.has_key(key):
448471
self.mPlugins[key] = plugin # just add a new plugin
449472
else:
450473
self.mPlugins[key]["localdir"] = plugin["localdir"]
451474
self.mPlugins[key]["read-only"] = plugin["read-only"]
452475
self.mPlugins[key]["error"] = plugin["error"]
453-
if plugin["name"]:
476+
self.mPlugins[key]["error_details"] = plugin["error_details"]
477+
if plugin["name"] and plugin["name"] != key:
454478
self.mPlugins[key]["name"] = plugin["name"] # local name has higher priority
455479
self.mPlugins[key]["version_inst"] = plugin["version_inst"]
456480
self.mPlugins[key]["desc_local"] = plugin["desc_local"]
@@ -465,7 +489,7 @@ def updatePlugin(self, key, readOnly):
465489
# greater less "newer"
466490
if not self.mPlugins[key]["version_avail"]:
467491
self.mPlugins[key]["status"] = "orphan"
468-
elif self.mPlugins[key]["error"] == "broken":
492+
elif self.mPlugins[key]["error"] in ["broken","dependent"]:
469493
self.mPlugins[key]["status"] = "installed"
470494
elif not self.mPlugins[key]["version_inst"]:
471495
self.mPlugins[key]["status"] = "not installed"

python/plugins/plugin_installer/installer_gui.py

+73-42
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ def abort(self):
227227
self.http.abort()
228228
self.mResult = self.tr("Aborted by user")
229229
self.reject()
230-
# --- /class QgsPluginInstallerPluginErrorDialog ------------------------------------------------------------- #
230+
# --- /class QgsPluginInstallerInstallingDialog ------------------------------------------------------------- #
231231

232232

233233

@@ -248,7 +248,6 @@ def __init__(self, parent, errorMessage):
248248

249249

250250

251-
252251
# --- class QgsPluginInstallerDialog ------------------------------------------------------------------------- #
253252
class QgsPluginInstallerDialog(QDialog, Ui_QgsPluginInstallerDialogBase):
254253
# ----------------------------------------- #
@@ -390,17 +389,19 @@ def populatePluginTree(self):
390389
"orphan" : self.tr("This plugin is installed, but I can't find it in any enabled repository"),
391390
"new" : self.tr("This plugin is not installed and is seen for the first time"),
392391
"newer" : self.tr("This plugin is installed and is newer than its version available in a repository"),
393-
"incompatible" : self.tr("This plugin is incompatible and probably won't work with your Quantum GIS version"),
394-
"broken" : self.tr("This plugin probably depends on some components missing in your system\nIt has been installed, but can't be loaded")}
392+
"incompatible" : self.tr("This plugin is incompatible with your Quantum GIS version and probably won't work"),
393+
"dependent" : self.tr("The Python module is missing on your system.\nFor more information, please visit its homepage"),
394+
"broken" : self.tr("This plugin seems to be broken\nIt has been installed, but can't be loaded")}
395395
statuses ={"not installed" : self.tr("not installed", "singular"),
396396
"installed" : self.tr("installed", "singular"),
397397
"upgradeable" : self.tr("upgradeable", "singular"),
398398
"orphan" : self.tr("installed", "singular"),
399399
"new" : self.tr("new!", "singular"),
400400
"newer" : self.tr("installed", "singular"),
401401
"incompatible" : self.tr("invalid", "singular"),
402+
"dependent" : self.tr("invalid", "singular"),
402403
"broken" : self.tr("invalid", "singular")}
403-
orderInvalid = ["incompatible","broken"]
404+
orderInvalid = ["incompatible","broken","dependent"]
404405
orderValid = ["upgradeable","new","not installed","installed","orphan","newer"]
405406
def addItem(p):
406407
if self.filterCheck(p):
@@ -436,10 +437,13 @@ def addItem(p):
436437
else:
437438
verTip = ""
438439
if p["error"] == "broken":
439-
desc = self.tr("This plugin is invalid or has unfulfilled dependencies")
440+
desc = self.tr("This plugin is broken")
440441
descTip = statusTips[p["error"]]
441442
elif p["error"] == "incompatible":
442-
desc = self.tr("This plugin is designed for a higher version of Quantum GIS")
443+
desc = self.tr("This plugin requires a newer version of Quantum GIS") + " (" + self.tr("at least")+ " " + p["error_details"] + ")"
444+
descTip = statusTips[p["error"]]
445+
elif p["error"] == "dependent":
446+
desc = self.tr("This plugin requires a missing module") + " (" + p["error_details"] + ")"
443447
descTip = statusTips[p["error"]]
444448
else:
445449
desc = p["desc_local"]
@@ -535,54 +539,81 @@ def installPlugin(self):
535539
""" install currently selected plugin """
536540
if not self.treePlugins.currentItem():
537541
return
542+
infoString = ('','')
538543
key = plugins.keyByUrl(self.treePlugins.currentItem().toolTip(5))
539544
plugin = plugins.all()[key]
545+
previousStatus = plugin["status"]
540546
if not plugin:
541547
return
542-
543-
if plugin["status"] == "newer":
548+
if plugin["status"] == "newer" and not plugin["error"]: # ask for confirmation if user downgrades an usable plugin
544549
if QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), self.tr("Are you sure you want to downgrade the plugin to the latest available version? The installed one is newer!"), QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
545550
return
546-
547551
dlg = QgsPluginInstallerInstallingDialog(self,plugin)
548552
dlg.exec_()
549553

550554
if dlg.result():
551555
infoString = (self.tr("Plugin installation failed"), dlg.result())
556+
elif not QDir(QDir.cleanPath(QgsApplication.qgisSettingsDirPath() + "/python/plugins/" + key)).exists():
557+
infoString = (self.tr("Plugin has disappeared"), self.tr("The plugin seems to have been installed but I don't know where. Probably the plugin package contained a wrong named directory.\nPlease search the list of installed plugins. I'm nearly sure you'll find the plugin there, but I just can't determine which of them it is. It also means that I won't be able to determine if this plugin is installed and inform you about available updates. However the plugin may work. Please contact the plugin author and submit this issue."))
558+
QApplication.setOverrideCursor(Qt.WaitCursor)
559+
self.getAllAvailablePlugins()
560+
QApplication.restoreOverrideCursor()
552561
else:
553-
path = QDir.cleanPath(QgsApplication.qgisSettingsDirPath() + "/python/plugins/" + key)
554-
if not QDir(path).exists():
555-
infoString = (self.tr("Plugin has disappeared"), self.tr("The plugin seems to have been installed but I don't know where. Probably the plugin package contained a wrong named directory.\nPlease search the list of installed plugins. I'm nearly sure you'll find the plugin there, but I just can't determine which of them it is. It also means that I won't be able to determine if this plugin is installed and inform you about available updates. However the plugin may work. Please contact the plugin author and submit this issue."))
556-
QApplication.setOverrideCursor(Qt.WaitCursor)
557-
self.getAllAvailablePlugins()
558-
QApplication.restoreOverrideCursor()
562+
try:
563+
exec ("sys.path_importer_cache.clear()")
564+
exec ("import %s" % plugin["localdir"])
565+
exec ("reload (%s)" % plugin["localdir"])
566+
except:
567+
pass
568+
plugins.updatePlugin(key, False)
569+
plugin = plugins.all()[key]
570+
if not plugin["error"]:
571+
if previousStatus in ["not installed", "new"]:
572+
infoString = (self.tr("Plugin installed successfully"),
573+
self.tr("Python plugin installed.\nYou have to enable it in the Plugin Manager."))
574+
else:
575+
infoString = (self.tr("Plugin reinstalled successfully"),
576+
self.tr("Python plugin reinstalled.\nYou have to restart Quantum GIS to reload it."))
559577
else:
560-
try:
561-
exec ("sys.path_importer_cache.clear()")
562-
exec ("del sys.modules[%s]" % plugin["localdir"]) # remove old version if exist
563-
except:
564-
pass
565-
try:
566-
exec ("import %s" % plugin["localdir"])
567-
exec ("reload (%s)" % plugin["localdir"])
568-
if plugin["status"] == "not installed" or plugin["status"] == "new":
569-
infoString = (self.tr("Plugin installed successfully"), self.tr("Python plugin installed.\nYou have to enable it in the Plugin Manager."))
578+
if plugin["error"] == "incompatible":
579+
message = self.tr("The plugin is designed for a newer version of Quantum GIS. The minimum required version is:")
580+
message += " <b>" + plugin["error_details"] + "</b>"
581+
elif plugin["error"] == "dependent":
582+
message = self.tr("The plugin depends on some components missing on your system. Please install the following Python module:")
583+
message += "<b> " + plugin["error_details"] + "</b>"
584+
else:
585+
message = self.tr("The plugin is broken. Python said:")
586+
message += "<br><b>" + plugin["error_details"] + "</b>"
587+
dlg = QgsPluginInstallerPluginErrorDialog(self,message)
588+
dlg.exec_()
589+
if dlg.result():
590+
# revert installation
591+
plugins.setPluginData(key, "status", "not installed")
592+
plugins.setPluginData(key, "version_inst", "")
593+
plugins.setPluginData(key, "desc_local", "")
594+
plugins.setPluginData(key, "error", "")
595+
plugins.setPluginData(key, "error_details", "")
596+
pluginDir = unicode(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins/"+ str(plugin["localdir"]))
597+
removeDir(pluginDir)
598+
if QDir(pluginDir).exists():
599+
infoString = (self.tr("Plugin uninstall failed"), result)
600+
try:
601+
exec ("sys.path_importer_cache.clear()")
602+
exec ("import %s" % plugin["localdir"])
603+
exec ("reload (%s)" % plugin["localdir"])
604+
except:
605+
pass
606+
plugins.updatePlugin(key, False)
570607
else:
571-
infoString = (self.tr("Plugin installed successfully"),self.tr("Python plugin reinstalled.\nYou have to restart Quantum GIS to reload it."))
572-
except Exception, error:
573-
dlg = QgsPluginInstallerPluginErrorDialog(self,error.message)
574-
dlg.exec_()
575-
if dlg.result():
576-
pluginDir = unicode(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins/"+ str(plugin["localdir"]))
577-
result = removeDir(pluginDir)
578-
if result:
579-
QMessageBox.warning(self, self.tr("Plugin uninstall failed"), result)
580-
plugins.updatePlugin(key, False)
581-
self.populatePluginTree()
582-
return
583-
plugins.updatePlugin(key, False)
608+
try:
609+
exec ("del sys.modules[%s]" % plugin["localdir"])
610+
except:
611+
pass
612+
if not plugin["repository"]:
613+
plugins.remove(key)
584614
self.populatePluginTree()
585-
QMessageBox.information(self, infoString[0], infoString[1])
615+
if infoString[0]:
616+
QMessageBox.information(self, infoString[0], infoString[1])
586617

587618

588619
# ----------------------------------------- #
@@ -603,7 +634,6 @@ def uninstallPlugin(self):
603634
#print "Uninstalling plugin", plugin["name"], pluginDir
604635
result = removeDir(pluginDir)
605636
if result:
606-
QApplication.restoreOverrideCursor()
607637
QMessageBox.warning(self, self.tr("Plugin uninstall failed"), result)
608638
else:
609639
try:
@@ -616,8 +646,9 @@ def uninstallPlugin(self):
616646
plugins.setPluginData(key, "status", "not installed")
617647
plugins.setPluginData(key, "version_inst", "")
618648
plugins.setPluginData(key, "desc_local", "")
649+
plugins.setPluginData(key, "error", "")
650+
plugins.setPluginData(key, "error_details", "")
619651
self.populatePluginTree()
620-
QApplication.restoreOverrideCursor()
621652
QMessageBox.information(self, self.tr("QGIS Python Plugin Installer"), self.tr("Plugin uninstalled successfully"))
622653

623654

0 commit comments

Comments
 (0)