Skip to content

Commit 2a6a4c5

Browse files
author
borysiasty
committed
Plugin Installer update - cleaning and refactoring
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@10587 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent b8a2b6e commit 2a6a4c5

File tree

5 files changed

+151
-120
lines changed

5 files changed

+151
-120
lines changed

python/plugins/plugin_installer/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
Copyright (C) 2007-2008 Matthew Perry
3-
Copyright (C) 2008 Borys Jurgiel
3+
Copyright (C) 2008-2009 Borys Jurgiel
44
/***************************************************************************
55
* *
66
* This program is free software; you can redistribute it and/or modify *
@@ -14,7 +14,7 @@ def name():
1414
return "Plugin Installer"
1515

1616
def version():
17-
return "Version 0.9.14"
17+
return "Version 1.0"
1818

1919
def description():
2020
return "Downloads and installs QGIS python plugins"

python/plugins/plugin_installer/i18n.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ file: installer_plugin.py
4343
// InstallerPlugin::initGui
4444
translate( "QgsPluginInstaller", "Fetch Python Plugins..." )
4545
translate( "QgsPluginInstaller", "Install more plugins from remote repositories" )
46-
translate( "QgsPluginInstaller", "Install more plugins from remote repositories" )
4746
translate( "QgsPluginInstaller", "Looking for new plugins..." )
47+
translate( "QgsPluginInstaller", "QGIS Plugin Conflict:" )
48+
translate( "QgsPluginInstaller", "The Plugin Installer has detected an obsolete plugin which masks a newer version shipped with this QGIS version. Probably it is a remainder of an older QGIS installation. Please use the Plugin Installer to remove it in order to unmask the instance shipped with this version of QGIS." )
49+
4850

4951
// InstallerPlugin::checkingDone
5052
translate( "QgsPluginInstaller", "There is a new plugin available" )

python/plugins/plugin_installer/installer_data.py

+116-77
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
"""
33
Copyright (C) 2007-2008 Matthew Perry
4-
Copyright (C) 2008 Borys Jurgiel
4+
Copyright (C) 2008-2009 Borys Jurgiel
55
66
/***************************************************************************
77
* *
@@ -20,7 +20,7 @@
2020
from qgis.core import *
2121
from unzip import unzip
2222
from version_compare import compareVersions, normalizeVersion
23-
23+
import sys
2424

2525
"""
2626
Data structure:
@@ -84,7 +84,7 @@ def setIface(qgisIface):
8484
("Martin Dobias' Sandbox", "http://mapserver.sk/~wonder/qgis/plugins-sandbox.xml", ""),
8585
("Aaron Racicot's Repository", "http://qgisplugins.z-pulley.com", ""),
8686
("Barry Rowlingson's Repository", "http://www.maths.lancs.ac.uk/~rowlings/Qgis/Plugins/plugins.xml", ""),
87-
("GIS-Lab Repository", "http://gis-lab.info/programs/qgis/qgis-repo.xml", "")]
87+
("GIS-Lab Repository", "http://gis-lab.info/programs/qgis/qgis-repo.xml", "")]
8888

8989

9090

@@ -245,11 +245,17 @@ def allUnavailable(self):
245245

246246

247247
# ----------------------------------------- #
248-
def setRepositoryData(self,reposName, key, value):
248+
def setRepositoryData(self, reposName, key, value):
249249
""" write data to the mRepositories dict """
250250
self.mRepositories[reposName][key] = value
251251

252252

253+
# ----------------------------------------- #
254+
def remove(self, reposName):
255+
""" remove given item from the mRepositories dict """
256+
del self.mRepositories[reposName]
257+
258+
253259
# ----------------------------------------- #
254260
def rename(self, oldName, newName):
255261
""" rename repository key """
@@ -284,7 +290,7 @@ def checkingOnStartInterval(self):
284290
interval = 0
285291
for j in [1,3,7,14,30]:
286292
if i >= j:
287-
interval = j
293+
interval = j
288294
return interval
289295

290296

@@ -414,8 +420,7 @@ def xmlDownloaded(self,nr,state):
414420
experimental = False
415421
if pluginNodes.item(i).firstChildElement("experimental").text().simplified().toUpper() in ["TRUE","YES"]:
416422
experimental = True
417-
plugin = {}
418-
plugin[name] = {
423+
plugin = {
419424
"name" : pluginNodes.item(i).toElement().attribute("name"),
420425
"version_avail" : pluginNodes.item(i).toElement().attribute("version"),
421426
"desc_repo" : pluginNodes.item(i).firstChildElement("description").text().simplified(),
@@ -440,8 +445,8 @@ def xmlDownloaded(self,nr,state):
440445
#if compatible, add the plugin to the list
441446
if compareVersions(QGIS_VER, qgisMinimumVersion) < 2 and compareVersions(qgisMaximumVersion, QGIS_VER) < 2:
442447
if QGIS_VER[0]==qgisMinimumVersion[0] or name=="plugin_installer" or (qgisMinimumVersion!="0" and qgisMaximumVersion!="2"):
443-
plugins.addPlugin(plugin)
444-
plugins.workarounds()
448+
#add the plugin to the cache
449+
plugins.addFromRepository(plugin)
445450
self.mRepositories[reposName]["state"] = 2
446451
else:
447452
#print "Repository parsing error"
@@ -452,7 +457,7 @@ def xmlDownloaded(self,nr,state):
452457

453458
# is the checking done?
454459
if not self.fetchingInProgress():
455-
plugins.getAllInstalled()
460+
plugins.rebuild()
456461
self.saveCheckingOnStartLastDate()
457462
self.emit(SIGNAL("checkingDone()"))
458463
# --- /class Repositories ---------------------------------------------------------------- #
@@ -467,7 +472,10 @@ class Plugins(QObject):
467472
# ----------------------------------------- #
468473
def __init__(self):
469474
QObject.__init__(self)
470-
self.mPlugins = {}
475+
self.mPlugins = {} # the dict of plugins (dicts)
476+
self.repoCache = {} # the dict of lists of plugins (dicts)
477+
self.localCache = {} # the dict of plugins (dicts)
478+
self.obsoletePlugins = [] # the list of outdated 'user' plugins masking newer 'system' ones
471479

472480

473481
# ----------------------------------------- #
@@ -486,37 +494,39 @@ def keyByUrl(self, name):
486494

487495

488496
# ----------------------------------------- #
489-
def setPluginData(self, pluginName, key, value):
490-
""" write data to the mPlugins dict """
491-
self.mPlugins[pluginName][key] = value
497+
def addInstalled(self, plugin):
498+
""" add given plugin to the localCache """
499+
key = plugin["localdir"]
500+
self.localCache[key] = plugin
492501

493502

494503
# ----------------------------------------- #
495-
def clear(self):
496-
""" clear the plugins dict"""
497-
self.mPlugins = {}
504+
def addFromRepository(self, plugin):
505+
""" add given plugin to the repoCache """
506+
repo = plugin["repository"]
507+
try:
508+
self.repoCache[repo] += [plugin]
509+
except:
510+
self.repoCache[repo] = [plugin]
498511

499512

500513
# ----------------------------------------- #
501-
def addPlugin(self, plugins):
502-
""" add a plugin (first from given) to the mPlugins dict """
503-
key = plugins.keys()[0]
504-
plugin = plugins[key]
505-
plugin["version_avail"] = normalizeVersion(plugin["version_avail"])
506-
plugin["version_inst"] = normalizeVersion(plugin["version_inst"])
507-
if not self.mPlugins.has_key(key) or compareVersions(self.mPlugins[key]["version_avail"],plugin["version_avail"]) == 2:
508-
self.mPlugins[key] = plugin # add the plugin if not present yet or if is newer than existing one
514+
def removeInstalledPlugin(self, key):
515+
""" remove given plugin from the localCache """
516+
if self.localCache.has_key(key):
517+
del self.localCache[key]
509518

510519

511520
# ----------------------------------------- #
512-
def remove(self, key):
513-
""" remove given plugin from the mPlugins dict """
514-
del self.mPlugins[key]
521+
def removeRepository(self, repo):
522+
""" remove whole repository from the repoCache """
523+
if self.repoCache.has_key(repo):
524+
del self.repoCache[repo]
515525

516526

517527
# ----------------------------------------- #
518-
def updatePlugin(self, key, readOnly):
519-
""" The mPlugins should contain available plugins first. Now, add installed one (add when not present, update if present) """
528+
def getInstalledPlugin(self, key, readOnly):
529+
""" get the metadata of an installed plugin """
520530
if readOnly:
521531
path = QgsApplication.pkgDataPath()
522532
else:
@@ -532,7 +542,8 @@ def updatePlugin(self, key, readOnly):
532542
error = ""
533543
errorDetails = ""
534544
try:
535-
exec("import "+ key)
545+
exec("import %s" % key)
546+
exec("reload (%s)" % key)
536547
try:
537548
exec("nam = %s.name()" % key)
538549
except:
@@ -589,73 +600,107 @@ def updatePlugin(self, key, readOnly):
589600
"url" : path,
590601
"experimental" : False,
591602
"filename" : "",
592-
"status" : "",
603+
"status" : "orphan",
593604
"error" : error,
594605
"error_details" : errorDetails,
595606
"repository" : "",
596607
"localdir" : key,
597608
"read-only" : readOnly}
598-
599-
if not self.mPlugins.has_key(key):
600-
self.mPlugins[key] = plugin # just add a new plugin
601-
else:
602-
self.mPlugins[key]["localdir"] = plugin["localdir"]
603-
self.mPlugins[key]["read-only"] = plugin["read-only"]
604-
self.mPlugins[key]["error"] = plugin["error"]
605-
self.mPlugins[key]["error_details"] = plugin["error_details"]
606-
if plugin["name"] and plugin["name"] != key:
607-
self.mPlugins[key]["name"] = plugin["name"] # local name has higher priority
608-
self.mPlugins[key]["version_inst"] = plugin["version_inst"]
609-
self.mPlugins[key]["desc_local"] = plugin["desc_local"]
610-
# set status
611-
#
612-
# installed available status
613-
# ---------------------------------------
614-
# none any "not installed" (will be later checked if is "new")
615-
# any none "orphan"
616-
# same same "installed"
617-
# less greater "upgradeable"
618-
# greater less "newer"
619-
if not self.mPlugins[key]["version_avail"]:
620-
self.mPlugins[key]["status"] = "orphan"
621-
elif self.mPlugins[key]["error"] in ["broken","dependent"]:
622-
self.mPlugins[key]["status"] = "installed"
623-
elif not self.mPlugins[key]["version_inst"]:
624-
self.mPlugins[key]["status"] = "not installed"
625-
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
626-
self.mPlugins[key]["status"] = "installed"
627-
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
628-
self.mPlugins[key]["status"] = "upgradeable"
629-
else:
630-
self.mPlugins[key]["status"] = "newer"
609+
return plugin
631610

632611

633612
# ----------------------------------------- #
634613
def getAllInstalled(self):
635-
""" update the mPlugins dict with alredy installed plugins """
614+
""" Build the localCache """
615+
self.localCache = {}
636616
# first, try to add the read-only plugins...
617+
pluginsPath = unicode(QDir.convertSeparators(QDir.cleanPath(QgsApplication.pkgDataPath() + "/python/plugins")))
618+
# temporarily add the system path as the first element to force loading the read-only plugins, even if masked by user ones.
619+
sys.path = [pluginsPath] + sys.path
637620
try:
638-
pluginDir = QDir.cleanPath(unicode(QgsApplication.pkgDataPath()) + "/python/plugins")
639-
pluginDir = QDir(pluginDir)
621+
pluginDir = QDir(pluginsPath)
640622
pluginDir.setFilter(QDir.AllDirs)
641623
for key in pluginDir.entryList():
642624
key = unicode(key)
643625
if not key in [".",".."]:
644-
self.updatePlugin(key, True)
626+
self.localCache[key] = self.getInstalledPlugin(key, True)
645627
except:
646628
# return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the system plugin directory")
647629
pass # it's not necessary to stop due to this error
630+
# remove the temporarily added path
631+
sys.path.remove(pluginsPath)
648632
# ...then try to add locally installed ones
649633
try:
650-
pluginDir = QDir.cleanPath(unicode(QgsApplication.qgisSettingsDirPath()) + "/python/plugins")
634+
pluginDir = QDir.convertSeparators(QDir.cleanPath(QgsApplication.qgisSettingsDirPath() + "/python/plugins"))
651635
pluginDir = QDir(pluginDir)
652636
pluginDir.setFilter(QDir.AllDirs)
653637
except:
654638
return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the local plugin directory")
655639
for key in pluginDir.entryList():
656640
key = unicode(key)
657641
if not key in [".",".."]:
658-
self.updatePlugin(key, False)
642+
plugin = self.getInstalledPlugin(key, False)
643+
if key in self.localCache.keys() and compareVersions(self.localCache[key]["version_inst"],plugin["version_inst"]) == 1:
644+
# An obsolete plugin in the "user" location is masking a newer one in the "system" location!
645+
self.obsoletePlugins += [key]
646+
self.localCache[key] = plugin
647+
648+
649+
# ----------------------------------------- #
650+
def rebuild(self):
651+
""" build or rebuild the mPlugins from the caches """
652+
self.mPlugins = {}
653+
for i in self.localCache.keys():
654+
self.mPlugins[i] = self.localCache[i].copy()
655+
settings = QSettings()
656+
(allowed, ok) = settings.value(settingsGroup+"/allowedPluginType", QVariant(2)).toInt()
657+
for i in self.repoCache.values():
658+
for plugin in i:
659+
key = plugin["localdir"]
660+
# check if the plugin is allowed and if there isn't any better one added already.
661+
if (allowed != 1 or plugin["repository"] == officialRepo[0]) and (allowed == 3 or not plugin["experimental"]) \
662+
and not (self.mPlugins.has_key(key) and self.mPlugins[key]["version_avail"] and compareVersions(self.mPlugins[key]["version_avail"], plugin["version_avail"]) < 2):
663+
# The mPlugins doct contains now locally installed plugins.
664+
# Now, add the available one if not present yet or update it if present already.
665+
if not self.mPlugins.has_key(key):
666+
self.mPlugins[key] = plugin # just add a new plugin
667+
else:
668+
self.mPlugins[key]["version_avail"] = plugin["version_avail"]
669+
self.mPlugins[key]["desc_repo"] = plugin["desc_repo"]
670+
self.mPlugins[key]["filename"] = plugin["filename"]
671+
self.mPlugins[key]["repository"] = plugin["repository"]
672+
self.mPlugins[key]["experimental"] = plugin["experimental"]
673+
# use remote name if local one is not available
674+
if self.mPlugins[key]["name"] == key and plugin["name"]:
675+
self.mPlugins[key]["name"] = plugin["name"]
676+
# those metadata has higher priority for their remote instances:
677+
if plugin["author"]:
678+
self.mPlugins[key]["author"] = plugin["author"]
679+
if plugin["homepage"]:
680+
self.mPlugins[key]["homepage"] = plugin["homepage"]
681+
if plugin["url"]:
682+
self.mPlugins[key]["url"] = plugin["url"]
683+
# set status
684+
#
685+
# installed available status
686+
# ---------------------------------------
687+
# none any "not installed" (will be later checked if is "new")
688+
# any none "orphan"
689+
# same same "installed"
690+
# less greater "upgradeable"
691+
# greater less "newer"
692+
if not self.mPlugins[key]["version_avail"]:
693+
self.mPlugins[key]["status"] = "orphan"
694+
elif self.mPlugins[key]["error"] in ["broken","dependent"]:
695+
self.mPlugins[key]["status"] = "installed"
696+
elif not self.mPlugins[key]["version_inst"]:
697+
self.mPlugins[key]["status"] = "not installed"
698+
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
699+
self.mPlugins[key]["status"] = "installed"
700+
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
701+
self.mPlugins[key]["status"] = "upgradeable"
702+
else:
703+
self.mPlugins[key]["status"] = "newer"
659704

660705

661706
# ----------------------------------------- #
@@ -689,12 +734,6 @@ def isThereAnythingNew(self):
689734
return False
690735

691736

692-
# ----------------------------------------- #
693-
def workarounds(self):
694-
""" workarounds for particular plugins with wrong metadata """
695-
if self.mPlugins.has_key("select") and self.mPlugins["select"]["version_avail"] == "0.1":
696-
self.mPlugins["select"]["version_avail"] = "0.2"
697-
698737
# --- /class Plugins --------------------------------------------------------------------- #
699738

700739

0 commit comments

Comments
 (0)