diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..c9ebf2d2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python-envs.defaultEnvManager": "ms-python.python:system" +} \ No newline at end of file diff --git a/ORStools/ORStoolsPlugin.py b/ORStools/ORStoolsPlugin.py index 2156bf8a..76e2245c 100644 --- a/ORStools/ORStoolsPlugin.py +++ b/ORStools/ORStoolsPlugin.py @@ -28,12 +28,14 @@ """ from qgis.gui import QgisInterface +from qgis.utils import iface from qgis.core import QgsApplication, QgsSettings from qgis.PyQt.QtCore import QTranslator, qVersion, QCoreApplication, QLocale import os.path from .gui import ORStoolsDialog from .proc import provider, ENDPOINTS, DEFAULT_SETTINGS +from .utils import configmanager class ORStools: @@ -49,6 +51,7 @@ def __init__(self, iface: QgisInterface) -> None: application at run time. :type iface: QgsInterface """ + self.iface = iface self.dialog = ORStoolsDialog.ORStoolsDialogMain(iface) self.provider = provider.ORStoolsProvider() @@ -80,6 +83,8 @@ def initGui(self) -> None: QgsApplication.processingRegistry().addProvider(self.provider) self.dialog.initGui() + # starts deprecated url dialog after QGIS Main-Window opened + iface.initializationCompleted.connect(self.check_provider_url) def unload(self) -> None: """remove menu entry and toolbar icons""" @@ -88,7 +93,7 @@ def unload(self) -> None: def add_default_provider_to_settings(self): s = QgsSettings() - settings = s.value("ORStools/config") + settings = configmanager.read_config() settings_keys = ["ENV_VARS", "base_url", "key", "name", "endpoints"] @@ -105,3 +110,28 @@ def add_default_provider_to_settings(self): s.setValue("ORStools/config", settings) else: s.setValue("ORStools/config", DEFAULT_SETTINGS) + + def url_is_deprecated(self) -> bool: + settings = configmanager.read_config() + + if not settings: + return False + + return settings["providers"][0]["base_url"] != DEFAULT_SETTINGS["providers"][0]["base_url"] + + def reset_provider_url(self): + """Reset the first provider URL to the default.""" + + settings = configmanager.read_config() + + if not settings: + return + + settings["providers"][0]["base_url"] = DEFAULT_SETTINGS["providers"][0]["base_url"] + + configmanager.write_config(settings) + + def check_provider_url(self): + if self.url_is_deprecated(): + if ORStoolsDialog.url_dialog_reset_button(self.iface.mainWindow()): + self.reset_provider_url() diff --git a/ORStools/gui/ORStoolsDialog.py b/ORStools/gui/ORStoolsDialog.py index 276b60a1..09d36f3e 100644 --- a/ORStools/gui/ORStoolsDialog.py +++ b/ORStools/gui/ORStoolsDialog.py @@ -153,6 +153,35 @@ def on_about_click(parent: QWidget) -> None: ) +class DeprecatedUrlDialog(QMessageBox): + """Dialog informing the user that the configured URL is deprecated.""" + + def __init__(self, parent=None): + super().__init__(parent) + + self.setIcon(QMessageBox.Warning) + self.setWindowTitle(self.tr("Deprecated URL")) + + self.setText( + self.tr( + "The configured ORS provider URL is deprecated.\n" + "Would you like to reset it to the new default URL?" + ) + ) + + self.reset_button = self.addButton(self.tr("Reset URL"), QMessageBox.AcceptRole) + + self.addButton(self.tr("Close"), QMessageBox.RejectRole) + + +def url_dialog_reset_button(parent=None) -> bool: + """Shows the deprecated URL dialog and returns bool.""" + + url_dlg = DeprecatedUrlDialog(parent) + url_dlg.exec() + return url_dlg.clickedButton() == url_dlg.reset_button + + class ORStoolsDialogMain: """Defines all mandatory QGIS things about dialog.""" @@ -535,7 +564,7 @@ def reload_geocode_completer_ors(self, request, lineEdit, text): encoded = quote(lineEdit.text()) - url = f"https://api.openrouteservice.org/geocode/search?api_key={api_key}&text={encoded}&focus.point.lat={middle.y()}&focus.point.lon={middle.x()}" + url = f"https://api.heigit.org/geocode/search?api_key={api_key}&text={encoded}&focus.point.lat={middle.y()}&focus.point.lon={middle.x()}" error_code = request.get(QNetworkRequest(QUrl(url))) if error_code == QgsBlockingNetworkRequest.ErrorCode.NoError: reply = request.reply() diff --git a/ORStools/proc/__init__.py b/ORStools/proc/__init__.py index 87e79c3f..8d22c165 100644 --- a/ORStools/proc/__init__.py +++ b/ORStools/proc/__init__.py @@ -43,7 +43,7 @@ "ORS_QUOTA": "X-Ratelimit-Limit", "ORS_REMAINING": "X-Ratelimit-Remaining", }, - "base_url": "https://api.openrouteservice.org", + "base_url": "https://api.heigit.org", "key": "", "name": "openrouteservice", "timeout": 60, diff --git a/ORStools/utils/configmanager.py b/ORStools/utils/configmanager.py index f7fa62d2..66b34afe 100644 --- a/ORStools/utils/configmanager.py +++ b/ORStools/utils/configmanager.py @@ -34,7 +34,7 @@ def read_config() -> dict: """ - Reads config.yml from file and returns the parsed dict. + Reads config and returns the parsed dict. :returns: Parsed settings dictionary. :rtype: dict diff --git a/ORStools/utils/router.py b/ORStools/utils/router.py index 802b0c57..11f5871c 100644 --- a/ORStools/utils/router.py +++ b/ORStools/utils/router.py @@ -35,7 +35,10 @@ def route_as_layer(task, provider, profile, optimize, directions): layer_out.updateFields() # if no API key is present, when ORS is selected, throw an error message - if not provider["key"] and provider["base_url"].startswith("https://api.openrouteservice.org"): + if not provider["key"] and ( + provider["base_url"].startswith("https://api.openrouteservice.org") + or provider["base_url"].startswith("https://api.heigit.org") + ): raise exceptions.InvalidKey() agent = "QGIS_ORStoolsDialog" diff --git a/tests/test_common.py b/tests/test_common.py index 3cb8f0b5..2ad35be9 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -14,7 +14,7 @@ def test_client_retry_on_over_query_limit(self): """Test that client retries on OverQueryLimit and eventually succeeds""" provider = { "ENV_VARS": None, - "base_url": "https://api.openrouteservice.org", + "base_url": "https://api.heigit.org", "key": self.api_key, "name": "openrouteservice", "timeout": 60,