diff --git a/jupyter_remote_qgis_proxy/handlers.py b/jupyter_remote_qgis_proxy/handlers.py index e1d527b..a3ce473 100644 --- a/jupyter_remote_qgis_proxy/handlers.py +++ b/jupyter_remote_qgis_proxy/handlers.py @@ -1,23 +1,20 @@ -import os -import logging - from jupyter_remote_desktop_proxy.handlers import DesktopHandler from tornado import web +from tornado.ioloop import IOLoop -from .qgis.utils import open_qgis - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) +from .utils import is_process_running, start_qgis class QgisHandler(DesktopHandler): @web.authenticated async def get(self): - logging.info("Starting QGIS") + await super().get() action = self.get_argument("action", None) url = self.get_argument("url", None) project_name = self.get_argument("project_name", "new project") layer_name = self.get_argument("layer_name", "Vector Layer") - if action and url: - open_qgis(action, url=url, project_name=project_name, layer_name=layer_name) - await super().get() + + if not is_process_running("websockify"): + IOLoop.current().call_later(3, lambda:start_qgis(action, url, project_name, layer_name)) + + diff --git a/jupyter_remote_qgis_proxy/logger.py b/jupyter_remote_qgis_proxy/logger.py new file mode 100644 index 0000000..f12c0c7 --- /dev/null +++ b/jupyter_remote_qgis_proxy/logger.py @@ -0,0 +1,5 @@ +import logging + + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) diff --git a/jupyter_remote_qgis_proxy/qgis/scripts/zoom.py b/jupyter_remote_qgis_proxy/qgis/scripts/zoom.py index 5a8d70b..1ee9981 100644 --- a/jupyter_remote_qgis_proxy/qgis/scripts/zoom.py +++ b/jupyter_remote_qgis_proxy/qgis/scripts/zoom.py @@ -5,6 +5,7 @@ # Get the QGIS interface iface = qgis.utils.iface +iface.mainWindow().showMaximized() # Get the active map canvas canvas = iface.mapCanvas() diff --git a/jupyter_remote_qgis_proxy/qgis/utils.py b/jupyter_remote_qgis_proxy/qgis/utils.py index 9f72865..9235ef8 100644 --- a/jupyter_remote_qgis_proxy/qgis/utils.py +++ b/jupyter_remote_qgis_proxy/qgis/utils.py @@ -28,4 +28,4 @@ def open_qgis(action="add_vector_layer", **kwargs): } project_file_content = action_template.format(**layer_args) f.write(project_file_content) - subprocess.Popen(["qgis", "--nologo", "--project", file_path, "--code", zoom_script_path, "--code", maximize_script_path]) + subprocess.Popen(["qgis", "--nologo", "--project", file_path, "--code", zoom_script_path]) diff --git a/jupyter_remote_qgis_proxy/utils.py b/jupyter_remote_qgis_proxy/utils.py new file mode 100644 index 0000000..70aecfc --- /dev/null +++ b/jupyter_remote_qgis_proxy/utils.py @@ -0,0 +1,50 @@ +import psutil +import time + +from .logger import logger +from .qgis.utils import open_qgis + + +def is_process_running(process_name): + """ + Checks if a process with the given name is running. + """ + for process in psutil.process_iter(): + try: + if process.name().lower() == process_name.lower(): + return True + except (psutil.NoSuchProcess, psutil.AccessDenied): + pass + return False + + +def wait_for_condition(condition, timeout=10): + """ + Waits for a condition to be true for a specified timeout. + + Args: + condition: A callable that returns True when the condition is met. + timeout: The maximum time in seconds to wait (default: 10). + + Returns: + True if the condition becomes true before the timeout, False otherwise. + """ + start_time = time.time() + while time.time() - start_time < timeout: + if condition(): + return True + time.sleep(0.5) + return False + + +def start_qgis(action, url, project_name, layer_name): + """Starts QGIS and waits for websockify to start if necessary.""" + logger.info("Waiting for websockify to start") + is_websockify_running = lambda: is_process_running("websockify") + running = wait_for_condition(is_websockify_running, timeout=10) + logger.info(f"Websockify is running: {running}") + logger.info("Starting QGIS") + if action and url: + open_qgis(action, url=url, project_name=project_name, layer_name=layer_name) + elif not is_process_running("qgis"): + open_qgis()