Skip to content

Add an engine that syncs songs to the phone - #61

Open
hatstand wants to merge 3 commits into
mainfrom
claude/project-thread-wugi27-sync-engine
Open

hatstand wants to merge 3 commits into
mainfrom
claude/project-thread-wugi27-sync-engine

Conversation

@hatstand

@hatstand hatstand commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Builds on #57 (the store for synced songs). Until that merges, review only e3a629f.

It's part of media sync, which keeps music from Clementine on the phone to play offline. The design doc describes the whole of it.

SyncEngine brings the phone's songs in line with the sync rules for one Clementine, as the Android client's engine does:

  • For each rule it asks Clementine for the rule's manifest, with the formats the phone plays, the rule's seed and its limits.
  • It downloads the songs that are new or changed into the synced songs' folder as Artist/Album/NN Title.ext, through a hidden partial file so a download cut short leaves nothing half-written. Songs with the same name get " (2)" and so on.
  • A song in several rules is downloaded once. Once every rule has synced, songs no rule wants and nobody pinned are deleted.
  • A source that's gone, or needs setting up on the computer, keeps its songs. A rule that fails keeps its songs and lets the others carry on, and a sync cut short keeps what it downloaded, so next time only the rest is fetched.

It talks to Clementine through SyncConnection, so the tests run it against a fake Clementine. Wiring it to the real connection, covers and conversions come in later pull requests. It's behind the testing features flag like the rest of media sync, so nothing changes for users yet.


Generated by Claude Code

The phone's record of what it keeps for offline listening: the sync
rules, the songs and covers it has downloaded, which rules want which
songs, and plays made on the phone, all kept per Clementine by its
server id. A song is stored once however many rules want it, and goes
once no rule wants it and it isn't pinned. It has the same tables as
the Android client's, and nothing uses it yet.

The database wrapper learns NULLs, blobs and typed rows for it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R2bAq6kZW6eyymkA3zsd4p
SyncEngine brings the phone's songs in line with the rules for one
Clementine: it asks for each rule's manifest, downloads the songs that are
new or changed into the synced songs' folder as Artist/Album/NN Title, and
deletes the songs no rule or pin wants any more. A song in several rules is
downloaded once, a rule that fails keeps its songs and lets the others carry
on, and a sync cut short keeps what it downloaded. It talks to Clementine
through SyncConnection, so the tests run it against a fake one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R2bAq6kZW6eyymkA3zsd4p
@github-actions

Copy link
Copy Markdown

Screenshots

From run 40710246868, against a real Clementine. Left: main. Right: this pull request, light and dark.

Screen main This PR This PR, dark
01_connect
02_queue
03_player
04_connection
05_settings
06_library
07_library_album
08_search
09_outputs
10_internet
11_internet_radio
fold_outer_player –

Screens at a failure

dark_failure

failure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants