forked from arechen/EapilSkillMarket
Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed.
62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
"""Portable LibreOffice runner for Windows, macOS and Linux."""
|
|
|
|
import os
|
|
import platform
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
|
|
def resolve_soffice_binary():
|
|
explicit = os.environ.get("SOFFICE_PATH")
|
|
if explicit:
|
|
candidate = Path(explicit).expanduser()
|
|
if candidate.is_file():
|
|
return str(candidate)
|
|
raise FileNotFoundError(f"SOFFICE_PATH does not exist: {candidate}")
|
|
names = ("soffice.com", "soffice.exe", "soffice") if platform.system() == "Windows" else ("soffice",)
|
|
for name in names:
|
|
binary = shutil.which(name)
|
|
if binary:
|
|
return binary
|
|
candidates = [Path("/Applications/LibreOffice.app/Contents/MacOS/soffice")]
|
|
if platform.system() == "Windows":
|
|
candidates = [
|
|
Path(root) / "LibreOffice/program" / name
|
|
for root in (os.environ.get("ProgramFiles"), os.environ.get("ProgramFiles(x86)")) if root
|
|
for name in ("soffice.com", "soffice.exe")
|
|
]
|
|
for candidate in candidates:
|
|
if candidate.is_file():
|
|
return str(candidate)
|
|
raise FileNotFoundError("LibreOffice not found. Install it or set SOFFICE_PATH to its executable.")
|
|
|
|
|
|
def get_soffice_env():
|
|
env = os.environ.copy()
|
|
env["PYTHONUTF8"] = "1"
|
|
if platform.system() == "Linux":
|
|
env.setdefault("SAL_USE_VCLPLUGIN", "svp")
|
|
return env
|
|
|
|
|
|
def run_soffice(args, **kwargs):
|
|
binary = resolve_soffice_binary()
|
|
kwargs.setdefault("env", get_soffice_env())
|
|
kwargs.setdefault("timeout", 120)
|
|
if any(str(arg).startswith("-env:UserInstallation=") for arg in args):
|
|
return subprocess.run([binary, *args], **kwargs)
|
|
with tempfile.TemporaryDirectory(prefix="skill-lo-", ignore_cleanup_errors=True) as profile:
|
|
profile_arg = f"-env:UserInstallation={Path(profile).resolve().as_uri()}"
|
|
return subprocess.run([binary, profile_arg, *args], **kwargs)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
raise SystemExit(run_soffice(sys.argv[1:]).returncode)
|
|
except (FileNotFoundError, subprocess.TimeoutExpired) as exc:
|
|
print(str(exc), file=sys.stderr)
|
|
raise SystemExit(1)
|