feat: add Subsonic playlist sync source#139
Open
BlackJocker1995 wants to merge 1 commit into
Open
Conversation
Add a new SubsonicManager module that syncs playlists from
Subsonic-compatible servers (Navidrome, Airsonic, Gonic, original
Subsonic) to the iPod. No tracks are downloaded — this is a
playlist-only sync that references songs already in the iPod library
by db_track_id, using fuzzy (title, artist) matching with curly-quote
normalisation.
Architecture (mirrors PodcastManager pattern)
SubsonicManager/
client.py OpenSubsonic REST API client (token+salt auth)
plan_builder.py Builds SyncPlan with playlists_to_add/_to_edit
mapping.py Subsonic song → PCTrack mapping (unused, retained)
artwork.py getCoverArt + Navidrome placeholder detection
Settings & UI
Settings → Subsonic page: server URL/user/password, Test Connection,
per-playlist checkbox selection with Refresh button.
Sidebar: Sync Subsonic button.
Sync-time mapping dialog (QTabWidget, two tabs):
Tab 1 Mapping — choose which iPod playlist each Subsonic list
maps to (New / existing playlist).
Tab 2 Sync Mode — Remote→Local (Overwrite), Remote→Local (Add).
Local→Remote modes shown greyed out for future Subsonic write
support.
Sync flow
User clicks Sync Subsonic → dialog fetches playlist names →
user chooses mapping & mode → SubsonicPlanWorker builds plan
(playlists_to_add for new, playlists_to_edit for mapped with
merge/overwrite) → Sync Review preview → execute writes playlists
only (no file transfers — to_add is always empty).
Key design decisions
- Playlist-only: no song download; references existing iPod tracks.
- Fuzzy match: _match_key normalises curly quotes, case, punctuation.
- Merge semantics: positive playlist_mappings id = merge (keep existing
+ add new); negative id = overwrite (replace entirely).
- Deterministic playlist ids: blake2b(subsonic_id + name) → stable
across re-syncs.
- Credentials stored in plaintext settings.json (matches Last.fm
convention).
Tests: 123 pass (49 Subsonic-specific + 74 regression). ruff clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a new SubsonicManager module that syncs playlists from Subsonic-compatible servers (Navidrome, Airsonic, Gonic, original Subsonic) to the iPod. No tracks are downloaded — this is a playlist-only sync that references songs already in the iPod library by db_track_id, using fuzzy (title, artist) matching with curly-quote normalisation.
Architecture (mirrors PodcastManager pattern)
SubsonicManager/
client.py OpenSubsonic REST API client (token+salt auth)
plan_builder.py Builds SyncPlan with playlists_to_add/_to_edit
mapping.py Subsonic song → PCTrack mapping (unused, retained)
artwork.py getCoverArt + Navidrome placeholder detection
Settings & UI
Settings → Subsonic page: server URL/user/password, Test Connection,
per-playlist checkbox selection with Refresh button.
Sidebar: Sync Subsonic button.
Sync-time mapping dialog (QTabWidget, two tabs):
Tab 1 Mapping — choose which iPod playlist each Subsonic list
maps to (New / existing playlist).
Tab 2 Sync Mode — Remote→Local (Overwrite), Remote→Local (Add).
Local→Remote modes shown greyed out for future Subsonic write
support.
Sync flow
User clicks Sync Subsonic → dialog fetches playlist names →
user chooses mapping & mode → SubsonicPlanWorker builds plan
(playlists_to_add for new, playlists_to_edit for mapped with
merge/overwrite) → Sync Review preview → execute writes playlists
only (no file transfers — to_add is always empty).
Key design decisions
Tests: 123 pass (49 Subsonic-specific + 74 regression). ruff clean.