From 1fba950284aba7d0ced7bd758726a28d0154e5d4 Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Sun, 7 Jun 2026 23:18:21 -0700 Subject: [PATCH] Release 2.6.8: version bump + docker-publish default + What's New changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _SOULSYNC_BASE_VERSION 2.6.7 → 2.6.8 (drives the UI version + release notes). - docker-publish.yml workflow_dispatch default version_tag → 2.6.8 (the manual tagged-release publish; run the workflow to push :2.6.8 + announce). - helper.js WHATS_NEW: new 2.6.8 block (18 entries) covering everything since 2.6.7 — Blocklist, the #801 retry overhaul, Download Origins, Expired Download Cleaner, Lyrics Filler + re-tag lyrics, Spotify-token-in-DB deauth fix, #705 release-date gate, YouTube-OOTB, Navidrome #809, the dashboard/ modal visual pass, #767 reorganize edition, #806 cover art, cover-art read-only handling, #804 import fixes, artist-page discography + #808, iTunes-id repair, torrent stall handling, paste-MBID match, and smaller fixes. Surfaces automatically in What's New + version release notes now that the build version is 2.6.8. --- .github/workflows/docker-publish.yml | 4 ++-- web_server.py | 2 +- webui/static/helper.js | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index e5f75e23..70344823 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -9,9 +9,9 @@ on: workflow_dispatch: inputs: version_tag: - description: 'Version tag (e.g. 2.6.7)' + description: 'Version tag (e.g. 2.6.8)' required: true - default: '2.6.7' + default: '2.6.8' jobs: build-and-push: diff --git a/web_server.py b/web_server.py index f54fb24d..56b1566e 100644 --- a/web_server.py +++ b/web_server.py @@ -40,7 +40,7 @@ logger = setup_logging(_log_level, _log_path) # App version — single source of truth for backup metadata, system-info, update check, etc. # Semver: MAJOR.MINOR.PATCH. Bump at each dev→main release. -_SOULSYNC_BASE_VERSION = "2.6.7" +_SOULSYNC_BASE_VERSION = "2.6.8" def _build_version_string(): """Append short commit hash to version when available (e.g. 2.35+abc1234).""" diff --git a/webui/static/helper.js b/webui/static/helper.js index 7bc96f1a..b512605c 100644 --- a/webui/static/helper.js +++ b/webui/static/helper.js @@ -3413,6 +3413,28 @@ function closeHelperSearch() { // projects that span multiple commits before shipping. Strip the flag at // release time and add a real `date:` line at the top of the version block. const WHATS_NEW = { + '2.6.8': [ + { date: 'June 7, 2026 — 2.6.8 release' }, + { title: 'Blocklist — never download an artist, album, or track again', desc: 'a proper artist / album / track blocklist, reachable from the Blocklist button on the Watchlist page. Add an entry by pasting a Spotify / iTunes / Deezer / MusicBrainz link or ID; SoulSync resolves it and, in the background, matches it across your other sources so a ban added by Spotify ID also blocks the same thing arriving via Deezer or Tidal. Bans are enforced everywhere it matters: the wishlist never re-adds a blocked item, the download queue (playlist sync / album / discography) skips them, and starting a manual download of a blocked artist asks for a "download anyway?" confirm first. Profile-scoped, and your old Discovery blacklist is migrated in automatically.', page: 'watchlist' }, + { title: 'Download retry overhaul — exhaust every candidate before giving up (#801)', desc: 'when a download fails AcoustID or integrity verification, SoulSync no longer just quarantines and stops. It now retries the next-best candidate, works through every query for a source from cache first (no needless re-searching), and when a whole source is exhausted it switches to the next source instead of failing the track. New opt-in knobs (collapsible tiles on the Downloads settings): retry-next-candidate-on-mismatch, a per-source exhaustive retry budget, and a last-resort "accept a repeated version mismatch" fallback for stubborn tracks. A race guard also stops stale duplicate completion calls from re-quarantining a file after you have already moved on.', page: 'downloads' }, + { title: 'Download Origins — see (and delete) exactly what your syncs pulled in', desc: 'a new Download Origins view (button on the Watchlist page) records every track SoulSync downloaded on your behalf and why — which watchlist artist or which playlist sync triggered it. Browse the full provenance list and delete any of it (file + library entry) in one place. This also powers the new Expired Download Cleaner below.', page: 'watchlist' }, + { title: 'Expired Download Cleaner — retention-based cleanup of synced downloads', desc: 'a new Library Maintenance job that cleans up downloads brought in by the watchlist / playlist sync once they pass a retention window you set per origin (off, or 1–4 weeks / 2 / 3 / 6 months). It is deliberately careful: it never proposes deleting something still in a playlist you actively mirror or an artist you still watch, or anything you have played more than once. Dry run is ON by default — it lists what it would remove as findings for you to review and delete — and you can flip it to fully automatic. Default off; only ever touches downloads tracked from this version forward, never your existing or manual library.', page: 'dashboard' }, + { title: 'Lyrics Filler — fill in missing .lrc lyrics across your library (Sokhi)', desc: 'a new Library Maintenance job that finds tracks with no lyrics and — checking LRClib first — only flags the ones lyrics actually exist for, so instrumentals are never surfaced. Review and apply to write a synced .lrc and embed the lyrics. The Library Re-tag tool also gains a Lyrics option, so it can fetch/refresh lyrics alongside tags and cover art in the same pass.', page: 'dashboard' }, + { title: 'Spotify daily Docker de-auth — fixed (wolf39us)', desc: 'Spotify auth tokens now live in the database instead of a file the container could lose, so your Spotify connection survives daily Docker restarts instead of silently logging out and stalling enrichment. (Tokens are also never shipped to the browser.)', page: 'settings' }, + { title: 'Release-date gate — unreleased tracks stop burning cycles (#705)', desc: 'tracks with a future release date no longer get stuck cycling through the wishlist or Fresh Tape trying to download something that does not exist yet. They are held until their release date arrives, then processed normally.', page: 'sync' }, + { title: 'YouTube works out of the box', desc: 'the Docker image now ships a JavaScript runtime and a nightly yt-dlp, so YouTube streams and music videos work immediately without manual setup or hitting yt-dlp signature breakage.', page: 'settings' }, + { title: 'Navidrome playback for un-mounted libraries (#809)', desc: 'Navidrome tracks now play even when the music library is not mounted on the SoulSync container\'s disk — it streams them through the Navidrome server\'s own API instead of failing. The crossfade preload path streams the same way, so gapless/crossfade works for those tracks too.', page: 'dashboard' }, + { title: 'Dashboard + download/discovery modals — a living visual pass', desc: 'a big visual upgrade. The download and discovery modals were revamped with dashboard-grade motion and live per-track row states (pills that animate only while a track is actually working). The dashboard worker orbs and rate monitor got a depth + life pass — orbital depth, telemetry comet tails and impact ripples, a sleep/wake cycle when idle, a daily-budget ring around the Spotify avatar, rate-limit bans that visibly count down, and VU-style peak-hold ticks — all moved to GPU/compositor-only so it is smoother, not heavier.', page: 'dashboard' }, + { title: 'Reorganize picks the right album edition (#767)', desc: 'reorganize / track-number repair no longer mislabels a single as track 2 of a 10-track deluxe. When the edition it is about to use clearly does not fit your actual files (e.g. one file vs a 10-track deluxe), it finds the correct edition and pins it. Well-fitting albums are untouched.', page: 'library' }, + { title: 'Cover art at native resolution + correct editions (#806)', desc: 'MusicBrainz cover art is now fetched at native resolution (Cover Art Archive /front) instead of a downscaled thumbnail, and a numeric edition difference is treated as a different release — so "Vol.4" stops getting served "Vol.4.5"\'s cover. Includes an archive.org outage cooldown so a CAA outage does not stall imports.', page: 'library' }, + { title: 'Cover Art Filler: fix album OR artist art independently + clearer read-only errors', desc: 'the Cover Art Filler can now repair album art or artist art on their own instead of always doing both (Pache711). And when your music folder is genuinely read-only, it now says so accurately — read-only detection comes from an actual write attempt rather than mount flags (which union/NFS/mergerfs setups misreport), so a writable library is never falsely blocked, and the message names real causes (a :ro volume, a read-only host/NFS/SMB mount) instead of guessing.', page: 'dashboard' }, + { title: 'Import: stop wiping good metadata + clearer rejections (#804)', desc: 'fixed an import bug that could blank every tag on an already-tagged file and file it under "Unknown Artist" when metadata enhancement hit a transient error — clean/matched imports now keep their existing tags on failure. Files you import/sort yourself are also no longer false-quarantined for a small duration difference against a re-resolved release (that check is for catching broken downloads, not your own files). And the import window now shows each failed file\'s reason inline instead of just "Failed".', page: 'dashboard' }, + { title: 'Artist pages show your full discography again', desc: 'fixed artist-detail pages showing only a handful of albums for a heavily-watched artist — background watchlist probes were poisoning the album-list cache. Also fixed missing tracks on an artist page where album-context qualifiers were blocking library-presence matching (#808).', page: 'library' }, + { title: 'Watchlist iTunes IDs: backfill that actually works + corruption repair', desc: 'the watchlist iTunes-ID backfill never ran in the normal wiring; it now uses the registry client and works. A one-time repair also fixes artists whose stored "iTunes ID" was actually a Deezer ID. Plus the Deezer-search → Tidal-download multi-artist flow is pinned end to end (Netti93).', page: 'watchlist' }, + { title: 'Torrents: stalled-download handling (noldevin)', desc: 'a dead magnet no longer holds a download worker hostage for six hours — stalled torrents are abandoned, and the stall thresholds are now exposed as UI settings you can tune.', page: 'settings' }, + { title: 'Manual match by pasted MusicBrainz link/ID (Ashh)', desc: 'the manual-match tool now accepts a pasted MusicBrainz ID or URL to match a track directly to that exact entity.', page: 'library' }, + { title: 'Smaller fixes', desc: 'fixed the Stream button never learning its stream was ready (a 2.6.5 regression); Library Re-tag cover-mode scans no longer produce unappliable "(0 track(s))" findings, and the re-tag findings now show each track\'s real filename; mirrored "Liked Songs" stops 400-ing on every auto-refresh (wolf39us); downloads now pause all enrichment workers (and discovery pauses the heavy five) so imports stay fast; Genius rate-limits fail fast instead of napping the import pipeline; and an on-demand memory-growth diagnostic was added for chasing leaks (#802).' }, + ], '2.6.7': [ { date: 'June 5, 2026 — 2.6.7 release' }, { title: 'Spotify Free — Spotify metadata with no credentials, and a rate-limit bridge (#798)', desc: 'a new "Spotify Free (no credentials)" metadata source. Pick it in Settings → Metadata to get Spotify search + enrichment without connecting a Spotify account (it uses the public web-player data via the optional spotapi package). It also works as a rate-limit bridge for connected users: if your real Spotify auth gets rate-limited, enrichment automatically falls through to the free source instead of stalling, then returns to your real auth once the ban lifts. The worker can be resumed mid-ban, the dashboard now shows "Running (Spotify Free)" instead of looking stuck, and the daily-API budget never pauses a Spotify-Free user — free work isn\'t counted against it, and once your real-API budget for the day is spent the worker switches to free (uncapped) for the rest of the day instead of pausing, reverting to your real auth on the daily reset. Opt-in — nothing changes unless you select it.', page: 'settings' },