diff --git a/Cli.py b/Cli.py index ac85b5c..51169df 100644 --- a/Cli.py +++ b/Cli.py @@ -52,7 +52,8 @@ def Run(Arguments: list[str]) -> int: for Program in Programs.values(): Current = GetStatus(Program) State = "update available" if Current.UpdateAvailable else "installed" if Current.Installed else "not installed" - print(f"{Program.Name:12} {State:16} {Current.Error}") + Name = f" {Program.Name}" if Program.Parent else Program.Name + print(f"{Name:12} {State:16} {Current.Error}") return 0 Program = Programs.get(Args.Name.lower()) diff --git a/Manifests.py b/Manifests.py index 4292e66..7a4247c 100644 --- a/Manifests.py +++ b/Manifests.py @@ -102,6 +102,7 @@ class Program: Name: str Description: str Folder: Path # the manifest's own folder + Parent: str = "" # a program this one belongs to (e.g. SaraSort -> SaraSortd): listed indented under it Git: str = "" # e.g. "{GitHost}/SaraSortd" Branch: str = "" # empty = the repo's default branch Include: list[str] = field(default_factory=lambda: ["**"]) @@ -192,6 +193,7 @@ def LoadProgram(Folder: Path) -> Program: Name=Data["Name"], Description=Data.get("Description", ""), Folder=Folder, + Parent=Data.get("Parent", ""), Git=Source["Git"], Branch=Source.get("Branch", ""), Include=Source.get("Include", ["**"]), @@ -213,8 +215,18 @@ def LoadProgram(Folder: Path) -> Program: def LoadPrograms() -> list[Program]: - return [ + """Alphabetical, with each program's children (Parent = its Name) right + after it. A child whose parent isn't there keeps its own place.""" + Loaded = [ LoadProgram(Folder) for Folder in sorted(ManifestsDir.iterdir()) if (Folder / "Manifest.toml").exists() ] + Names = {Current.Name for Current in Loaded} + Ordered = [] + for Current in Loaded: + if Current.Parent in Names: + continue + Ordered.append(Current) + Ordered.extend(Child for Child in Loaded if Child.Parent == Current.Name) + return Ordered diff --git a/ProgramCard.py b/ProgramCard.py index 0d0aa6d..69020ee 100644 --- a/ProgramCard.py +++ b/ProgramCard.py @@ -8,6 +8,8 @@ from Core import ChipButtonStyle, Palette from Installer import RemovalPlan, Status from Manifests import Program +ChildIndent = 40 + class ProgramCard(ft.Container): def __init__( @@ -70,6 +72,8 @@ class ProgramCard(ft.Container): border=ft.Border.all(1, Palette.Surface1), border_radius=8, padding=16, + # A program that belongs to another (Parent) sits indented under it. + margin=ft.Margin.only(left=ChildIndent) if Program.Parent else None, ) def _SetChip(self, Text: str, Color: str) -> None: diff --git a/Programs/SaraSort/Manifest.toml b/Programs/SaraSort/Manifest.toml new file mode 100644 index 0000000..52aa6d1 --- /dev/null +++ b/Programs/SaraSort/Manifest.toml @@ -0,0 +1,27 @@ +# Kept in sync between SaraSuite/Programs/SaraSort/ and SaraSort/Packaging/SaraSuite/. +Name = "SaraSort" +Parent = "SaraSortd" # a GUI for SaraSortd, listed under it +Description = "A GUI for configuring SaraSortd: a flowchart of what goes where, its service and logs, configs and templates." + +[Source] +Git = "{GitHost}/SaraSort" +Include = ["*.py", "requirements.txt", "assets/**"] +Exclude = ["Packaging"] + +[Python] +RequirementsFile = "requirements.txt" + +[[Templates]] +Source = "Launch.sh" +Target = "{AppDir}/Packaging/Launch.sh" +Executable = true + +[[Templates]] +Source = "SaraSort.desktop" +Target = "{ApplicationsDir}/SaraSort.desktop" + +# Made by SaraSort itself: Config.toml, Layout.toml, Templates/. +[[Leftovers]] +Path = "{ConfigDir}" +Kind = "Config" +Note = "SaraSort's settings, flowchart layout and your templates" diff --git a/Programs/SaraSort/Templates/Launch.sh b/Programs/SaraSort/Templates/Launch.sh new file mode 100755 index 0000000..514065b --- /dev/null +++ b/Programs/SaraSort/Templates/Launch.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# Desktop-entry launcher: resolves the venv relative to this script rather +# than the caller's cwd, since .desktop Exec= lines are invoked with no +# guaranteed working directory. +cd "$(dirname "$(readlink -f "$0")")/.." || exit 1 +exec .venv/bin/python Main.py "$@" diff --git a/Programs/SaraSort/Templates/SaraSort.desktop b/Programs/SaraSort/Templates/SaraSort.desktop new file mode 100644 index 0000000..079c9a7 --- /dev/null +++ b/Programs/SaraSort/Templates/SaraSort.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Application +Name=SaraSort +Comment=Configure SaraSortd, the file sorting daemon +Exec={AppDir}/Packaging/Launch.sh +Icon={AppDir}/assets/Icon.png +Terminal=false +Categories=Utility; +StartupNotify=true diff --git a/README.md b/README.md index d624794..0aa5575 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ Targets, templates and `Set` values can use `{Variables}`: `Name`, `GitHost`, `H ```toml Name = "Example" Description = "Shown on the program's card." +Parent = "SaraSortd" # optional: listed (indented) under that program RestartUnits = ["xdg-desktop-portal.service"] # try-restarted after install/update/remove [Version] # optional, shown on the card