diff --git a/docs/docs/getting_started.md b/docs/docs/getting_started.md index 21b86d3..ff5f3ce 100644 --- a/docs/docs/getting_started.md +++ b/docs/docs/getting_started.md @@ -84,10 +84,12 @@ In the `Project` tab: ## Install the module plugin -In the `Plugin` tab, you can install the module plugin (ie. TWW plugin). Direct install using the `Install` button is currently not implemented. +In the `Plugin` tab, you can install the module plugin (ie. TWW plugin). There are two possibilities: -* Click `Copy ZIP to directory` -* In QGIS > Extension > Install and manage extension > Install from ZIP +1. Click `Install` and it will be installed in the current QGIS profile. Note: this is possible only if running oQtopus from QGIS. +2. Click `Copy ZIP to directory`: + * You can copy the plugin zip file to a directory of your choice. + * Then in QGIS > Extension > Install and manage extension > Install from ZIP. ## oQtopus as a standalone python executable diff --git a/oqtopus/gui/main_dialog.py b/oqtopus/gui/main_dialog.py index 5f58f29..df5228d 100644 --- a/oqtopus/gui/main_dialog.py +++ b/oqtopus/gui/main_dialog.py @@ -55,7 +55,6 @@ class MainDialog(QDialog, DIALOG_UI): - def __init__(self, modules_config_path, about_dialog_cls=None, parent=None): QDialog.__init__(self, parent) self.setupUi(self) diff --git a/oqtopus/gui/plugin_widget.py b/oqtopus/gui/plugin_widget.py index 8ae5b16..7b83740 100644 --- a/oqtopus/gui/plugin_widget.py +++ b/oqtopus/gui/plugin_widget.py @@ -1,5 +1,6 @@ import os import shutil +from zipfile import ZipFile from qgis.PyQt.QtCore import QUrl from qgis.PyQt.QtGui import QDesktopServices @@ -13,7 +14,6 @@ class PluginWidget(QWidget, DIALOG_UI): - def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi(self) @@ -23,9 +23,18 @@ def __init__(self, parent=None): self.copyZipToDirectory_pushButton.clicked.connect(self.__copyZipToDirectoryClicked) self.__current_module_package = None + self.__plugin_name = None + + try: + from qgis.utils import iface + + self.qgisProfile_label.setText(iface.userProfileManager().userProfile().name()) + except ImportError: + self.qgisProfile_label.setText("Unknown") def setModulePackage(self, module_package: ModulePackage): self.__current_module_package = module_package + self.__plugin_name = None self.__packagePrepareGetPluginFilename() def clearModulePackage(self): @@ -58,6 +67,20 @@ def __packagePrepareGetPluginFilename(self): QtUtils.setFontItalic(self.info_label, True) return + # Get the plugin name + self.__plugin_name = self.__extractPluginName(asset_plugin.package_zip) + if not self.__plugin_name: + self.info_label.setText( + self.tr(f"Couldn't determinate the plugin name for '{asset_plugin.package_zip}'.") + ) + QtUtils.setForegroundColor(self.info_label, PluginUtils.COLOR_WARNING) + QtUtils.setFontItalic(self.info_label, True) + return + + # Get the installed plugin current version + version = self.__getInstalledPluginVersion(self.__plugin_name) + self.currentVersion_label.setText(version) + QtUtils.resetForegroundColor(self.info_label) QtUtils.setFontItalic(self.info_label, False) self.info_label.setText( @@ -76,21 +99,61 @@ def __installClicked(self): # Check if the package exists asset_plugin = self.__current_module_package.asset_plugin if not os.path.exists(asset_plugin.package_zip): - self.info_label.setText( - self.tr(f"Plugin zip file '{asset_plugin.package_zip}' does not exist.") + QMessageBox.critical( + self, + self.tr("Error"), + self.tr(f"Plugin zip file '{asset_plugin.package_zip}' does not exist."), ) - QtUtils.setForegroundColor(self.info_label, PluginUtils.COLOR_WARNING) - QtUtils.setFontItalic(self.info_label, True) return - QMessageBox.warning( - self, - self.tr("Not implemented"), - self.tr( - 'Installation is not implemented yet.\nAt the moment, you can only copy the plugin zip file to a directory and use "Install from ZIP" in QGIS.' - ), - ) - return + try: + from pyplugin_installer import instance as plugin_installer_instance + from qgis.core import Qgis + except ImportError: + QMessageBox.critical( + self, + self.tr("Error"), + self.tr("Plugin installation is not possible when oQtopus is running standalone."), + ) + return + + try: + installer = plugin_installer_instance() + success = installer.installFromZipFile(asset_plugin.package_zip) + + # installFromZipFile return success from QGIS 3.44.08 + if Qgis.QGIS_VERSION_INT < 34408: + version = self.__getInstalledPluginVersion(self.__plugin_name) + QMessageBox.information( + self, + self.tr("Installation finished"), + self.tr(f"Current '{self.__plugin_name}' plugin version is {version}"), + ) + self.__packagePrepareGetPluginFilename() + return + + if not success: + QMessageBox.critical( + self, + self.tr("Error"), + self.tr(f"Plugin '{self.__plugin_name}' installation failed."), + ) + return + + QMessageBox.information( + self, + self.tr("Success"), + self.tr(f"Plugin '{self.__plugin_name}' installed successfully."), + ) + self.__packagePrepareGetPluginFilename() + + except Exception as e: + QMessageBox.critical( + self, + self.tr("Error"), + self.tr("Plugin installation failed with an exception: {0}").format(str(e)), + ) + return def __seeChangelogClicked(self): if self.__current_module_package is None: @@ -168,3 +231,23 @@ def __copyZipToDirectoryClicked(self): self.tr(f"Failed to copy plugin package: {e}"), ) return + + def __extractPluginName(self, package_zip: str) -> str: + with ZipFile(package_zip, "r") as zip_ref: + for name in zip_ref.namelist(): + print(f"name: {name}") + if name.endswith("/metadata.txt"): + return name.split("/")[0] + return "" + + def __getInstalledPluginVersion(self, plugin_name: str): + try: + from qgis.utils import pluginMetadata + except ImportError: + return self.tr("Unknown") + + version = pluginMetadata(plugin_name, "version") + if version == "__error__": + return self.tr("Not installed") + + return version diff --git a/oqtopus/ui/plugin_widget.ui b/oqtopus/ui/plugin_widget.ui index 85162f1..e3a39b3 100644 --- a/oqtopus/ui/plugin_widget.ui +++ b/oqtopus/ui/plugin_widget.ui @@ -33,12 +33,18 @@ - + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + - no current version + Unknown + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse