Skip to content

Commit

Permalink
Merge pull request #34876 from olivierdalang/plugins_take_2
Browse files Browse the repository at this point in the history
[plugin manager] allow to install stable or experimental
  • Loading branch information
m-kuhn committed Mar 15, 2020
2 parents 59c7579 + c924cfd commit 9b9c906
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 30 deletions.
14 changes: 10 additions & 4 deletions python/pyplugin_installer/installer.py
Expand Up @@ -220,14 +220,19 @@ def exportPluginsToManager(self):
"installed": plugin["installed"] and "true" or "false",
"available": plugin["available"] and "true" or "false",
"status": plugin["status"],
"status_exp": plugin["status_exp"],
"error": plugin["error"],
"error_details": plugin["error_details"],
"experimental": plugin["experimental"] and "true" or "false",
"deprecated": plugin["deprecated"] and "true" or "false",
"trusted": plugin["trusted"] and "true" or "false",
"version_available": plugin["version_available"],
"version_available_stable": plugin["version_available_stable"] or "",
"version_available_experimental": plugin["version_available_experimental"] or "",
"zip_repository": plugin["zip_repository"],
"download_url": plugin["download_url"],
"download_url_stable": plugin["download_url_stable"],
"download_url_experimental": plugin["download_url_experimental"],
"filename": plugin["filename"],
"downloads": plugin["downloads"],
"average_vote": plugin["average_vote"],
Expand Down Expand Up @@ -282,19 +287,20 @@ def upgradeAllUpgradeable(self):
self.installPlugin(key, quiet=True)

