Replace config file with folder-based mapping

Mappings between local playlist folders and Kreativ-Tonies are now
expressed purely through the filesystem instead of a YAML config:

  <root>/<household_id>/<freier_name> [id=<tonie_id>]/*.mp3

- internal/library: discovers tonie folders from this structure
  (Discover/Filter), and scaffolds it automatically from the
  TonieCloud account (Scaffold), leaving already-existing folders
  (matched by tonie id) untouched
- internal/syncer: decoupled from the removed config package via a
  plain Target{TonieID, Folder, Prune} struct
- cmd/toni-sync: new `init --root PATH` command to scaffold the
  library; `sync [FILTER] --root PATH` now discovers targets from the
  folder tree instead of a config file; removed the `config` command
  group entirely
- Unit tests for folder discovery, filtering, and scaffolding

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-08-14 12:02:54 +02:00
co-authored by Copilot
parent d003c32433
commit ae46e8f5c0
15 changed files with 580 additions and 395 deletions
+78 -52
View File
@@ -9,13 +9,33 @@ Abhängigkeiten (kein Python/pip nötig).
> **Hinweis:** toni-sync lädt selbst keine Musik von Deezer herunter. Das
> Herunterladen/Umgehen von DRM-geschützten Streams verstößt gegen die
> Nutzungsbedingungen von Deezer und ggf. gegen Urheberrecht. Lege deine
> bereits legal exportierten Audiodateien einfach in die konfigurierten
> bereits legal exportierten Audiodateien einfach in die passenden
> lokalen Ordner - toni-sync kümmert sich nur um den Abgleich mit der
> TonieCloud.
## Keine Config-Datei - die Ordnerstruktur *ist* die Konfiguration
Statt einer separaten Config-Datei wird das Mapping Playlist ↔ Kreativ-Tonie
direkt über die Ordnerstruktur abgebildet:
```
<root>/
<household_id>/
<freier_name> [id=<tonie_id>]/
01 - Track.mp3
02 - Track.mp3
```
- `<household_id>`: die Household-ID deines TonieCloud-Accounts
- `<freier_name> [id=<tonie_id>]`: frei wählbarer Name + Tonie-ID in eckigen
Klammern - der Name dient nur der Lesbarkeit, für das Mapping zählt allein
die ID
- Die alphabetische Dateireihenfolge innerhalb eines Tonie-Ordners bestimmt
die Kapitelreihenfolge auf dem Tonie
## Installation
Benötigt wird nur ein Go-Toolchain (>= 1.21) zum Bauen - danach ist das
Benötigt wird nur eine Go-Toolchain (>= 1.21) zum Bauen - danach ist das
Ergebnis eine einzelne Binary ohne weitere Abhängigkeiten:
```bash
@@ -40,66 +60,72 @@ export TONI_SYNC_USERNAME="you@example.com"
export TONI_SYNC_PASSWORD="********"
```
Alternativ: `--username`/`--password` Flags bei `tonies list` und `sync`.
Alternativ: `--username`/`--password` Flags bei `tonies list`, `init` und `sync`.
## Nutzung
### 1. Household- und Tonie-IDs herausfinden
### 1. Library-Ordner automatisch anlegen
```bash
toni-sync init --root ~/Musik/tonies
```
Legt für jede Household und jeden Kreativ-Tonie deines Accounts den
passenden Ordner an, z. B.:
```
[created] /home/you/Musik/tonies/abcd-1234/Peppa Wutz [id=ef01-5678]
[created] /home/you/Musik/tonies/abcd-1234/Gute-Nacht-Geschichten [id=9876-4321]
Library ready at /home/you/Musik/tonies
```
Bereits vorhandene Ordner (anhand der Tonie-ID erkannt, auch bei geändertem
Namen) werden nicht angefasst - deine Audiodateien bleiben unberührt.
Alternativ manuell: einfach die Ordner nach obigem Schema selbst anlegen.
### 2. Root-Ordner festlegen
Der Library-Root wird wie folgt bestimmt (erste zutreffende Option):
1. `--root PATH` Flag
2. Umgebungsvariable `TONI_SYNC_ROOT`
3. aktuelles Arbeitsverzeichnis
### 3. Audiodateien einsortieren & synchronisieren
Lege deine (legal exportierten) Audiodateien in den passenden Tonie-Ordner,
z. B. `01 - Track.mp3`, `02 - Track.mp3`, ...
```bash
# alle gefundenen Tonies synchronisieren
toni-sync sync --root ~/Musik/tonies
# nur Tonies syncen, deren Household-ID/Tonie-ID/Name den Filter enthalten
toni-sync sync peppa --root ~/Musik/tonies
# nur anzeigen, was sich ändern würde
toni-sync sync --root ~/Musik/tonies --dry-run
```
`sync` lädt neue Dateien hoch, entfernt Kapitel, die lokal nicht mehr
existieren (abschaltbar via `--no-prune`), und sortiert die Kapitel passend
zur lokalen Dateireihenfolge.
### Household-/Tonie-IDs nachschlagen
Falls du die Struktur lieber manuell pflegen willst:
```bash
toni-sync tonies list
```
Beispielausgabe:
```
Household: Familie Müller [id=abcd-1234]
- Peppa Wutz [id=ef01-5678] (12 chapters, 3600s)
- Gute-Nacht-Geschichten [id=9876-4321] (0 chapters, 0s)
```
### 2. Playlist <-> Toni Mapping konfigurieren
```bash
toni-sync config add \
--name peppa-wutz \
--household-id abcd-1234 \
--tonie-id ef01-5678 \
--folder ~/Musik/deezer-export/peppa-wutz \
--playlist-ref "https://www.deezer.com/playlist/XXXXXXXXX"
```
Weitere Kommandos:
```bash
toni-sync config list
toni-sync config remove peppa-wutz
```
Konfiguration wird standardmäßig in `~/.config/toni-sync/config.yaml`
gespeichert (überschreibbar via `--config-path` oder `TONI_SYNC_CONFIG`).
### 3. Synchronisieren
Lege deine (legal exportierten) Audiodateien in den konfigurierten Ordner,
z. B. `01 - Track.mp3`, `02 - Track.mp3`, ... - die alphabetische
Dateireihenfolge bestimmt die Kapitelreihenfolge auf dem Tonie.
```bash
# einzelnes Mapping
toni-sync sync peppa-wutz
# alle Mappings
toni-sync sync --all
# nur anzeigen, was sich ändern würde
toni-sync sync --all --dry-run
```
`sync` lädt neue Dateien hoch, entfernt Kapitel, die lokal nicht mehr
existieren (abschaltbar via `--no-prune` bei `config add`), und sortiert
die Kapitel passend zur lokalen Dateireihenfolge.
## Unterstützte Audioformate
`.mp3`, `.m4a`, `.aac`, `.ogg`, `.flac`, `.wav`
@@ -107,10 +133,10 @@ die Kapitel passend zur lokalen Dateireihenfolge.
## Projektstruktur
```
cmd/toni-sync/ CLI-Einstiegspunkt (Cobra-Kommandos)
internal/tonieapi/ Eigener, minimaler TonieCloud-API-Client
internal/config/ Laden/Speichern der Playlist<->Toni-Mappings (YAML)
internal/syncer/ Diff-/Apply-Logik zwischen lokalem Ordner und Tonie
cmd/toni-sync/ CLI-Einstiegspunkt (Cobra-Kommandos: tonies, init, sync)
internal/tonieapi/ Eigener, minimaler TonieCloud-API-Client
internal/library/ Erkennung & Scaffolding der Ordnerstruktur (Household/Tonie)
internal/syncer/ Diff-/Apply-Logik zwischen lokalem Ordner und Tonie
```
## Entwicklung / Tests