diff --git a/HISTORY.rst b/HISTORY.rst index 3b1b49c..a5714fb 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -5,6 +5,7 @@ History ------------------- - Fixes/enhancements: #616 +- Load remote schematisation: #626 3.14.1 (2024-09-25) diff --git a/threedi_models_and_simulations/utils.py b/threedi_models_and_simulations/utils.py index f753e4e..4429d87 100644 --- a/threedi_models_and_simulations/utils.py +++ b/threedi_models_and_simulations/utils.py @@ -343,6 +343,17 @@ def translate_illegal_chars(text, illegal_characters=r'\/:*?"<>|', replacement_c return sanitized_text +class NestedObject: + """A class to convert a nested dictionary into an object.""" + + def __init__(self, data): + for key, value in data.items(): + if isinstance(value, (list, tuple)): + setattr(self, key, [NestedObject(x) if isinstance(x, dict) else x for x in value]) + else: + setattr(self, key, NestedObject(value) if isinstance(value, dict) else value) + + class SchematisationRasterReferences: @staticmethod def global_settings_rasters(): diff --git a/threedi_models_and_simulations/utils_qgis.py b/threedi_models_and_simulations/utils_qgis.py index 19a4046..ffbb919 100644 --- a/threedi_models_and_simulations/utils_qgis.py +++ b/threedi_models_and_simulations/utils_qgis.py @@ -72,7 +72,7 @@ def get_plugin_instance(plugin_name): """Return given plugin name instance.""" try: plugin_instance = plugins[plugin_name] - except AttributeError: + except (AttributeError, KeyError): plugin_instance = None return plugin_instance diff --git a/threedi_models_and_simulations/widgets/build_options.py b/threedi_models_and_simulations/widgets/build_options.py index a4981b2..d5b533a 100644 --- a/threedi_models_and_simulations/widgets/build_options.py +++ b/threedi_models_and_simulations/widgets/build_options.py @@ -5,6 +5,7 @@ from qgis.PyQt.QtCore import QSettings +from ..utils import NestedObject from ..utils_qgis import get_schematisation_editor_instance from ..widgets.new_schematisation_wizard import NewSchematisationWizard from ..widgets.schematisation_download import SchematisationDownload @@ -86,3 +87,27 @@ def download_schematisation(self): if wip_revision is not None: settings = QSettings("3di", "qgisplugin") settings.setValue("last_used_spatialite_path", wip_revision.schematisation_dir) + + @api_client_required + def load_remote_schematisation(self, schematisation, revision): + """Download and load a schematisation from the server.""" + if isinstance(schematisation, dict): + schematisation = NestedObject(schematisation) + if isinstance(revision, dict): + revision = NestedObject(revision) + + # Download and load the schematisation + schematisation_download = SchematisationDownload(self.plugin_dock) + schematisation_download.download_required_files(schematisation, revision, is_latest_revision=True) + downloaded_local_schematisation = schematisation_download.downloaded_local_schematisation + custom_sqlite_filepath = schematisation_download.downloaded_sqlite_filepath + if downloaded_local_schematisation is not None: + self.load_local_schematisation( + local_schematisation=downloaded_local_schematisation, + action=BuildOptionActions.DOWNLOADED, + custom_sqlite_filepath=custom_sqlite_filepath, + ) + wip_revision = downloaded_local_schematisation.wip_revision + if wip_revision is not None: + settings = QSettings("3di", "qgisplugin") + settings.setValue("last_used_spatialite_path", wip_revision.schematisation_dir) diff --git a/threedi_models_and_simulations/widgets/log_in.py b/threedi_models_and_simulations/widgets/log_in.py index 39fb257..951b581 100644 --- a/threedi_models_and_simulations/widgets/log_in.py +++ b/threedi_models_and_simulations/widgets/log_in.py @@ -1,5 +1,6 @@ # 3Di Models and Simulations for QGIS, licensed under GPLv2 or (at your option) any later version # Copyright (C) 2023 by Lutra Consulting for 3Di Water Management +import inspect import logging import os from functools import wraps @@ -22,7 +23,7 @@ def api_client_required(fn): """Decorator for limiting functionality access to logged-in user (with option to log in).""" @wraps(fn) - def wrapper(self): + def wrapper(self, *args, **kwargs): if hasattr(self, "plugin_dock"): plugin_dock = getattr(self, "plugin_dock") else: @@ -46,7 +47,13 @@ def wrapper(self): plugin_dock.communication.bar_warn("Logging-in canceled. Action aborted!") return - return fn(self) + # Get the function's signature and check the number of parameters + sig = inspect.signature(fn) + num_params = len(sig.parameters) + if num_params == 1: + return fn(self) + else: + return fn(self, *args, **kwargs) return wrapper diff --git a/threedi_models_and_simulations/widgets/schematisation_download.py b/threedi_models_and_simulations/widgets/schematisation_download.py index dfbc387..accc480 100644 --- a/threedi_models_and_simulations/widgets/schematisation_download.py +++ b/threedi_models_and_simulations/widgets/schematisation_download.py @@ -219,16 +219,17 @@ def download_schematisation_revision(self): if self.downloaded_local_schematisation: self.close() - def download_required_files(self, schematisation, revision): + def download_required_files(self, schematisation, revision, is_latest_revision=False): """Download required schematisation revision files.""" try: - latest_online_revision = max([rev.number for rev in self.revisions]) schematisation_pk = schematisation.id schematisation_name = schematisation.name revision_pk = revision.id revision_number = revision.number revision_sqlite = revision.sqlite - is_latest_revision = revision_number == latest_online_revision + if not is_latest_revision: + latest_online_revision = max([rev.number for rev in self.revisions]) if self.revisions else None + is_latest_revision = revision_number == latest_online_revision try: local_schematisation = self.local_schematisations[schematisation_pk] local_schematisation_present = True