From ad0eda357508fa60bf4be904fbf5036dc41f5edb Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Sun, 21 Jun 2026 22:54:21 -0700 Subject: [PATCH] Release 2.7.5: bump version + What's New / version modal + PR description + docker-publish default tag Bumps _SOULSYNC_BASE_VERSION to 2.7.5, defaults the docker-publish workflow's version_tag to 2.7.5, and refreshes the release notes for the fixes/features since 2.7.4: deezer real track numbers, special-edition cover art (release-scope), the leading-'The' dedup, HiFi preview rejection (#895), M3U/M3U8 import (#893), organize-by-playlist file naming, durable Find & Add match, ignore-list management + manual-add unblock (#897), and the Unraid template fixes (#899). WHATS_NEW + VERSION_MODAL_SECTIONS rolled to 2.7.5 with 2.7.4 folded into the earlier-versions recap. --- .github/workflows/docker-publish.yml | 4 +- pr_description.md | 46 +++++++++-------- web_server.py | 2 +- webui/static/helper.js | 74 +++++++++++++++------------- 4 files changed, 69 insertions(+), 57 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index a216db03..5fa038f3 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.7.3)' + description: 'Version tag (e.g. 2.7.5)' required: true - default: '2.7.3' + default: '2.7.5' jobs: build-and-push: diff --git a/pr_description.md b/pr_description.md index 365c2dfa..17de1921 100644 --- a/pr_description.md +++ b/pr_description.md @@ -1,37 +1,43 @@ -# soulsync 2.7.4 — `dev` → `main` +# soulsync 2.7.5 — `dev` → `main` -patch release on top of 2.7.3. headline is **re-identify** — re-file an already-imported track under the right release without re-downloading it. +patch release on top of 2.7.4. a fix-heavy cycle — matching & artwork accuracy, the HiFi preview mess — plus a few quality-of-life features (M3U import, per-playlist file naming, ignore-list management). --- ## what's new -### re-identify a track (#889) -filed a track under the wrong release (single vs ep vs album)? there's now a ⇄ button in the library Enhanced view that lets you fix it. search any configured source (tabs, defaults to your active one), see the same song across its single / ep / album with type badges, pick the right one, and soulsync re-files the file you already have under that release — correct year, in-album track number, and art. opt to replace the original entry or keep both. +### matching & metadata accuracy +- **deezer track numbers** — a track grabbed from a deezer playlist/wishlist now gets its REAL in-album track number (e.g. "Apologize" = 16 on *Shock Value*), not the playlist index. deezer's playlist/search results don't carry the position, so we resolve it from the album endpoint. +- **special-edition cover art** — a special edition (e.g. *Clair Obscur: Expedition 33 (Gustave Edition)*) no longer ends up with the standard edition's art. musicbrainz albums were resolving cover art at release-GROUP scope (a single representative cover, ~always the standard), so a pinned release now prefers its OWN cover and only falls back to the group/provider art when the release has none of its own. +- **"The" dedup** — wanting "I Gotta Feeling" by "The Black Eyed Peas" when you own it under "Black Eyed Peas" (or vice-versa) no longer fails to match and re-downloads a duplicate. the matcher now searches both forms across a leading "The"; the confidence scorer still has the final say, so it can't merge genuinely different artists. -built additively over 5 phases (hint store → import seam → multi-source search → modal → button), all riding the existing import pipeline so a no-hint import is byte-identical to before. and it can't lose your file: replace deletes the old entry only *after* the re-import lands, and never if you pick the release it's already in. +### HiFi previews (#895) +HiFi was serving 30-second preview files dressed up as full songs (full length faked in the header). soulsync now rejects them three ways — short preview manifests, faked-header files that decode to ~30s, and a lossless-bitrate sanity check — and ABORTS the HiFi source instead of cascading down into a lower-tier copy of the same preview. (this was also an upstream Tidal-ban outage; the guard means you get a clean fail + fallback instead of a broken file.) -### cleaner libraries & imports -- **#890** — track titles no longer keep the "01 - " prefix from the filename when there's no embedded title tag (which made the real track read as a false "missing"). stripped conservatively so "7 Rings" / "1-800-273-8255" / "1979" are left alone. -- **#891** — a Library Reorganize now sweeps the leftover cover.jpg / .lrc / sidecars from the old folder so it actually empties, plus an opt-in "Remove Residual Files" toggle on the Empty Folder Cleaner for the image-only folders you already have. -- **Sokhi's batch** — same-album songs group under one canonical release id (no more split discographies / mixed cover art); a single can match its parent album; a mid-enrichment crash on an art-less file no longer leaves it untagged; and a sequel digit glued to a CJK title no longer matches the wrong album. +### playlists +- **M3U / M3U8 import (#893)** — the "import from file" tool now reads M3U/M3U8 playlists (the most common file-playlist format, and the one soulsync itself exports). parses extended `#EXTINF` (artist/title/duration) and simple path-only playlists, and round-trips with soulsync's own export. +- **organize-by-playlist file naming** — an opt-in template (`$position - $artist - $title`) renames the files INSIDE each playlist folder so they sort/play the way you want (e.g. in playlist order on a dumb player). filename only — validated to reject "/" and require `$title` — defaults to empty (keep the library filename), and works for both symlink and copy modes. +- **find & add is remembered** — a manual match you set on a synced playlist is no longer forgotten on the next auto-sync. replace-mode re-matched from scratch and ignored your durable pick; the matcher now consults the durable manual-match table, not just the volatile cache a library rescan wipes. -### quality & sources -- **#886** — AAC (.m4a) as an opt-in soulseek quality tier, ranked above mp3 / below flac. off by default; existing profiles unchanged until you enable it. -- **#887** — enrichment on Spotify Free now reads "Running (Spotify Free)" instead of wrongly showing "Not Authenticated". -- **#884** — NZBGet imports from the finished location, not the incomplete "….#NZBID" folder. -- **#885** — setting the timezone to Australia/Sydney no longer makes the cache-maintenance job loop every 5 seconds. +### ignore-list (#897) +- the wishlist ignore-list now has a "🚫 Ignored" button right on the wishlist page — it was buried in a modal most people never opened. +- manually re-adding a previously-cancelled track no longer gets silently blocked by the ignore-list. an explicit user add now bypasses + clears the ignore while keeping the real source type (so the Albums/Singles split is unaffected). -### polish -- the artist-detail header no longer bleeds the blurred artist photo behind it. +### docker / packaging (#899) +the Unraid template pointed its `TemplateURL` / `Icon` at a dead third-party repo — now points at the canonical files in this repo (raw URLs, not the HTML `/blob/` ones), and maps `/app/MusicVideos` so music-video downloads land on a share instead of an anonymous volume. + +--- + +## a brief recap of what came before +2.7.4 was **re-identify** (re-file an imported track under the right release without re-downloading) plus library/import cleanups (#889/#890/#891). 2.7.3 added the Quality Upgrade Finder and the wishlist ignore-list (#874). 2.7.2 brought playlist-folder mirroring + server-playlist M3U export; 2.7.1 added download verification + a review queue (#852); 2.7.0 made multi-user real — per-profile accounts, opt-in login, reverse-proxy support. --- ## tests -strictly additive across the board — every new behavior is opt-in or gated so default flows are unchanged. ~100 new tests this cycle (re-identify seam, title-strip danger cases, the shared residual-file classifier, aac tier, tz scheduler, spotify-free status). full imports / matching / reorganize / auto-import suites green, ruff clean. +additive + gated — every new behavior is opt-in or defaults to today's behavior. new seam/regression tests across deezer track positions, the HiFi preview guards, the "The" dedup, M3U parsing, the ignore-list manual-add bypass, the playlist item-naming template, and the release-scope cover-art helper. relevant suites green; `ruff check .` clean app-wide. ## post-merge -- [ ] tag `v2.7.4` on `main` -- [ ] docker-publish with `version_tag: 2.7.4` +- [ ] tag `v2.7.5` on `main` +- [ ] docker-publish with `version_tag: 2.7.5` - [ ] discord announce (auto-fired by the workflow) -- [ ] reply on #889 / #890 / #891 +- [ ] reply on #893 / #895 / #897 / #899 diff --git a/web_server.py b/web_server.py index 46e7fec4..7be627af 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.7.4" +_SOULSYNC_BASE_VERSION = "2.7.5" 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 d6a2cb89..52eb7528 100644 --- a/webui/static/helper.js +++ b/webui/static/helper.js @@ -3404,16 +3404,18 @@ function closeHelperSearch() { const WHATS_NEW = { // Convention: keep only the CURRENT release here, plus a single brief // "Earlier versions" summary entry. Don't accumulate old per-version blocks. - '2.7.4': [ - { date: 'June 2026 — 2.7.4 release' }, - { title: 'Re-identify a track (#889)', desc: 'filed a track under the wrong release? a new ⇄ button in the library Enhanced view lets you re-identify it — search any source (tabs, defaults to your active one), see the same song across its single / EP / album with type badges, pick the right one, and soulsync re-files the file you already have under that release with the correct year, in-album track number, and art. replace the original or keep both.', page: 'artists' }, - { title: 'Track titles no longer keep the "01 - " (#890)', desc: 'files with no embedded title tag used to import as "01 - Song Title" (the filename stem) — which never matched the canonical "Song Title", so the real track showed as a false "missing". the number prefix is now stripped, conservatively, so titles like "7 Rings" or "1-800-273-8255" are left alone.', page: 'library' }, - { title: 'Clear dead cover-art folders (#891)', desc: 'a Library Reorganize that moves an album now sweeps the leftover cover.jpg / .lrc / sidecars from the old folder so it actually empties. plus an opt-in "Remove Residual Files" toggle on the Empty Folder Cleaner clears the image-/sidecar-only folders you already have.', page: 'tools' }, - { title: 'AAC as an opt-in quality tier (#886)', desc: 'soulseek downloads can now include AAC (.m4a) as a selectable quality tier, ranked above MP3 and below FLAC. purely additive — off by default; every existing profile behaves exactly as before until you enable it.', page: 'settings' }, - { title: 'Spotify Free enrichment status (#887)', desc: 'if you run enrichment on Spotify Free (no spotify auth), the dashboard button now reads "Running (Spotify Free)" instead of wrongly showing "Not Authenticated".', page: 'dashboard' }, - { title: 'Cleaner album imports (Sokhi)', desc: 'songs from the same album now group under one canonical release id (no more split discographies or mixed cover art), a single can be matched to its parent album, a mid-enrichment crash on an art-less file no longer leaves it untagged, and a sequel digit glued to a CJK title no longer matches the wrong album.', page: 'library' }, - { title: 'More fixes', desc: 'NZBGet imports from the finished location instead of the incomplete "….#NZBID" folder (#884); setting your timezone to Australia/Sydney no longer makes the cache-maintenance job loop every 5 seconds (#885); and the artist-detail header no longer bleeds the blurred artist photo behind it.', page: 'downloads' }, - { title: 'Earlier versions', desc: '2.7.3 added the Quality Upgrade Finder (find + upgrade tracks you own in worse quality than available), a wishlist ignore-list (#874), quarantine duplicate-grouping (#876), the "Track 01" position fix, and Tidal discovery/favorites fixes (#867, #880). 2.7.2 brought playlist-folder mirroring + server-playlist M3U export and ReplayGain / Empty-Folder maintenance jobs; 2.7.1 added download verification + a review queue and closed the websocket login-bypass (#852); 2.7.0 made multi-user real — per-profile streaming accounts, opt-in login, reverse-proxy support.' }, + '2.7.5': [ + { date: 'June 2026 — 2.7.5 release' }, + { title: 'Special-edition cover art', desc: 'a special edition (e.g. *Clair Obscur: Expedition 33 (Gustave Edition)*) no longer ends up with the standard edition\'s art. musicbrainz albums resolved cover art at release-GROUP scope (one representative cover, ~always the standard), so a pinned release now prefers its OWN cover and only falls back to the group/provider art when the release has none.', page: 'library' }, + { title: 'Deezer track numbers', desc: 'a track grabbed from a deezer playlist/wishlist now gets its REAL in-album track number (e.g. "Apologize" = 16 on Shock Value), not the playlist index — resolved from deezer\'s album endpoint, which playlist/search results don\'t carry.', page: 'downloads' }, + { title: '"The" duplicate fix', desc: 'wanting "I Gotta Feeling" by "The Black Eyed Peas" when you own it under "Black Eyed Peas" (or vice-versa) no longer fails to match and re-downloads a duplicate. the matcher now searches both forms across a leading "The"; the scorer still has the final say.', page: 'downloads' }, + { title: 'HiFi previews rejected (#895)', desc: 'HiFi was serving 30-second preview files dressed up as full songs (faked length in the header). soulsync now catches them — short manifests, faked-header files that decode to ~30s, and a lossless-bitrate check — and aborts the HiFi source instead of cascading into a lower-tier copy of the same preview.', page: 'downloads' }, + { title: 'Import M3U / M3U8 playlists (#893)', desc: 'the "import from file" tool now reads M3U/M3U8 playlists — extended #EXTINF (artist/title/duration) and simple path-only files — and round-trips with soulsync\'s own M3U export.', page: 'sync' }, + { title: 'Name files in playlist folders', desc: 'an opt-in template ($position - $artist - $title) renames the files INSIDE each Organize-by-Playlist folder so they sort/play the way you want. filename only (rejects "/", requires $title), defaults to keeping the library filename, works for symlink + copy modes.', page: 'settings' }, + { title: 'Manage the ignore-list (#897)', desc: 'the wishlist ignore-list now has a "🚫 Ignored" button right on the wishlist page (it was buried in a modal). and manually re-adding a previously-cancelled track no longer gets silently blocked — an explicit add bypasses + clears the ignore.', page: 'downloads' }, + { title: 'Find & Add is remembered', desc: 'a manual match you set on a synced playlist is no longer forgotten on the next auto-sync. replace-mode re-matched from scratch; the matcher now honors the durable manual-match, not just the volatile cache a rescan wipes.', page: 'sync' }, + { title: 'Unraid template fixes (#899)', desc: 'the Unraid template now points its TemplateURL / Icon at the canonical files in this repo (raw URLs, not the dead third-party ones), and maps /app/MusicVideos so music-video downloads land on a share.', page: 'settings' }, + { title: 'Earlier versions', desc: '2.7.4 added re-identify (re-file an imported track under the right release without re-downloading) + library/import cleanups (#889/#890/#891). 2.7.3 added the Quality Upgrade Finder and the wishlist ignore-list (#874); 2.7.2 brought playlist-folder mirroring + server-playlist M3U export; 2.7.1 added download verification + a review queue (#852); 2.7.0 made multi-user real — per-profile streaming accounts, opt-in login, reverse-proxy support.' }, ], }; @@ -3444,38 +3446,42 @@ const WHATS_NEW = { // usage_note?: 'optional hint shown at the bottom' } const VERSION_MODAL_SECTIONS = [ { - title: "Re-identify a track (#889)", - description: "filed a track under the wrong release? re-identify it from the library without re-downloading — soulsync re-files the file you already have under the release you pick.", + title: "Matching & metadata accuracy", + description: "a batch of fixes so downloads land with the right numbers, art, and no duplicates.", features: [ - "a ⇄ button in the Enhanced library view opens a search across any configured source (tabs, defaults to your active one)", - "see the same song across its single / EP / album, each with a type badge, and pick the right collection", - "it re-files under that release with the correct year, in-album track number, and album art", - "replace the original entry or keep both — and it can never delete the file if you pick the release it's already in", - ], - usage_note: "Library → an artist → Enhanced view → ⇄ on a track", - }, - { - title: "Cleaner libraries & imports", - description: "a batch of fixes that keep the library tidy and matchable.", - features: [ - "#890 — track titles no longer keep the \"01 - \" from a filename (which caused false \"missing\" tracks); stripped conservatively so \"7 Rings\" / \"1-800-273-8255\" are left alone", - "#891 — a reorganize now sweeps leftover cover.jpg / .lrc from the old folder, plus an opt-in \"Remove Residual Files\" toggle clears image-only folders you already have", - "Sokhi — same-album songs group under one canonical release (no split discographies / mixed cover art); a single can match its parent album; a mid-enrichment crash no longer leaves a file untagged; a CJK-title sequel-digit no longer matches the wrong album", + "special-edition cover art — a pinned release (e.g. a \"Gustave Edition\") now uses its OWN cover instead of musicbrainz's release-group representative (usually the standard edition)", + "deezer track numbers — a track from a deezer playlist/wishlist gets its REAL in-album track number (e.g. \"Apologize\" = 16 on Shock Value), resolved from the album endpoint, not the playlist index", + "\"The\" dedup — \"The Black Eyed Peas\" and \"Black Eyed Peas\" now match across a leading \"The\", so a track you already own doesn't fail to match and re-download a duplicate", ], }, { - title: "Quality & sources", - description: "more control over downloads, plus a couple of source fixes.", + title: "HiFi previews (#895)", + description: "HiFi was serving 30-second preview files disguised as full songs (full length faked in the header).", features: [ - "#886 — AAC (.m4a) as an opt-in soulseek quality tier, ranked above MP3 and below FLAC; off by default so nothing changes until you enable it", - "#887 — enrichment on Spotify Free now reads \"Running (Spotify Free)\" instead of \"Not Authenticated\"", - "#884 — NZBGet imports from the finished location, not the incomplete \"….#NZBID\" folder", - "#885 — Australia/Sydney timezone no longer makes the cache-maintenance job loop every 5 seconds", + "rejects them three ways — short preview manifests, faked-header files that decode to ~30s, and a lossless-bitrate sanity check", + "aborts the HiFi source instead of cascading into a lower-tier copy of the same preview — you get a clean fail + fallback, not a broken file", ], }, { - title: "Earlier in 2.7.3 / 2.7.2 / 2.7.1 / 2.7.0", - description: "2.7.3 added the Quality Upgrade Finder (find + upgrade tracks you own in worse quality than available), a wishlist ignore-list (#874), quarantine duplicate-grouping (#876), the \"Track 01\" position fix, and Tidal discovery/favorites fixes (#867, #880). 2.7.2 brought playlist-folder mirroring + server-playlist M3U export and ReplayGain / Empty-Folder maintenance jobs; 2.7.1 added download verification (acoustid checks every download) + a review queue and closed the websocket login-bypass (#852); 2.7.0 made multi-user real — per-profile streaming accounts, opt-in login, reverse-proxy support.", + title: "Playlists", + description: "import from more formats, name files your way, and keep your manual matches.", + features: [ + "#893 — import M3U / M3U8 playlists in the \"import from file\" tool (extended #EXTINF + simple path-only files); round-trips with soulsync's own M3U export", + "organize-by-playlist file naming — an opt-in template ($position - $artist - $title) renames the files inside each playlist folder so they sort/play in order; filename only, defaults to keeping the library name, works for symlink + copy", + "find & add is remembered — a manual match on a synced playlist survives the next auto-sync; the matcher honors the durable manual-match, not just the volatile cache a rescan wipes", + ], + }, + { + title: "Ignore-list & packaging", + description: "manage the wishlist ignore-list, and a couple of Unraid template fixes.", + features: [ + "#897 — a \"🚫 Ignored\" button now lives right on the wishlist page (it was buried in a modal), and manually re-adding a previously-cancelled track no longer gets silently blocked", + "#899 — the Unraid template points TemplateURL / Icon at the canonical files in this repo (not a dead third-party repo) and maps /app/MusicVideos so music-video downloads land on a share", + ], + }, + { + title: "Earlier in 2.7.4 / 2.7.3 / 2.7.2 / 2.7.1 / 2.7.0", + description: "2.7.4 added re-identify (re-file an imported track under the right release without re-downloading) plus library/import cleanups (#889/#890/#891). 2.7.3 added the Quality Upgrade Finder and the wishlist ignore-list (#874); 2.7.2 brought playlist-folder mirroring + server-playlist M3U export and ReplayGain / Empty-Folder maintenance jobs; 2.7.1 added download verification (acoustid checks every download) + a review queue and closed the websocket login-bypass (#852); 2.7.0 made multi-user real — per-profile streaming accounts, opt-in login, reverse-proxy support.", features: [], }, ];