f
This commit is contained in:
@@ -217,6 +217,8 @@ def install_service_windows(
|
||||
headless: bool = True,
|
||||
detached: bool = True,
|
||||
start_on: str = "logon",
|
||||
pull: bool = False,
|
||||
workspace_root: Optional[Path] = None,
|
||||
) -> bool:
|
||||
try:
|
||||
schtasks = shutil.which("schtasks")
|
||||
@@ -226,14 +228,27 @@ def install_service_windows(
|
||||
)
|
||||
return False
|
||||
|
||||
bat = repo_root / "run-client.bat"
|
||||
# If we have a workspace root (Medios-Macina), we use it for the wrapper scripts
|
||||
base_dir = workspace_root if workspace_root else repo_root
|
||||
bat = base_dir / "run-client.bat"
|
||||
|
||||
python_exe = venv_py
|
||||
this_script = Path(__file__).resolve()
|
||||
|
||||
if not bat.exists():
|
||||
# Use escaped backslashes to avoid Python "invalid escape sequence" warnings
|
||||
content = '@echo off\n"%~dp0\\.venv\\Scripts\\python.exe" "%~dp0hydrus_client.py" %*\n'
|
||||
# Absolute paths ensure the service works regardless of where it starts
|
||||
content = f'@echo off\n"{python_exe}" "{this_script}" %*\n'
|
||||
bat.write_text(content, encoding="utf-8")
|
||||
|
||||
tr = str(bat)
|
||||
sc = "ONLOGON" if start_on == "logon" else "ONSTART"
|
||||
|
||||
task_args = "--detached "
|
||||
if headless: task_args += "--headless "
|
||||
if pull: task_args += "--pull "
|
||||
# Force the correct repo root for the service
|
||||
task_args += f'--repo-root "{repo_root}" '
|
||||
|
||||
cmd = [
|
||||
schtasks,
|
||||
"/Create",
|
||||
@@ -242,7 +257,7 @@ def install_service_windows(
|
||||
"/TN",
|
||||
service_name,
|
||||
"/TR",
|
||||
f'"{tr}"',
|
||||
f'{tr} {task_args}',
|
||||
"/RL",
|
||||
"LIMITED",
|
||||
"/F",
|
||||
@@ -283,7 +298,9 @@ def install_service_systemd(
|
||||
repo_root: Path,
|
||||
venv_py: Path,
|
||||
headless: bool = True,
|
||||
detached: bool = True
|
||||
detached: bool = True,
|
||||
pull: bool = False,
|
||||
workspace_root: Optional[Path] = None,
|
||||
) -> bool:
|
||||
try:
|
||||
systemctl = shutil.which("systemctl")
|
||||
@@ -296,15 +313,22 @@ def install_service_systemd(
|
||||
repo_root,
|
||||
venv_py,
|
||||
headless,
|
||||
detached
|
||||
detached,
|
||||
pull=pull,
|
||||
workspace_root=workspace_root
|
||||
)
|
||||
|
||||
unit_dir = Path.home() / ".config" / "systemd" / "user"
|
||||
unit_dir.mkdir(parents=True, exist_ok=True)
|
||||
unit_file = unit_dir / f"{service_name}.service"
|
||||
exec_args = f'"{venv_py}" "{str(repo_root / "run_client.py")}" --detached '
|
||||
exec_args += "--headless " if headless else "--gui "
|
||||
content = f"[Unit]\nDescription=Hydrus Client (user)\nAfter=network.target\n\n[Service]\nType=simple\nExecStart={exec_args}\nWorkingDirectory={str(repo_root)}\nRestart=on-failure\nEnvironment=PYTHONUNBUFFERED=1\n\n[Install]\nWantedBy=default.target\n"
|
||||
|
||||
this_script = Path(__file__).resolve()
|
||||
exec_args = f'"{venv_py}" "{this_script}" --detached '
|
||||
if headless: exec_args += "--headless "
|
||||
if pull: exec_args += "--pull "
|
||||
exec_args += f'--repo-root "{repo_root}" '
|
||||
|
||||
content = f"[Unit]\nDescription=Medios-Macina Client\nAfter=network.target\n\n[Service]\nType=simple\nExecStart={exec_args}\nWorkingDirectory={str(workspace_root if workspace_root else repo_root)}\nRestart=on-failure\nEnvironment=PYTHONUNBUFFERED=1\n\n[Install]\nWantedBy=default.target\n"
|
||||
unit_file.write_text(content, encoding="utf-8")
|
||||
subprocess.run([systemctl, "--user", "daemon-reload"], check=True)
|
||||
subprocess.run(
|
||||
@@ -356,14 +380,23 @@ def install_service_cron(
|
||||
repo_root: Path,
|
||||
venv_py: Path,
|
||||
headless: bool = True,
|
||||
detached: bool = True
|
||||
detached: bool = True,
|
||||
pull: bool = False,
|
||||
workspace_root: Optional[Path] = None,
|
||||
) -> bool:
|
||||
try:
|
||||
crontab = shutil.which("crontab")
|
||||
if not crontab:
|
||||
print("crontab not available; cannot install reboot cron job.")
|
||||
return False
|
||||
entry = f"@reboot {venv_py} {str(repo_root / 'run_client.py')} --detached {'--headless' if headless else '--gui'} # {service_name}\n"
|
||||
|
||||
this_script = Path(__file__).resolve()
|
||||
exec_args = f'"{venv_py}" "{this_script}" --detached '
|
||||
if headless: exec_args += "--headless "
|
||||
if pull: exec_args += "--pull "
|
||||
exec_args += f'--repo-root "{repo_root}" '
|
||||
|
||||
entry = f"@reboot {exec_args} # {service_name}\n"
|
||||
proc = subprocess.run(
|
||||
[crontab,
|
||||
"-l"],
|
||||
@@ -421,7 +454,9 @@ def install_service_auto(
|
||||
repo_root: Path,
|
||||
venv_py: Path,
|
||||
headless: bool = True,
|
||||
detached: bool = True
|
||||
detached: bool = True,
|
||||
pull: bool = False,
|
||||
workspace_root: Optional[Path] = None,
|
||||
) -> bool:
|
||||
try:
|
||||
if os.name == "nt":
|
||||
@@ -430,7 +465,9 @@ def install_service_auto(
|
||||
repo_root,
|
||||
venv_py,
|
||||
headless=headless,
|
||||
detached=detached
|
||||
detached=detached,
|
||||
pull=pull,
|
||||
workspace_root=workspace_root
|
||||
)
|
||||
else:
|
||||
if shutil.which("systemctl"):
|
||||
@@ -439,7 +476,9 @@ def install_service_auto(
|
||||
repo_root,
|
||||
venv_py,
|
||||
headless=headless,
|
||||
detached=detached
|
||||
detached=detached,
|
||||
pull=pull,
|
||||
workspace_root=workspace_root
|
||||
)
|
||||
else:
|
||||
return install_service_cron(
|
||||
@@ -447,11 +486,16 @@ def install_service_auto(
|
||||
repo_root,
|
||||
venv_py,
|
||||
headless=headless,
|
||||
detached=detached
|
||||
detached=detached,
|
||||
pull=pull,
|
||||
workspace_root=workspace_root
|
||||
)
|
||||
except Exception as exc:
|
||||
print("install_service_auto error:", exc)
|
||||
return False
|
||||
except Exception as exc:
|
||||
print("install_service_auto error:", exc)
|
||||
return False
|
||||
|
||||
|
||||
def uninstall_service_auto(service_name: str, repo_root: Path, venv_py: Path) -> bool:
|
||||
@@ -602,6 +646,11 @@ def main(argv: Optional[List[str]] = None) -> int:
|
||||
help=
|
||||
"Attempt to launch the client without showing the Qt GUI (best-effort). Default for subsequent runs; first run will show GUI unless --headless is supplied",
|
||||
)
|
||||
p.add_argument(
|
||||
"--pull",
|
||||
action="store_true",
|
||||
help="Run 'git pull' before starting the client",
|
||||
)
|
||||
p.add_argument(
|
||||
"--gui",
|
||||
action="store_true",
|
||||
@@ -660,6 +709,23 @@ def main(argv: Optional[List[str]] = None) -> int:
|
||||
else:
|
||||
repo_root = workspace_root
|
||||
|
||||
# Handle git pull update if requested
|
||||
if args.pull:
|
||||
if shutil.which("git"):
|
||||
if (repo_root / ".git").exists():
|
||||
if not args.quiet:
|
||||
print(f"Updating repository via 'git pull' in {repo_root}...")
|
||||
try:
|
||||
subprocess.run(["git", "pull"], cwd=str(repo_root), check=False)
|
||||
except Exception as e:
|
||||
print(f"Warning: git pull failed: {e}")
|
||||
else:
|
||||
if not args.quiet:
|
||||
print("Skipping 'git pull': directory is not a git repository.")
|
||||
else:
|
||||
if not args.quiet:
|
||||
print("Skipping 'git pull': 'git' not found on PATH.")
|
||||
|
||||
venv_py = find_venv_python(repo_root, args.venv, args.venv_name)
|
||||
|
||||
def _is_running_in_virtualenv() -> bool:
|
||||
@@ -817,7 +883,9 @@ def main(argv: Optional[List[str]] = None) -> int:
|
||||
repo_root,
|
||||
venv_py,
|
||||
headless=use_headless,
|
||||
detached=True
|
||||
detached=True,
|
||||
pull=args.pull,
|
||||
workspace_root=workspace_root
|
||||
)
|
||||
return 0 if ok else 6
|
||||
if args.uninstall_service:
|
||||
|
||||
Reference in New Issue
Block a user