diff --git a/ORStools/ORStoolsPlugin.py b/ORStools/ORStoolsPlugin.py index 2156bf8a..7913a0e4 100644 --- a/ORStools/ORStoolsPlugin.py +++ b/ORStools/ORStoolsPlugin.py @@ -50,7 +50,6 @@ def __init__(self, iface: QgisInterface) -> None: :type iface: QgsInterface """ self.dialog = ORStoolsDialog.ORStoolsDialogMain(iface) - self.provider = provider.ORStoolsProvider() # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) @@ -75,10 +74,15 @@ def __init__(self, iface: QgisInterface) -> None: self.add_default_provider_to_settings() + def initProcessing(self): + self.provider = provider.ORStoolsProvider() + QgsApplication.processingRegistry().addProvider(self.provider) + def initGui(self) -> None: """Create the menu entries and toolbar icons inside the QGIS GUI.""" - QgsApplication.processingRegistry().addProvider(self.provider) + self.initProcessing() + self.dialog.initGui() def unload(self) -> None: diff --git a/ORStools/common/networkaccessmanager.py b/ORStools/common/networkaccessmanager.py index 5641e6da..8b22226b 100644 --- a/ORStools/common/networkaccessmanager.py +++ b/ORStools/common/networkaccessmanager.py @@ -315,7 +315,11 @@ def replyFinished(self) -> None: # check if errorString is empty, if so, then set err string as # reply dump if re.match("(.)*server replied: $", self.reply.errorString()): - errString = self.reply.errorString() + self.http_call_result.content + try: + content_str = self.http_call_result.content.decode("utf-8", errors="replace") + errString = self.reply.errorString() + content_str + except ValueError: + errString = self.reply.errorString() + str(self.http_call_result.content) else: errString = self.reply.errorString() # check if self.http_call_result.status_code is available (client abort diff --git a/ORStools/proc/base_processing_algorithm.py b/ORStools/proc/base_processing_algorithm.py index 3f5751d4..55fbc13d 100644 --- a/ORStools/proc/base_processing_algorithm.py +++ b/ORStools/proc/base_processing_algorithm.py @@ -42,7 +42,7 @@ QgsProcessingFeedback, QgsSettings, ) -from typing import Any, Dict +from typing import Any, Dict, Union from qgis.PyQt.QtGui import QIcon @@ -74,6 +74,14 @@ def __init__(self) -> None: self.OUT_NAME = "ORSTOOLS_OUTPUT" self.PARAMETERS = None + try: + if hasattr(iface, "mainWindow") and iface.mainWindow() is not None: + self.IS_CLI = False + else: + self.IS_CLI = True + except NameError: + self.IS_CLI = True + def createInstance(self) -> Any: """ Returns instance of any child class @@ -183,14 +191,14 @@ def option_parameters(self) -> [QgsProcessingParameterDefinition]: ), ] - def get_endpoint_names_from_provider(self, provider: str) -> dict: + def get_endpoint_names_from_provider(self, provider: Union[str, int]) -> dict: providers = configmanager.read_config()["providers"] - ors_provider = providers[provider] + ors_provider = providers[int(provider)] return ors_provider["endpoints"] @classmethod def _get_ors_client_from_provider( - cls, provider: str, feedback: QgsProcessingFeedback + cls, provider: Union[str, int], feedback: QgsProcessingFeedback ) -> client.Client: """ Connects client to provider and returns a client instance for requests to the ors API @@ -200,7 +208,7 @@ def _get_ors_client_from_provider( agent = f"QGIS_{name}" providers = configmanager.read_config()["providers"] - ors_provider = providers[provider] + ors_provider = providers[int(provider)] ors_client = client.Client(ors_provider, agent) ors_client.overQueryLimit.connect( lambda: feedback.reportError("OverQueryLimit: Retrying...") diff --git a/ORStools/proc/directions_lines_proc.py b/ORStools/proc/directions_lines_proc.py index 4d6436cb..07034d8c 100644 --- a/ORStools/proc/directions_lines_proc.py +++ b/ORStools/proc/directions_lines_proc.py @@ -130,7 +130,7 @@ def processAlgorithm( ) -> Dict[str, str]: ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] preference = dict(enumerate(PREFERENCES))[parameters[self.IN_PREFERENCE]] diff --git a/ORStools/proc/directions_points_layer_proc.py b/ORStools/proc/directions_points_layer_proc.py index 41c8d5cf..e548c2f8 100644 --- a/ORStools/proc/directions_points_layer_proc.py +++ b/ORStools/proc/directions_points_layer_proc.py @@ -137,7 +137,7 @@ def processAlgorithm( ) -> Dict[str, str]: ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] preference = dict(enumerate(PREFERENCES))[parameters[self.IN_PREFERENCE]] diff --git a/ORStools/proc/directions_points_layers_proc.py b/ORStools/proc/directions_points_layers_proc.py index 024e05ef..185e83cb 100644 --- a/ORStools/proc/directions_points_layers_proc.py +++ b/ORStools/proc/directions_points_layers_proc.py @@ -151,7 +151,7 @@ def processAlgorithm( ) -> Dict[str, str]: ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] preference = dict(enumerate(PREFERENCES))[parameters[self.IN_PREFERENCE]] diff --git a/ORStools/proc/export_proc.py b/ORStools/proc/export_proc.py index 279d9f3a..d45d2713 100644 --- a/ORStools/proc/export_proc.py +++ b/ORStools/proc/export_proc.py @@ -80,7 +80,7 @@ def processAlgorithm( ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) # Get profile value - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] target_crs = QgsCoordinateReferenceSystem("EPSG:4326") rect = self.parameterAsExtent(parameters, self.IN_EXPORT, context, crs=target_crs) diff --git a/ORStools/proc/isochrones_layer_proc.py b/ORStools/proc/isochrones_layer_proc.py index 0a4b60e0..4bccbd9d 100644 --- a/ORStools/proc/isochrones_layer_proc.py +++ b/ORStools/proc/isochrones_layer_proc.py @@ -125,10 +125,9 @@ def processAlgorithm( ) -> Dict[str, str]: ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] - dimension = dict(enumerate(DIMENSIONS))[parameters[self.IN_METRIC]] - location_type = dict(enumerate(LOCATION_TYPES))[parameters[self.LOCATION_TYPE]] - + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] + dimension = dict(enumerate(DIMENSIONS))[int(parameters[self.IN_METRIC])] + location_type = dict(enumerate(LOCATION_TYPES))[int(parameters[self.LOCATION_TYPE])] factor = 60 if dimension == "time" else 1 ranges_raw = parameters[self.IN_RANGES] ranges_proc = [x * factor for x in map(float, ranges_raw.split(","))] @@ -210,6 +209,8 @@ def processAlgorithm( feedback.reportError(msg) logger.log(msg, 2) continue + if self.IS_CLI and num % 100 == 0: + print(f"Done {num} from {source.featureCount()}", flush=True) feedback.setProgress(int(100.0 / source.featureCount() * num)) return {self.OUT: self.dest_id} diff --git a/ORStools/proc/isochrones_point_proc.py b/ORStools/proc/isochrones_point_proc.py index b6b29c16..41e85973 100644 --- a/ORStools/proc/isochrones_point_proc.py +++ b/ORStools/proc/isochrones_point_proc.py @@ -110,10 +110,9 @@ def processAlgorithm( self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback ) -> Dict[str, str]: ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) - - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] - dimension = dict(enumerate(DIMENSIONS))[parameters[self.IN_METRIC]] - location_type = dict(enumerate(LOCATION_TYPES))[parameters[self.LOCATION_TYPE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] + dimension = dict(enumerate(DIMENSIONS))[int(parameters[self.IN_METRIC])] + location_type = dict(enumerate(LOCATION_TYPES))[int(parameters[self.LOCATION_TYPE])] factor = 60 if dimension == "time" else 1 ranges_raw = parameters[self.IN_RANGES] diff --git a/ORStools/proc/matrix_proc.py b/ORStools/proc/matrix_proc.py index 089347d3..347d7088 100644 --- a/ORStools/proc/matrix_proc.py +++ b/ORStools/proc/matrix_proc.py @@ -96,7 +96,7 @@ def processAlgorithm( ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) # Get profile value - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] # TODO: enable once core matrix is available # options = self.parseOptions(parameters, context) diff --git a/ORStools/proc/provider.py b/ORStools/proc/provider.py index 2307e22a..c08279c3 100644 --- a/ORStools/proc/provider.py +++ b/ORStools/proc/provider.py @@ -38,6 +38,9 @@ from .isochrones_layer_proc import ORSIsochronesLayerAlgo from .isochrones_point_proc import ORSIsochronesPointAlgo from .matrix_proc import ORSMatrixAlgo +from .provider_add_conf import ORSProviderAddAlgo +from .provider_rm_conf import ORSProviderRmAlgo +from .provider_get_confid_by_name import ORSProviderGetConfIdAlgo from ORStools.utils.gui import GuiUtils from .snap_layer_proc import ORSSnapLayerAlgo @@ -70,6 +73,9 @@ def loadAlgorithms(self) -> None: self.addAlgorithm(ORSExportAlgo()) self.addAlgorithm(ORSSnapLayerAlgo()) self.addAlgorithm(ORSSnapPointAlgo()) + self.addAlgorithm(ORSProviderAddAlgo()) + self.addAlgorithm(ORSProviderRmAlgo()) + self.addAlgorithm(ORSProviderGetConfIdAlgo()) @staticmethod def icon(): diff --git a/ORStools/proc/provider_add_conf.py b/ORStools/proc/provider_add_conf.py new file mode 100644 index 00000000..1b0a339d --- /dev/null +++ b/ORStools/proc/provider_add_conf.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + ORStools + A QGIS plugin + QGIS client to query openrouteservice + ------------------- + begin : 2017-02-01 + git sha : $Format:%H$ + copyright : (C) 2021 by HeiGIT gGmbH + email : support@openrouteservice.heigit.org + ***************************************************************************/ + + This plugin provides access to openrouteservice API functionalities + (https://openrouteservice.org), developed and + maintained by the openrouteservice team of HeiGIT gGmbH, Germany. By using + this plugin you agree to the ORS terms of service + (https://openrouteservice.org/terms-of-service/). + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from typing import Dict + +from qgis.PyQt.QtCore import QCoreApplication + +from qgis.core import ( + QgsSettings, + QgsProcessingAlgorithm, + QgsProcessingParameterString, + QgsProcessingParameterNumber, + QgsProcessingParameterBoolean, + QgsProcessingContext, + QgsProcessingFeedback, +) + +from ORStools.utils import logger +from ..proc import ENDPOINTS + + +class ORSProviderAddAlgo(QgsProcessingAlgorithm): + def __init__(self): + super().__init__() + self.PARAMETERS: list = [ + QgsProcessingParameterString( + name="ors_provider_name", + description=self.tr("Set unique name for your ors provider"), + ), + QgsProcessingParameterString( + name="ors_provider_api_key", + description=self.tr("Set api key for your ors provider"), + optional=True, + ), + QgsProcessingParameterString( + name="ors_provider_url", + description=self.tr("Set url to ors api"), + ), + QgsProcessingParameterNumber( + name="ors_provider_timeout", + description=self.tr("Set custom timeout (in seconds)"), + defaultValue=60, + ), + QgsProcessingParameterBoolean( + name="ors_provider_overwrite", + description=self.tr("If True, existing provider is overwritten"), + defaultValue=False, + ), + # TODO: Service Endpoints + # QgsProcessingParameterString( + # name="otp_endpoint_directions", + # description=self.tr("Endpoint for directions on your provider"), + # defaultValue="directions", + # optional=True + # ), + ] + + def group(self): + return "Configuration" + + def groupId(self): + return "configuration" + + def initAlgorithm(self, config={}): + for parameter in self.PARAMETERS: + self.addParameter(parameter) + + def processAlgorithm( + self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback + ) -> Dict[str, str]: + s = QgsSettings() + provider_name = self.parameterAsString(parameters, "ors_provider_name", context) + provider_url = self.parameterAsString(parameters, "ors_provider_url", context) + provider_api_key = self.parameterAsString(parameters, "ors_provider_api_key", context) + provider_timeout = self.parameterAsInt(parameters, "ors_provider_timeout", context) + provider_overwrite = self.parameterAsBoolean(parameters, "ors_provider_timeout", context) + + current_config = s.value("ORStools/config") + if provider_name in [x["name"] for x in current_config["providers"]]: + if provider_overwrite: + msg = f"A provider with the name '{provider_name}' already exists. Replacement not yet implemented." + else: + # ignoring reset of settings for now. + msg = f"A provider with the name '{provider_name}' already exists. Please mark overwrite checkbox." + feedback.pushInfo(msg) + logger.log(msg, 2) + return {"OUTPUT": msg} + else: + existing_config = s.value("ORStools/config") + s.setValue( + "ORStools/config", + { + "providers": existing_config["providers"] + + [ + { + "base_url": provider_url, + "key": provider_api_key, + "name": provider_name, + "timeout": provider_timeout, + "endpoints": ENDPOINTS, # TODO: customize"new config added: " + } + ] + }, + ) + s.sync() # this gives no feedback whatsover, so checking manually is necessary: + try: + with open(s.fileName(), "a"): + pass + msg = f"config has been added: {provider_name}" + except IOError as e: + msg = f"config couldn't be added: {e} | {s.fileName()}" + + return { + "OUTPUT": msg, + "CONFIG": s.value("ORStools/config", {"providers": []})["providers"], + } + + def createInstance(self): + return self.__class__() + + def name(self): + return "config_add_provider" + + def displayName(self) -> str: + """ + Algorithm name shown in QGIS toolbox + :return: + """ + return self.tr("Set Provider Config via Algorithm (e.g. headless)") + + def tr(self, string: str, context=None) -> str: + context = context or self.__class__.__name__ + return QCoreApplication.translate(context, string) + # return string #disabling QCoreApplication.translate due to Qt + + def flags(self): + return ( + super().flags() | QgsProcessingAlgorithm.FlagHideFromToolbox + ) # prior 3.36 but seems to work in 3.42, too diff --git a/ORStools/proc/provider_get_confid_by_name.py b/ORStools/proc/provider_get_confid_by_name.py new file mode 100644 index 00000000..fd55b7c2 --- /dev/null +++ b/ORStools/proc/provider_get_confid_by_name.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + ORStools + A QGIS plugin + QGIS client to query openrouteservice + ------------------- + begin : 2017-02-01 + git sha : $Format:%H$ + copyright : (C) 2021 by HeiGIT gGmbH + email : support@openrouteservice.heigit.org + ***************************************************************************/ + + This plugin provides access to openrouteservice API functionalities + (https://openrouteservice.org), developed and + maintained by the openrouteservice team of HeiGIT gGmbH, Germany. By using + this plugin you agree to the ORS terms of service + (https://openrouteservice.org/terms-of-service/). + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from typing import Dict + +from qgis.PyQt.QtCore import QCoreApplication + +from qgis.core import ( + QgsSettings, + QgsProcessingAlgorithm, + QgsProcessingParameterString, + QgsProcessingContext, + QgsProcessingFeedback, +) + +from ORStools.utils import logger + + +class ORSProviderGetConfIdAlgo(QgsProcessingAlgorithm): + def __init__(self): + super().__init__() + self.PARAMETERS: list = [ + QgsProcessingParameterString( + name="ors_provider_name", + description=self.tr("Specify unique name for your ors provider"), + ), + ] + + def group(self): + return "Configuration" + + def groupId(self): + return "configuration" + + def initAlgorithm(self, config={}): + for parameter in self.PARAMETERS: + self.addParameter(parameter) + + def processAlgorithm( + self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback + ) -> Dict[str, str]: + s = QgsSettings() + provider_name = self.parameterAsString(parameters, "ors_provider_name", context) + current_config = s.value("ORStools/config") + + msg = self.tr(f"Config with specified name not found! - {provider_name}") + result = -1 + + if provider_name in [x["name"] for x in current_config["providers"]]: + found = [ + int(j) + for j, y in {str(i): x for i, x in enumerate(current_config["providers"])}.items() + if y["name"] == provider_name + ] + if len(found) > 0: + result = found[0] + msg = self.tr(f"The provider with name: {provider_name} has the ID {str(result)}") + + feedback.pushInfo(msg) + logger.log(msg, 2) + return { + "OUTPUT": result, + "CONFIG": s.value("ORStools/config", {"providers": []})["providers"], + } + + def createInstance(self): + return self.__class__() + + def name(self): + return "config_get_provider_id_by_name" + + def displayName(self) -> str: + """ + Algorithm name shown in QGIS toolbox + :return: + """ + return self.tr("Get Provider Config ID via Algorithm (e.g. headless)") + + def tr(self, string: str, context=None) -> str: + context = context or self.__class__.__name__ + return QCoreApplication.translate(context, string) + + def flags(self): + return ( + super().flags() | QgsProcessingAlgorithm.FlagHideFromToolbox + ) # prior 3.36 but seems to work in 3.42, too diff --git a/ORStools/proc/provider_rm_conf.py b/ORStools/proc/provider_rm_conf.py new file mode 100644 index 00000000..79aebd81 --- /dev/null +++ b/ORStools/proc/provider_rm_conf.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + ORStools + A QGIS plugin + QGIS client to query openrouteservice + ------------------- + begin : 2017-02-01 + git sha : $Format:%H$ + copyright : (C) 2021 by HeiGIT gGmbH + email : support@openrouteservice.heigit.org + ***************************************************************************/ + + This plugin provides access to openrouteservice API functionalities + (https://openrouteservice.org), developed and + maintained by the openrouteservice team of HeiGIT gGmbH, Germany. By using + this plugin you agree to the ORS terms of service + (https://openrouteservice.org/terms-of-service/). + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from typing import Dict + +from qgis.PyQt.QtCore import QCoreApplication + +from qgis.core import ( + QgsSettings, + QgsProcessingAlgorithm, + QgsProcessingParameterString, + QgsProcessingContext, + QgsProcessingFeedback, +) + +from ORStools.utils import logger + + +class ORSProviderRmAlgo(QgsProcessingAlgorithm): + def __init__(self): + super().__init__() + self.PARAMETERS: list = [ + QgsProcessingParameterString( + name="ors_provider_name", + description=self.tr("Set unique name for your ors provider"), + ), + ] + + def group(self): + return "Configuration" + + def groupId(self): + return "configuration" + + def initAlgorithm(self, config={}): + for parameter in self.PARAMETERS: + self.addParameter(parameter) + + def processAlgorithm( + self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback + ) -> Dict[str, str]: + s = QgsSettings() + provider_name = self.parameterAsString(parameters, "ors_provider_name", context) + current_config = s.value("ORStools/config") + if provider_name in [x["name"] for x in current_config["providers"]]: + found = [ + int(j) + for j, y in {str(i): x for i, x in enumerate(current_config["providers"])}.items() + if y["name"] == provider_name + ] + if len(found) > 0: + del current_config["providers"][found[0]] + s.setValue("ORStools/config", {"providers": current_config["providers"]}) + s.sync() # this gives no feedback whatsover, so checking manually is necessary: + try: + with open(s.fileName(), "a"): + pass + msg = f"config deleted: {provider_name}" + except IOError as e: + msg = f"config couldn't been deleted: {e} | {s.fileName()}" + else: + msg = self.tr(f"Old config not found! - {provider_name} - and is therfore not deleted.") + + # + feedback.pushInfo(msg) + logger.log(msg, 2) + return {"OUTPUT": msg, "CONFIG": s.value("ORStools/config", {"providers": []})["providers"]} + + def createInstance(self): + return self.__class__() + + def name(self): + return "config_remove_provider" + + def displayName(self) -> str: + """ + Algorithm name shown in QGIS toolbox + :return: + """ + return self.tr("Remove Provider Config via Algorithm (e.g. headless)") + + def tr(self, string: str, context=None) -> str: + context = context or self.__class__.__name__ + return QCoreApplication.translate(context, string) + + def flags(self): + return ( + super().flags() | QgsProcessingAlgorithm.FlagHideFromToolbox + ) # prior 3.36 but seems to work in 3.42, too diff --git a/ORStools/proc/snap_layer_proc.py b/ORStools/proc/snap_layer_proc.py index edd07be5..9e606ba0 100644 --- a/ORStools/proc/snap_layer_proc.py +++ b/ORStools/proc/snap_layer_proc.py @@ -79,7 +79,7 @@ def processAlgorithm( ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) # Get profile value - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] # Get parameter values source = self.parameterAsSource(parameters, self.IN_POINTS, context) diff --git a/ORStools/proc/snap_point_proc.py b/ORStools/proc/snap_point_proc.py index 94fd2db1..039feb95 100644 --- a/ORStools/proc/snap_point_proc.py +++ b/ORStools/proc/snap_point_proc.py @@ -82,7 +82,7 @@ def processAlgorithm( ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback) # Get profile value - profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]] + profile = dict(enumerate(PROFILES))[int(parameters[self.IN_PROFILE])] # Get parameter values point = self.parameterAsPoint(parameters, self.IN_POINT, context, self.crs_out) diff --git a/tests/test_proc.py b/tests/test_proc.py index c13fc807..4b5c5a68 100644 --- a/tests/test_proc.py +++ b/tests/test_proc.py @@ -7,6 +7,7 @@ QgsFeature, QgsGeometry, QgsRectangle, + QgsSettings, ) from qgis.testing import unittest from qgis.PyQt.QtCore import QMetaType @@ -20,6 +21,7 @@ from ORStools.proc.matrix_proc import ORSMatrixAlgo from ORStools.proc.snap_layer_proc import ORSSnapLayerAlgo from ORStools.proc.snap_point_proc import ORSSnapPointAlgo +from ORStools.proc.provider_add_conf import ORSProviderAddAlgo class TestProc(unittest.TestCase): @@ -277,3 +279,35 @@ def test_snapping(self): self.assertRaises( Exception, lambda: snap_points.processAlgorithm(parameters, self.context, self.feedback) ) + + def test_add_provider(self): + parameters = { + "ors_provider_name": "TestProvider", + "ors_provider_api_key": "test_api_key", + "ors_provider_url": "https://test.example.org", + "ors_provider_timeout": 120, + "ors_provider_overwrite": False, + } + + # Create an instance of the algorithm + add_provider_algo = ORSProviderAddAlgo().create() + + # Run the algorithm + result = add_provider_algo.processAlgorithm(parameters, self.context, self.feedback) + + # Validate the result + self.assertIn("OUTPUT", result) + self.assertEqual(result["OUTPUT"], "config has been added: TestProvider") + + # Verify the provider was added to the settings + settings = QgsSettings() + config = settings.value("ORStools/config") + providers = config["providers"] + self.assertTrue(any(provider["name"] == "TestProvider" for provider in providers)) + + # Clean up by removing the test provider + config["providers"] = [ + provider for provider in providers if provider["name"] != "TestProvider" + ] + settings.setValue("ORStools/config", config) + settings.sync()