mirror of
https://git.srhtnin.garden/sarah/SaraSuite.git
synced 2026-10-14 18:28:11 +02:00
macOS support (code only, no build yet)
This commit is contained in:
1 parent
1feb6d4336
commit
ca04dcd4a7
17 files changed
+572
-126
No files matched your search
@@ -1,6 +1,6 @@
|
||||
Name = "SaraFem"
|
||||
Description = "Desktop file manager that understands SaraTag Books, and (on Linux) can stand in as the system file picker."
|
||||
Platforms = ["Linux", "Windows"]
|
||||
Platforms = ["Linux", "Windows", "macOS"]
|
||||
|
||||
# The portal reads its descriptors and preferences once at startup.
|
||||
RestartUnits = ["xdg-desktop-portal.service"]
|
||||
@@ -77,6 +77,13 @@ Name = "SaraFem"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
# macOS: an app bundle, ~/Applications/SaraFem.app (python Main.py, from the app folder).
|
||||
[[Shortcuts]]
|
||||
Platform = "macOS"
|
||||
Name = "SaraFem"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
[[Leftovers]]
|
||||
Path = "{CacheHome}/SaraFem"
|
||||
Kind = "Runtime"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Kept in sync between SaraSuite/Programs/SaraSort/ and SaraSort/Packaging/SaraSuite/.
|
||||
Name = "SaraSort"
|
||||
Parent = "SaraSortd" # a GUI for SaraSortd, listed under it
|
||||
Platforms = ["Linux", "Windows"]
|
||||
Platforms = ["Linux", "Windows", "macOS"]
|
||||
Description = "A GUI for configuring SaraSortd: a flowchart of what goes where, its service and logs, configs and templates."
|
||||
|
||||
[Source]
|
||||
@@ -31,6 +31,13 @@ Name = "SaraSort"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
# macOS: an app bundle, ~/Applications/SaraSort.app (python Main.py, from the app folder).
|
||||
[[Shortcuts]]
|
||||
Platform = "macOS"
|
||||
Name = "SaraSort"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
# Made by SaraSort itself: Config.toml, Layout.toml, Templates/.
|
||||
[[Leftovers]]
|
||||
Path = "{ConfigDir}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name = "SaraSortd"
|
||||
Description = "Sorts files from input folders into output folders by the rules in its configs. Runs in the background."
|
||||
Platforms = ["Linux", "Windows"]
|
||||
Platforms = ["Linux", "Windows", "macOS"]
|
||||
|
||||
[Version]
|
||||
File = "SaraSortd.py"
|
||||
@@ -46,10 +46,11 @@ Platform = "Linux"
|
||||
Source = "SaraSortd.service"
|
||||
Target = "{SystemdUserDir}/SaraSortd.service"
|
||||
|
||||
# Windows, and Linux without systemd (runit, OpenRC, s6, ...): run from
|
||||
# ConfigDir by ServiceRun.py, which restarts it if it fails, at login through
|
||||
# a shortcut in the Startup folder / an XDG autostart entry (SaraSuite's
|
||||
# Services.py). On Linux the same service has a Unit for systemd too.
|
||||
# Windows, macOS, and Linux without systemd (runit, OpenRC, s6, ...): run
|
||||
# from ConfigDir by ServiceRun.py, which restarts it if it fails, at login
|
||||
# through a shortcut in the Startup folder / a LaunchAgent / an XDG autostart
|
||||
# entry (SaraSuite's Services.py). On Linux the same service has a Unit for
|
||||
# systemd too.
|
||||
[[Templates]]
|
||||
Source = "../../ServiceRun.py"
|
||||
Target = "{ProgramDir}/ServiceRun.py"
|
||||
@@ -69,5 +70,12 @@ Script = "SaraSortd.py"
|
||||
WorkingDir = "{ConfigDir}"
|
||||
Option = "Autostart"
|
||||
|
||||
[[Services]]
|
||||
Platform = "macOS"
|
||||
Name = "SaraSortd"
|
||||
Script = "SaraSortd.py"
|
||||
WorkingDir = "{ConfigDir}"
|
||||
Option = "Autostart"
|
||||
|
||||
# Everything SaraSortd makes inside the sorting folders is worked out from
|
||||
# GlobalConf.toml by Hooks.py.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Kept in sync between SaraSuite/Programs/SaraTag/ and SaraTag/Packaging/SaraSuite/.
|
||||
Name = "SaraTag"
|
||||
Platforms = ["Linux", "Windows"]
|
||||
Platforms = ["Linux", "Windows", "macOS"]
|
||||
Description = "Tag files with Books (sidecars) defined by Lexicons: browse, filter and sort by tag, edit tags on many files at once."
|
||||
|
||||
[Version]
|
||||
@@ -40,6 +40,13 @@ Name = "SaraTag"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
# macOS: an app bundle, ~/Applications/SaraTag.app (python Main.py, from the app folder).
|
||||
[[Shortcuts]]
|
||||
Platform = "macOS"
|
||||
Name = "SaraTag"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
# Made by SaraTag itself. The Lexicons are your tag definitions: only tick
|
||||
# "remove configs" if you don't need them any more.
|
||||
[[Leftovers]]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Kept in sync between SaraSuite/Programs/SaraTune/ and SaraTune/Packaging/SaraSuite/.
|
||||
Name = "SaraTune"
|
||||
Platforms = ["Linux", "Windows"]
|
||||
Platforms = ["Linux", "Windows", "macOS"]
|
||||
Description = "A music player with two modes: Audio to open a file or folder and listen right away, Music for your library, a queue and saved playlists. Linux needs libmpv (Fedora: mpv-libs)."
|
||||
|
||||
[Source]
|
||||
@@ -30,6 +30,13 @@ Name = "SaraTune"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
# macOS: an app bundle, ~/Applications/SaraTune.app (python Main.py, from the app folder).
|
||||
[[Shortcuts]]
|
||||
Platform = "macOS"
|
||||
Name = "SaraTune"
|
||||
Script = "Main.py"
|
||||
Icon = "assets/Icon.png"
|
||||
|
||||
# Made by SaraTune itself.
|
||||
[[Leftovers]]
|
||||
Path = "{ConfigDir}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Kept in sync between SaraSuite/Programs/SaraView/ and SaraView/Client/Packaging/SaraSuite/.
|
||||
Name = "SaraView"
|
||||
Platforms = ["Linux", "Windows"]
|
||||
Platforms = ["Linux", "Windows", "macOS"]
|
||||
Description = "SaraView's desktop client: view and edit files in a local folder, or on a SaraView server."
|
||||
|
||||
[Source]
|
||||
@@ -32,6 +32,13 @@ Name = "SaraView"
|
||||
Script = "Client/Main.py"
|
||||
Icon = "Client/assets/Icon.png"
|
||||
|
||||
# macOS: an app bundle, ~/Applications/SaraView.app (python Client/Main.py, from the app folder).
|
||||
[[Shortcuts]]
|
||||
Platform = "macOS"
|
||||
Name = "SaraView"
|
||||
Script = "Client/Main.py"
|
||||
Icon = "Client/assets/Icon.png"
|
||||
|
||||
# Made by SaraView itself: Config.toml and Session.toml (your saved login).
|
||||
[[Leftovers]]
|
||||
Path = "{ConfigDir}"
|
||||
|
||||
+17
-8
@@ -1,8 +1,8 @@
|
||||
"""Runs a SaraSuite program as a background service where there's no systemd
|
||||
--user to do it: on Windows (started windowless with pythonw.exe), and on
|
||||
Linux with another init system (runit on Void, OpenRC, s6, dinit, ...).
|
||||
Started at login (Windows: a shortcut in the Startup folder; Linux: an XDG
|
||||
autostart entry) and when SaraSuite or the program's own GUI (e.g. SaraSort
|
||||
--user to do it: on Windows (started windowless with pythonw.exe), on macOS,
|
||||
and on Linux with another init system (runit on Void, OpenRC, s6, dinit, ...).
|
||||
Started at login (Windows: a shortcut in the Startup folder; macOS: a
|
||||
LaunchAgent; Linux: an XDG autostart entry) and when SaraSuite or the program's own GUI (e.g. SaraSort
|
||||
for SaraSortd) starts it:
|
||||
|
||||
python ServiceRun.py <Name> <Script> [<WorkingDir>]
|
||||
@@ -12,7 +12,8 @@ seconds after it fails (an exception or a non-zero exit), not after a clean
|
||||
exit or a stop; its output goes to <Name>.log. Its PID is in <Name>.pid, so
|
||||
anything can tell whether it runs, and stop it, without admin rights. Both
|
||||
files are in SaraSuite's Services folder: %LOCALAPPDATA%\\SaraSuite\\Services
|
||||
on Windows, ~/.local/share/SaraSuite/Services on Linux.
|
||||
on Windows, ~/Library/Application Support/SaraSuite/Services on macOS,
|
||||
~/.local/share/SaraSuite/Services on Linux.
|
||||
|
||||
Installed next to each program that has a service (Programs/<Name>/Manifest.toml).
|
||||
"""
|
||||
@@ -20,6 +21,7 @@ Installed next to each program that has a service (Programs/<Name>/Manifest.toml
|
||||
import os
|
||||
import runpy
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
@@ -27,6 +29,7 @@ from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
IsWindows = sys.platform == "win32"
|
||||
IsMac = sys.platform == "darwin"
|
||||
RestartSeconds = 10 # the unit's RestartSec
|
||||
MaxLogBytes = 1_000_000 # then the log starts over, the old one kept as <Name>.log.1
|
||||
Stopping = False
|
||||
@@ -35,22 +38,28 @@ Stopping = False
|
||||
def ServicesDir() -> Path:
|
||||
if IsWindows:
|
||||
Base = Path(os.environ.get("LOCALAPPDATA") or Path.home() / "AppData" / "Local")
|
||||
elif IsMac:
|
||||
Base = Path.home() / "Library" / "Application Support"
|
||||
else:
|
||||
Base = Path(os.environ.get("XDG_DATA_HOME") or Path.home() / ".local" / "share")
|
||||
return Base / "SaraSuite" / "Services"
|
||||
|
||||
|
||||
def _AlreadyRunning(PidFile: Path) -> bool:
|
||||
"""Linux: whether the PID file's process is another ServiceRun.py still
|
||||
running (not a reused PID). Windows relies on whoever starts it to check."""
|
||||
"""Linux and macOS: whether the PID file's process is another
|
||||
ServiceRun.py still running (not a reused PID). Windows relies on whoever
|
||||
starts it to check."""
|
||||
if IsWindows:
|
||||
return False
|
||||
try:
|
||||
Pid = int(PidFile.read_text().strip())
|
||||
if Pid == os.getpid():
|
||||
return False
|
||||
if IsMac: # no /proc
|
||||
Output = subprocess.run(["ps", "-o", "command=", "-p", str(Pid)], capture_output=True, text=True, timeout=15).stdout
|
||||
return "ServiceRun.py" in Output
|
||||
return b"ServiceRun.py" in Path(f"/proc/{Pid}/cmdline").read_bytes()
|
||||
except (OSError, ValueError):
|
||||
except (OSError, ValueError, subprocess.SubprocessError):
|
||||
return False
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user