114 lines
4.2 KiB
Python
114 lines
4.2 KiB
Python
import logging
|
|
import platform
|
|
|
|
from io import StringIO
|
|
from itertools import product
|
|
from os import environ, pathsep
|
|
from pathlib import Path
|
|
from re import search
|
|
from subprocess import CalledProcessError, run
|
|
|
|
logging.getLogger(__name__).propagate=True
|
|
|
|
def find_flatpak_browser():
|
|
if platform.system() != "Linux":
|
|
return
|
|
|
|
for path_element in map(Path, environ["PATH"].split(":")):
|
|
if (path_element/"flatpak").is_file():
|
|
flatpak_bin = path_element/"flatpak"
|
|
break
|
|
else:
|
|
# flatpak is not installed
|
|
return
|
|
|
|
flatpak_apps = ("com.google.Chrome", "com.microsoft.Edge", "com.brave.Browser", "org.chromium.Chromium")
|
|
|
|
try:
|
|
flatpak_process = run(
|
|
[
|
|
str(flatpak_bin),
|
|
"list",
|
|
"--app",
|
|
"--columns=application"
|
|
],
|
|
capture_output=True,
|
|
check=True
|
|
)
|
|
except CalledProcessError as e:
|
|
pass
|
|
else:
|
|
with StringIO(flatpak_process.stdout.decode()) as flatpak_output:
|
|
installed_flatpaks = flatpak_output.readlines()[1:]
|
|
|
|
for flatpak_app in flatpak_apps:
|
|
if flatpak_app in [_.strip() for _ in installed_flatpaks]:
|
|
return f"flatpak run --filesystem={Path.home()/'.local/share/jupyter/runtime'} {flatpak_app} --start-maximized --profile-directory=Default --app=%s"
|
|
|
|
|
|
def find_browser():
|
|
# find a chromium-based browser on the system to use.
|
|
if platform.system() == "Windows":
|
|
from winreg import HKEY_CLASSES_ROOT, OpenKey, QueryValue
|
|
|
|
cmds = (
|
|
"Google/Chrome/Application/chrome.exe",
|
|
"BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
"Microsoft/Edge/Application/msedge.exe",
|
|
)
|
|
path_elements = map(Path, (environ["ProgramFiles"], environ["ProgramFiles(x86)"]))
|
|
|
|
# do a lookup of default browser command in windows registry
|
|
try:
|
|
with OpenKey(HKEY_CLASSES_ROOT, r"http\shell\open") as k:
|
|
default_browser_cmd = QueryValue(k, "command").replace('"%1"', "").replace('"', "").strip()
|
|
except FileNotFoundError:
|
|
pass
|
|
else:
|
|
# if the command looks like one of the known chromium browsers or even vaguely resembles one, return immediately with a browser command
|
|
if any(default_browser_cmd.endswith(cmd.replace("/", pathsep)) for cmd in cmds) or search(r"\\Application\\\w+\.exe$", default_browser_cmd):
|
|
return f'"{default_browser_cmd}" --start-maximized --profile-directory=Default --app=%s'
|
|
|
|
elif platform.system() == "Linux":
|
|
# prefers Google Chrome on Linux due to popularity of the browser
|
|
cmds = ("google-chrome", "microsoft-edge", "brave", "chromium")
|
|
path_elements = map(Path, environ["PATH"].split(":"))
|
|
|
|
elif platform.system() == "Darwin":
|
|
# also prefers Google Chrome on MacOS due to popularity of the browser
|
|
cmds = (
|
|
"Contents/MacOS/Google Chrome",
|
|
"Contents/MacOS/Microsoft Edge",
|
|
"Contents/MacOS/Brave Browser",
|
|
"Contents/MacOS/Chromium",
|
|
)
|
|
path_elements = [Path(f"/Applications/{Path(cmd).name}.app") for cmd in cmds]
|
|
|
|
# use the first chromium-based browser found as the browser to run Jupyter in app mode
|
|
for cmd, path_element in product(cmds, path_elements):
|
|
browser = path_element / cmd
|
|
if browser.exists():
|
|
return f'"{browser}" --start-maximized --profile-directory=Default --app=%s'
|
|
|
|
|
|
# generated if you run `jupyter lab --generate-config`, used for additional configuration
|
|
DEFAULT_CONFIG_FILE = Path.home() / ".jupyter/jupyter_lab_config.py"
|
|
|
|
# user's home will be the root path of jupyter's file explorer
|
|
c.ServerApp.root_dir = str(Path.home())
|
|
|
|
browser_cmd = find_flatpak_browser() or find_browser()
|
|
|
|
if browser_cmd:
|
|
c.ServerApp.browser = browser_cmd
|
|
else:
|
|
logging.getLogger(__name__).warning(
|
|
"No Chromium-based browser was found on this system, therefore Jupyter will run "
|
|
+ "in a new tab of the system-default browser"
|
|
)
|
|
|
|
# read and exec default config file for additional config/overrides
|
|
if DEFAULT_CONFIG_FILE.exists():
|
|
with open(DEFAULT_CONFIG_FILE, "r") as config_file:
|
|
exec(config_file.read())
|