mirror of
https://git.srhtnin.garden/sarah/SaraSort.git
synced 2026-10-14 18:48:11 +02:00
macOS support
This commit is contained in:
1 parent
5613f4f8fe
commit
1bd37db1ba
8 files changed
+113
-29
No files matched your search
+28
-5
@@ -2,19 +2,21 @@
|
||||
and its logs. SaraSortd's own log files are read from its LogDir.
|
||||
|
||||
Linux with systemd: its systemd user unit (systemctl / journalctl).
|
||||
Windows, and Linux without systemd (runit, OpenRC, s6, ...): SaraSuite runs
|
||||
Windows, macOS, and Linux without systemd (runit, OpenRC, s6, ...): SaraSuite runs
|
||||
it itself (its Services.py), and this does the same:
|
||||
- it runs as `python ServiceRun.py SaraSortd SaraSortd.py <ConfigDir>`
|
||||
(pythonw.exe on Windows); ServiceRun.py restarts it if it fails, keeps its
|
||||
output in SaraSuite's Services folder as SaraSortd.log (the "Service log"
|
||||
here) and records its PID in SaraSortd.pid (that's how "running" is told);
|
||||
- autostart is a shortcut to that command in the Startup folder (Windows)
|
||||
or an XDG autostart entry, ~/.config/autostart/SaraSortd.desktop (Linux).
|
||||
- autostart is a shortcut to that command in the Startup folder (Windows),
|
||||
a LaunchAgent, ~/Library/LaunchAgents/srhtnin.SaraSortd.plist (macOS), or
|
||||
an XDG autostart entry, ~/.config/autostart/SaraSortd.desktop (Linux).
|
||||
Unit is the systemd unit name ("SaraSortd.service"); run by SaraSuite, the
|
||||
service is called the same without ".service".
|
||||
"""
|
||||
|
||||
import os
|
||||
import plistlib
|
||||
import re
|
||||
import signal
|
||||
import subprocess
|
||||
@@ -23,7 +25,7 @@ from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from Core import AutostartDir, ChildEnvironment, ConfigHome, DataHome, IsWindows, LoadConfig, RunBySaraSuite
|
||||
from Core import AutostartDir, ChildEnvironment, ConfigHome, DataHome, Home, IsMac, IsWindows, LoadConfig, RunBySaraSuite
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -48,7 +50,7 @@ def _Run(Arguments: list[str], Timeout: int = 15) -> subprocess.CompletedProcess
|
||||
creationflags=_NoWindow)
|
||||
|
||||
|
||||
# --- Run by SaraSuite (Windows; Linux without systemd) ------------------------------------------
|
||||
# --- Run by SaraSuite (Windows; macOS; Linux without systemd) ------------------------------------------
|
||||
|
||||
|
||||
def _Name(Unit: str) -> str:
|
||||
@@ -62,6 +64,8 @@ def _ServicesFile(Name: str, Suffix: str) -> Path:
|
||||
def _AutostartFile(Name: str) -> Path:
|
||||
if IsWindows:
|
||||
return ConfigHome / "Microsoft" / "Windows" / "Start Menu" / "Programs" / "Startup" / f"{Name}.lnk"
|
||||
if IsMac:
|
||||
return Home / "Library" / "LaunchAgents" / f"srhtnin.{Name}.plist"
|
||||
return AutostartDir / f"{Name}.desktop"
|
||||
|
||||
|
||||
@@ -85,6 +89,11 @@ def _Pid(Name: str) -> str:
|
||||
Pid = int(_ServicesFile(Name, ".pid").read_text().strip())
|
||||
except (OSError, ValueError):
|
||||
return ""
|
||||
if IsMac: # no /proc: ask ps for its command line
|
||||
try:
|
||||
return str(Pid) if "ServiceRun.py" in _Run(["ps", "-o", "command=", "-p", str(Pid)]).stdout else ""
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return ""
|
||||
if not IsWindows:
|
||||
try:
|
||||
return str(Pid) if b"ServiceRun.py" in Path(f"/proc/{Pid}/cmdline").read_bytes() else ""
|
||||
@@ -134,6 +143,18 @@ def _AutostartEntry(Python: Path, Arguments: list[str], Name: str) -> str:
|
||||
)
|
||||
|
||||
|
||||
def _LaunchAgent(Python: Path, Arguments: list[str], Name: str, Folder: Path) -> bytes:
|
||||
"""The same LaunchAgent SaraSuite writes (its MacSupport.LaunchAgent)."""
|
||||
return plistlib.dumps({
|
||||
"Label": f"srhtnin.{Name}",
|
||||
"ProgramArguments": [str(Python), *Arguments],
|
||||
"WorkingDirectory": str(Folder),
|
||||
"RunAtLoad": True,
|
||||
"ProcessType": "Background",
|
||||
"StandardErrorPath": str(Home / "Library" / "Logs" / f"{Name}.launchd.log"),
|
||||
})
|
||||
|
||||
|
||||
def _OwnControl(Name: str, Action: str) -> str:
|
||||
Python, Arguments, Folder = _Command(Name)
|
||||
try:
|
||||
@@ -169,6 +190,8 @@ def _OwnControl(Name: str, Action: str) -> str:
|
||||
Quoted = " ".join(f'"{Item}"' if " " in Item or "\\" in Item else Item for Item in Arguments)
|
||||
pylnk3.for_file(str(Python), str(Entry), arguments=Quoted, work_dir=str(Folder),
|
||||
description=f"{Name} (background service)")
|
||||
elif IsMac:
|
||||
Entry.write_bytes(_LaunchAgent(Python, Arguments, Name, Folder))
|
||||
else:
|
||||
Entry.write_text(_AutostartEntry(Python, Arguments, Name))
|
||||
elif Action == "disable":
|
||||
|
||||
Reference in new issue
Block a user