Last active
June 10, 2023 20:04
-
-
Save Amourspirit/1540a52f21c020a8190b468a3e9efc16 to your computer and use it in GitHub Desktop.
Start the LibreOffice (FlatPak) in a virtual environment.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This module is used to start the LibreOffice (FlatPak) in a virtual environment. | |
When this script is run, it will start the LibreOffice (FlatPak) and include | |
the virtual environment's site-packages directory in the PYTHONPATH. | |
In short when this module is included in the root of a project with a virtual environment | |
then the LibreOffice (FlatPak) will be able to import the project's modules installed with pip. | |
Usage: | |
python office.py [options] [app] | |
Examples: | |
python office.py --nologo writer | |
Known Issues: | |
The --minimized option does not work (at least not when I tested). | |
See: | |
https://gist.github.com/Amourspirit/1540a52f21c020a8190b468a3e9efc16 | |
""" | |
from __future__ import annotations | |
from typing import List, Union | |
import argparse | |
import os | |
import sys | |
from pathlib import Path | |
from subprocess import Popen | |
# region Get Virtual Environment Location | |
def _get_root_dir() -> Path: | |
return Path(_get_virtual_env()).parent | |
def _get_virtual_env() -> Path: | |
""" | |
Gets the Virtual Environment for current python environment. | |
Raises: | |
FileNotFoundError: If no virtual environment is found. | |
Returns: | |
Path: Viruatl Environment path such as ``/home/user/my_project/.venv``. | |
""" | |
env = os.getenv("VIRTUAL_ENV", "") | |
if env: | |
return Path(env) | |
current_dir = Path(__file__).parent | |
if (current_dir / ".venv").exists(): | |
return current_dir / ".venv" | |
if (current_dir / "venv").exists(): | |
return current_dir / "venv" | |
if (current_dir / "env").exists(): | |
return current_dir / "env" | |
raise FileNotFoundError("No Virtual Environment Found") | |
def _get_site_packages_dir() -> Union[Path, None]: | |
""" | |
Gets the ``site-packages`` directory for current python environment. | |
Returns: | |
Union[Path, None]: site-packages dir if found; Otherwise, None. | |
""" | |
v_path = _get_virtual_env() | |
p_site = v_path / "Lib" / "site-packages" | |
if p_site.exists() and p_site.is_dir(): | |
return p_site | |
ver = f"{sys.version_info[0]}.{sys.version_info[1]}" | |
p_site = v_path / "lib" / f"python{ver}" / "site-packages" | |
if p_site.exists() and p_site.is_dir(): | |
return p_site | |
return None | |
# endregion Get Virtual Environment Location | |
# region Manage Arguments | |
def _add_args(parser: argparse.ArgumentParser) -> None: | |
parser.add_argument( | |
"--invisible", | |
action="store_true", | |
default=False, | |
help="""Starts in invisible mode. Neither the start-up logo nor | |
the initial program window will be visible. Application | |
can be controlled, and documents and dialogs can be | |
controlled and opened via the API. Using the parameter, | |
the process can only be ended using the taskmanager | |
(Windows) or the kill command (UNIX-like systems). It | |
cannot be used in conjunction with --quickstart. """, | |
) | |
parser.add_argument( | |
"--nologo", action="store_true", default=False, help="Disables the splash screen at program start." | |
) | |
parser.add_argument( | |
"--minimized", action="store_true", default=False, help="Starts minimized. The splash screen is not displayed." | |
) | |
parser.add_argument( | |
"--norestore", | |
action="store_true", | |
default=False, | |
help="enables restart and file recovery after a system crash.", | |
) | |
parser.add_argument( | |
"--headless", | |
action="store_true", | |
default=False, | |
help="""Starts in "headless mode" which allows using the | |
application without GUI. This special mode can be used | |
when the application is controlled by external clients | |
via the API.""", | |
) | |
parser.add_argument("app", choices=["writer", "calc", "draw", "impress", "math", "base", 'global", "web', "none"]) | |
parser.add_argument( | |
"--path-no-root", action="store_true", default=False, help="If set then the root path is not included in PYTHONPATH." | |
) | |
def _update_args(args: argparse.Namespace, args_lst: List[str]) -> None: | |
if args.invisible: | |
args_lst.append("--invisible") | |
if args.norestore: | |
args_lst.append("--norestore") | |
if args.nologo: | |
args_lst.append("--nologo") | |
if args.minimized: | |
args_lst.append("--minimized") | |
if args.headless: | |
args_lst.append("--headless") | |
if args.app != "none": | |
args_lst.append(f"--{args.app}") | |
# endregion Manage Arguments | |
def main() -> None: | |
parser = argparse.ArgumentParser(description="Office") | |
_add_args(parser) | |
args = parser.parse_args() | |
if len(sys.argv) == 1: | |
parser.print_help(sys.stderr) | |
sys.exit(1) | |
python_path = str(_get_site_packages_dir()) | |
if args.path_no_root is False: | |
python_path += f":{_get_root_dir()}" | |
open_args = [ | |
"flatpak", | |
f'--env=PYTHONPATH="{python_path}"', | |
"run", | |
"org.libreoffice.LibreOffice/x86_64/stable", | |
"--nofirststartwizard", | |
] | |
_update_args(args, open_args) | |
# display is included because of this issue when it is omitted: | |
# Set DISPLAY environment variable, use -display option | |
# or check permissions of your X-Server | |
# (See "man X" resp. "man xhost" for details) | |
open_args.append(f"--display {os.getenv('DISPLAY', ':0')}") | |
# print(" ".join(open_args)) | |
Popen(" ".join(open_args), shell=True) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment