The chapter order on the tonie is already fully API-controlled via SortChaptersOfTonie/PATCH. This adds an explicit way to define that order via an .m3u/.m3u8 file placed in the tonie folder, instead of relying on alphabetical filenames: - internal/syncer/playlist.go: finds a single playlist file in the tonie folder, parses its entries (ignoring blanks/#-comments), and reorders local tracks accordingly. Tracks not referenced by the playlist are appended afterwards so nothing is silently dropped; playlist entries without a matching local file are ignored. Multiple playlist files in the same folder is an error (ambiguous order). - ListLocalTracks now prefers this playlist-defined order, falling back to alphabetical filename order when no playlist is present. - Tests covering playlist ordering, unreferenced-track handling, missing entries, and the multiple-playlists error case. - README documents the .m3u/.m3u8 convention. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
toni-sync
Ein CLI-Tool zur Verwaltung von Kreativ-Tonies: Es synchronisiert lokale Audio-Ordner (z. B. exportierte Deezer-Playlists) automatisch zu den passenden Kreativ-Tonies über die inoffizielle TonieCloud-API. Geschrieben in Go, kompiliert zu einer einzigen statischen Binary - keine Laufzeit- 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 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 eine Go-Toolchain (>= 1.21) zum Bauen - danach ist das Ergebnis eine einzelne Binary ohne weitere Abhängigkeiten:
go build -o toni-sync ./cmd/toni-sync
./toni-sync --help
Oder direkt installieren (landet in $(go env GOPATH)/bin):
go install ./cmd/toni-sync
Anmeldedaten
toni-sync benötigt deine TonieCloud-Zugangsdaten (dieselben wie in der Tonies-App). Sie werden nicht gespeichert, sondern bei jedem Aufruf über Umgebungsvariablen oder interaktiven Prompt abgefragt:
export TONI_SYNC_USERNAME="you@example.com"
export TONI_SYNC_PASSWORD="********"
Alternativ: --username/--password Flags bei tonies list, init und sync.
Nutzung
1. Library-Ordner automatisch anlegen
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):
--root PATHFlag- Umgebungsvariable
TONI_SYNC_ROOT - aktuelles Arbeitsverzeichnis
3. Audiodateien einsortieren & synchronisieren
Lege deine (legal exportierten) Audiodateien in den passenden Tonie-Ordner. Die Kapitelreihenfolge wird wie folgt bestimmt:
- Mit Playlist: Liegt genau eine
.m3u/.m3u8-Datei im Tonie-Ordner, bestimmt deren Zeilenreihenfolge die Kapitelreihenfolge (Kommentare/#-Zeilen und Leerzeilen werden ignoriert, Pfade relativ zum Ordner). Dateien, die lokal existieren aber nicht in der Playlist stehen, werden trotzdem synchronisiert und ans Ende angehängt (nichts geht verloren). Einträge in der Playlist ohne passende Datei werden ignoriert. Liegen mehrere Playlist- Dateien im selben Ordner, brichtsyncmit einem Fehler ab (Reihenfolge wäre sonst mehrdeutig). - Ohne Playlist: alphabetische Dateireihenfolge, z. B.
01 - Track.mp3,02 - Track.mp3, ...
Beispiel playlist.m3u:
#EXTM3U
02 - Second Track.mp3
01 - First Track.mp3
03 - Third Track.mp3
# 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 Reihenfolge (Playlist-Datei falls vorhanden, sonst alphabetisch).
Household-/Tonie-IDs nachschlagen
Falls du die Struktur lieber manuell pflegen willst:
toni-sync tonies list
Household: Familie Müller [id=abcd-1234]
- Peppa Wutz [id=ef01-5678] (12 chapters, 3600s)
- Gute-Nacht-Geschichten [id=9876-4321] (0 chapters, 0s)
Unterstützte Audioformate
.mp3, .m4a, .aac, .ogg, .flac, .wav
Projektstruktur
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
go build ./...
go vet ./...
go test ./...