# ----------------------------------------- #
def installPlugin(self, key, quiet=False):
def installPlugin(self, key, quiet=False, stable=True):
""" Install given plugin """
error = False
status_key = 'status' if stable else 'status_exp'
infoString = ('', '')
plugin = plugins.all()[key]
previousStatus = plugin["status"]
previousStatus = plugin[status_key]
if not plugin:
return
if plugin["status"] == "newer" and not plugin["error"]: # ask for confirmation if user downgrades an usable plugin
if plugin[status_key] == "newer" and not plugin["error"]: # ask for confirmation if user downgrades an usable plugin
if QMessageBox.warning(iface.mainWindow(), 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:
return

dlg = QgsPluginInstallerInstallingDialog(iface.mainWindow(), plugin)
dlg = QgsPluginInstallerInstallingDialog(iface.mainWindow(), plugin, stable=stable)
dlg.exec_()

if dlg.result():
Expand Down
68 changes: 58 additions & 10 deletions python/pyplugin_installer/installer_data.py
Expand Up @@ -418,16 +418,23 @@ def xmlDownloaded(self):
else:
plugin_id = None

version = pluginNodes.item(i).toElement().attribute("version")
download_url = pluginNodes.item(i).firstChildElement("download_url").text().strip()

plugin = {
"id": name,
"plugin_id": plugin_id,
"name": pluginNodes.item(i).toElement().attribute("name"),
"version_available": pluginNodes.item(i).toElement().attribute("version"),
"version_available": version,
"version_available_stable": version if not experimental else "",
"version_available_experimental": version if experimental else "",
"description": pluginNodes.item(i).firstChildElement("description").text().strip(),
"about": pluginNodes.item(i).firstChildElement("about").text().strip(),
"author_name": pluginNodes.item(i).firstChildElement("author_name").text().strip(),
"homepage": pluginNodes.item(i).firstChildElement("homepage").text().strip(),
"download_url": pluginNodes.item(i).firstChildElement("download_url").text().strip(),
"download_url": download_url,
"download_url_stable": download_url if not experimental else "",
"download_url_experimental": download_url if experimental else "",
"category": pluginNodes.item(i).firstChildElement("category").text().strip(),
"tags": pluginNodes.item(i).firstChildElement("tags").text().strip(),
"changelog": pluginNodes.item(i).firstChildElement("changelog").text().strip(),
Expand All @@ -445,6 +452,7 @@ def xmlDownloaded(self):
"installed": False,
"available": True,
"status": "not installed",
"status_exp": "not installed",
"error": "",
"error_details": "",
"version_installed": "",
Expand Down Expand Up @@ -668,15 +676,20 @@ def pluginMetadata(fct):
"deprecated": pluginMetadata("deprecated").strip().upper() in ["TRUE", "YES"],
"trusted": False,
"version_available": "",
"version_available_stable": "",
"version_available_experimental": "",
"zip_repository": "",
"download_url": path, # warning: local path as url!
"download_url_stable": "",
"download_url_experimental": "",
"filename": "",
"downloads": "",
"average_vote": "",
"rating_votes": "",
"available": False, # Will be overwritten, if any available version found.
"installed": True,
"status": "orphan", # Will be overwritten, if any available version found.
"status_exp": "orphan", # Will be overwritten, if any available version found.
"error": error,
"error_details": errorDetails,
"readonly": readOnly,
Expand Down Expand Up @@ -736,7 +749,12 @@ def rebuild(self):
# check if the plugin is allowed and if there isn't any better one added already.
if (allowExperimental or not plugin["experimental"]) \
and (allowDeprecated or not plugin["deprecated"]) \
and not (key in self.mPlugins and self.mPlugins[key]["version_available"] and compareVersions(self.mPlugins[key]["version_available"], plugin["version_available"]) < 2):
and not (
key in self.mPlugins and self.mPlugins[key]["version_available"]
and compareVersions(self.mPlugins[key]["version_available"], plugin["version_available"]) < 2
and self.mPlugins[key]["experimental"] and not plugin["experimental"]
):

# The mPlugins dict contains now locally installed plugins.
# Now, add the available one if not present yet or update it if present already.
if key not in self.mPlugins:
Expand All @@ -753,36 +771,66 @@ def rebuild(self):
# other remote metadata is preferred:
for attrib in ["name", "plugin_id", "description", "about", "category", "tags", "changelog", "author_name", "author_email", "homepage",
"tracker", "code_repository", "experimental", "deprecated", "version_available", "zip_repository",
"version_available_stable", "version_available_experimental", "download_url_stable", "download_url_experimental",
"download_url", "filename", "downloads", "average_vote", "rating_votes", "trusted", "plugin_dependencies"]:
if attrib not in translatableAttributes or attrib == "name": # include name!
if plugin.get(attrib, False):
self.mPlugins[key][attrib] = plugin[attrib]

# If the stable version is higher than the experimental version, we ignore the experimental version
if compareVersions(self.mPlugins[key]["version_available_stable"], self.mPlugins[key]["version_available_experimental"]) == 1:
self.mPlugins[key]["version_available_experimental"] = ''

# set status
#
# installed available status
# ---------------------------------------
# none any "not installed" (will be later checked if is "new")
# any none "orphan"
# no none "none available"
# yes none "orphan"
# same same "installed"
# less greater "upgradeable"
# greater less "newer"
if not self.mPlugins[key]["version_available"]:
if not self.mPlugins[key]["version_available_stable"] and not self.mPlugins[key]["version_installed"]:
self.mPlugins[key]["status"] = "none available"
elif not self.mPlugins[key]["version_available_stable"] and self.mPlugins[key]["version_installed"]:
self.mPlugins[key]["status"] = "orphan"
elif not self.mPlugins[key]["version_installed"]:
self.mPlugins[key]["status"] = "not installed"
elif self.mPlugins[key]["version_installed"] in ["?", "-1"]:
self.mPlugins[key]["status"] = "installed"
elif compareVersions(self.mPlugins[key]["version_available"], self.mPlugins[key]["version_installed"]) == 0:
elif compareVersions(self.mPlugins[key]["version_available_stable"], self.mPlugins[key]["version_installed"]) == 0:
self.mPlugins[key]["status"] = "installed"
elif compareVersions(self.mPlugins[key]["version_available"], self.mPlugins[key]["version_installed"]) == 1:
elif compareVersions(self.mPlugins[key]["version_available_stable"], self.mPlugins[key]["version_installed"]) == 1:
self.mPlugins[key]["status"] = "upgradeable"
else:
self.mPlugins[key]["status"] = "newer"
# debug: test if the status match the "installed" tag:
if self.mPlugins[key]["status"] in ["not installed"] and self.mPlugins[key]["installed"]:
raise Exception("Error: plugin status is ambiguous (1)")
if self.mPlugins[key]["status"] in ["not installed", "none available"] and self.mPlugins[key]["installed"]:
raise Exception("Error: plugin status is ambiguous (1) for plugin {}".format(key))
if self.mPlugins[key]["status"] in ["installed", "orphan", "upgradeable", "newer"] and not self.mPlugins[key]["installed"]:
raise Exception("Error: plugin status is ambiguous (2)")
raise Exception("Error: plugin status is ambiguous (2) for plugin {}".format(key))

if not self.mPlugins[key]["version_available_experimental"] and not self.mPlugins[key]["version_installed"]:
self.mPlugins[key]["status_exp"] = "none available"
elif not self.mPlugins[key]["version_available_experimental"] and self.mPlugins[key]["version_installed"]:
self.mPlugins[key]["status_exp"] = "orphan"
elif not self.mPlugins[key]["version_installed"]:
self.mPlugins[key]["status_exp"] = "not installed"
elif self.mPlugins[key]["version_installed"] in ["?", "-1"]:
self.mPlugins[key]["status_exp"] = "installed"
elif compareVersions(self.mPlugins[key]["version_available_experimental"], self.mPlugins[key]["version_installed"]) == 0:
self.mPlugins[key]["status_exp"] = "installed"
elif compareVersions(self.mPlugins[key]["version_available_experimental"], self.mPlugins[key]["version_installed"]) == 1:
self.mPlugins[key]["status_exp"] = "upgradeable"
else:
self.mPlugins[key]["status_exp"] = "newer"
# debug: test if the status_exp match the "installed" tag:
if self.mPlugins[key]["status_exp"] in ["not installed", "none available"] and self.mPlugins[key]["installed"]:
raise Exception("Error: plugin status_exp is ambiguous (1) for plugin {}".format(key))
if self.mPlugins[key]["status_exp"] in ["installed", "orphan", "upgradeable", "newer"] and not self.mPlugins[key]["installed"]:
raise Exception("Error: plugin status_exp is ambiguous (2) for plugin {} (status_exp={})".format(key, self.mPlugins[key]["status_exp"]))

self.markNews()

# ----------------------------------------- #
Expand Down
Expand Up @@ -40,7 +40,7 @@
class QgsPluginInstallerInstallingDialog(QDialog, Ui_QgsPluginInstallerInstallingDialogBase):
# ----------------------------------------- #

def __init__(self, parent, plugin):
def __init__(self, parent, plugin, stable=True):
QDialog.__init__(self, parent)
self.setupUi(self)
self.plugin = plugin
Expand All @@ -50,7 +50,7 @@ def __init__(self, parent, plugin):
self.labelName.setText(plugin["name"])
self.buttonBox.clicked.connect(self.abort)

self.url = QUrl(plugin["download_url"])
self.url = QUrl(plugin["download_url_stable"] if stable else plugin["download_url_experimental"])
self.redirectionCounter = 0

fileName = plugin["filename"]
Expand Down

0 comments on commit 9b9c906

Please sign in to comment.