webui: open browser in new window
All checks were successful
checks-impure / test (pull_request) Successful in 21s
checks / test (pull_request) Successful in 1m30s

This gets closer to an app like feeling
This commit is contained in:
DavHau 2023-10-04 16:54:24 +02:00
parent 018590d30b
commit 544322ee6e
3 changed files with 51 additions and 14 deletions

View File

@ -2,32 +2,64 @@ import argparse
import logging import logging
import multiprocessing as mp import multiprocessing as mp
import os import os
import shutil
import signal
import socket import socket
import subprocess import subprocess
import sys import sys
import syslog import syslog
import tempfile
import time import time
import urllib.request import urllib.request
import webbrowser
from contextlib import ExitStack, contextmanager from contextlib import ExitStack, contextmanager
from pathlib import Path from pathlib import Path
from threading import Thread from threading import Thread
from typing import Iterator from typing import Iterator
# XXX: can we dynamically load this using nix develop? # XXX: can we dynamically load this using nix develop?
from uvicorn import run import uvicorn
from clan_cli.errors import ClanError
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def defer_open_browser(base_url: str) -> None: def open_browser(base_url: str) -> None:
for i in range(5): with tempfile.TemporaryDirectory() as tmpdir:
for i in range(5):
try:
urllib.request.urlopen(base_url + "/health")
break
except OSError:
time.sleep(i)
proc = _open_browser(base_url, tmpdir)
try: try:
urllib.request.urlopen(base_url + "/health") proc.wait()
break print("Browser closed")
except OSError: os.kill(os.getpid(), signal.SIGINT)
time.sleep(i) finally:
webbrowser.open(base_url) proc.kill()
proc.wait()
def _open_browser(base_url: str, tmpdir: str) -> subprocess.Popen:
for browser in ("firefox", "iceweasel", "iceape", "seamonkey"):
if shutil.which(browser):
cmd = [
browser,
"-kiosk",
"-private-window",
"--new-instance",
"--profile",
tmpdir,
base_url,
]
print(" ".join(cmd))
return subprocess.Popen(cmd)
for browser in ("chromium", "chromium-browser", "google-chrome", "chrome"):
if shutil.which(browser):
return subprocess.Popen([browser, f"--app={base_url}"])
raise ClanError("No browser found")
@contextmanager @contextmanager
@ -84,9 +116,9 @@ def start_server(args: argparse.Namespace) -> None:
open_url = f"http://[{args.host}]:{args.port}" open_url = f"http://[{args.host}]:{args.port}"
if not args.no_open: if not args.no_open:
Thread(target=defer_open_browser, args=(open_url,)).start() Thread(target=open_browser, args=(open_url,)).start()
run( uvicorn.run(
"clan_cli.webui.app:app", "clan_cli.webui.app:app",
host=args.host, host=args.host,
port=args.port, port=args.port,
@ -161,7 +193,7 @@ def set_out_to_syslog() -> None: # type: ignore
def _run_socketfile(socket_file: Path, debug: bool) -> None: def _run_socketfile(socket_file: Path, debug: bool) -> None:
set_out_to_syslog() set_out_to_syslog()
run( uvicorn.run(
"clan_cli.webui.app:app", "clan_cli.webui.app:app",
uds=str(socket_file), uds=str(socket_file),
access_log=debug, access_log=debug,

View File

@ -10,6 +10,7 @@
, pytest-cov , pytest-cov
, pytest-subprocess , pytest-subprocess
, pytest-parallel , pytest-parallel
, pytest-timeout
, python3 , python3
, runCommand , runCommand
, setuptools , setuptools
@ -44,6 +45,7 @@ let
pytest-cov pytest-cov
pytest-subprocess pytest-subprocess
pytest-parallel pytest-parallel
pytest-timeout
openssh openssh
git git
gnupg gnupg

View File

@ -5,15 +5,17 @@ import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
import pytest
from ports import PortFunction from ports import PortFunction
@pytest.mark.timeout(10)
def test_start_server(unused_tcp_port: PortFunction, temporary_dir: Path) -> None: def test_start_server(unused_tcp_port: PortFunction, temporary_dir: Path) -> None:
port = unused_tcp_port() port = unused_tcp_port()
fifo = temporary_dir / "fifo" fifo = temporary_dir / "fifo"
os.mkfifo(fifo) os.mkfifo(fifo)
notify_script = temporary_dir / "notify.sh" notify_script = temporary_dir / "firefox"
bash = shutil.which("bash") bash = shutil.which("bash")
assert bash is not None assert bash is not None
notify_script.write_text( notify_script.write_text(
@ -25,7 +27,8 @@ echo "1" > {fifo}
notify_script.chmod(0o700) notify_script.chmod(0o700)
env = os.environ.copy() env = os.environ.copy()
env["BROWSER"] = str(notify_script) print(str(temporary_dir.absolute()))
env["PATH"] = ":".join([str(temporary_dir.absolute())] + env["PATH"].split(":"))
with subprocess.Popen( with subprocess.Popen(
[sys.executable, "-m", "clan_cli.webui", "--port", str(port)], env=env [sys.executable, "-m", "clan_cli.webui", "--port", str(port)], env=env
) as p: ) as p: