Skip to content

Commit

Permalink
wait for websockify to start before starting qgis
Browse files Browse the repository at this point in the history
Related to jupyterhub/jupyter-remote-desktop-proxy#105.

When QGIS starts before VNC connection is established, the QGIS process doesn't get attached to the VNC session and runs in the background.

We wait for the VNC connection to be established to make sure the QGIS GUI shows up in the VNC session.
  • Loading branch information
sunu committed Jun 5, 2024
1 parent af28295 commit 772c016
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 12 deletions.
19 changes: 8 additions & 11 deletions jupyter_remote_qgis_proxy/handlers.py
Original file line number Diff line number Diff line change
@@ -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))


5 changes: 5 additions & 0 deletions jupyter_remote_qgis_proxy/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import logging


logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
1 change: 1 addition & 0 deletions jupyter_remote_qgis_proxy/qgis/scripts/zoom.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

# Get the QGIS interface
iface = qgis.utils.iface
iface.mainWindow().showMaximized()

# Get the active map canvas
canvas = iface.mapCanvas()
Expand Down
2 changes: 1 addition & 1 deletion jupyter_remote_qgis_proxy/qgis/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
50 changes: 50 additions & 0 deletions jupyter_remote_qgis_proxy/utils.py
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit 772c016

Please sign in to comment.