Commit graph

1661 commits

Author SHA1 Message Date
Broque Thomas
616b377225 Fix Deezer download crash: config_manager not in scope
Deezer client imports config_manager locally in __init__ and stores
it as self._config, unlike the other clients which import at module
level. The allow_fallback line was referencing the wrong name.
2026-03-24 13:12:23 -07:00
Broque Thomas
6101832ee1 Add search filter and rematch to discovery pool modal
Discovery pool lists (matched and failed) now have a search input
that filters tracks client-side by name, artist, or playlist.

Matched tracks get a "Rematch" button that opens the fix modal in
cache-only mode — deletes the old cache entry and saves the new
match directly to the discovery cache via /api/discovery-pool/rematch.
This works regardless of whether a mirrored playlist track exists.

Failed tracks retain the existing "Fix Match" flow unchanged.
2026-03-24 13:07:04 -07:00
Broque Thomas
54b02b86c1 Update help docs: add HiFi/Deezer sources, quality fallback, template vars
- Overview and setup sections now list all 6 download sources
- Services table adds HiFi (no auth) and Deezer (ARL token)
- Enhanced Search documents multi-source tabs (Spotify/iTunes/Deezer)
- Download Sources table adds HiFi and Deezer rows
- Post-processing explains AcoustID skip for streaming sources and
  the new artist/title verification for streaming candidates
- File Organization documents $albumtype, $disc, and all template vars
- Quality Profiles adds callout for per-source fallback toggle
- Settings credentials list adds HiFi and Deezer entries
2026-03-24 12:30:26 -07:00
Broque Thomas
ee9f3b7386 Fix $albumtype template not working for singles in album context search
The album-aware search (_detect_album_info_album_context) was forcing
is_album=True for every track found in any release, including singles.
This routed singles through the album_path template instead of
single_path, ignoring the user's $albumtype folder structure.

Now applies the same classification logic as _detect_album_info_web:
checks album_type, total_tracks, and name comparisons to correctly
distinguish albums from singles/EPs. Works for all metadata sources
(Spotify, iTunes, Deezer) since all album objects have album_type.
2026-03-24 12:02:48 -07:00
Broque Thomas
89cfea0fe7 Add per-source quality fallback toggle for streaming downloads (#187)
Each streaming source (Tidal, Qobuz, HiFi, Deezer) now has an "Allow
quality fallback" checkbox in Settings. When disabled, the source only
tries the exact quality selected — if unavailable, it skips and lets
the orchestrator try the next source. Default is ON (current behavior).
2026-03-24 11:42:47 -07:00
Broque Thomas
e28aeccfd1 Redesign pool fix match modal: fixed height, no layout shift (#186)
Modal now uses a fixed 600px height from open — results scroll within
a dedicated area instead of growing the modal and pushing inputs up.
This eliminates the layout shift that caused accidental result clicks.

Other fixes:
- Input fields now have labels (Track, Artist)
- Overlay dismiss uses mousedown with stopPropagation to prevent
  accidental close when clicking near inputs
- Reduced results from 50 to 20 for faster response
- Clean minimal design matching app style
- Mobile: full-screen modal, stacked inputs with 44px touch targets
2026-03-24 11:16:37 -07:00
Broque Thomas
434ac417fd Add artist/title verification for streaming source download candidates
Streaming sources (Tidal, Qobuz, Deezer, HiFi, YouTube) were blindly
trusted with confidence 1.0 — all search results passed through without
any matching. When searching common track titles like "Die for You",
the most popular version (The Weeknd) could be downloaded instead of
the intended artist (Grabbitz/Valorant).

Now verifies each streaming result's artist and title against the
expected track before accepting it. Artist must substring-match or
have >=0.6 similarity; title needs >=0.5 similarity. Results sorted
by title confidence. If nothing passes, falls through to the standard
matching engine instead of silently downloading the wrong track.
2026-03-24 11:03:43 -07:00
Broque Thomas
7b615a9534 Redesign enhanced search results: modern flat layout with responsive cards
- Search bar: stripped heavy purple chrome, minimal dark input style
- Dropdown: inline flow instead of overlay, hides page header when active
- Section labels: flat uppercase text, no bordered glass boxes
- Artist cards: full-bleed photo with gradient overlay and name at bottom
  (matches library page style), flexbox wrap layout with fixed dimensions
- Album cards: discover-style dark cards in horizontal scroll on desktop,
  wrap to 2-per-row on mobile
- Track rows: clean flat list, subtle hover, smaller cover art
- Source tabs: compact pills with per-source accent colors
- Renamed grid classes (enh-artists-grid, enh-albums-grid, enh-tracks-list)
  to avoid collision with generic .artists-grid rule
- Mobile: downloads-main-panel min-width:0 fix for 1190px overflow,
  cards use calc(50% - 8px) for 2-per-row fill, touch-friendly targets
2026-03-24 10:45:14 -07:00
Broque Thomas
16be814a67 Fix album completeness fix returning 400 for stale findings
When missing_tracks was empty (API unavailable at scan time) or the
album was completed between scan and fix, the handler returned a 400
error. Now it re-fetches missing tracks from Spotify/iTunes/Deezer at
fix time and auto-resolves findings where the album is already complete.
2026-03-24 09:32:17 -07:00
Broque Thomas
01b0b70515 Fix enhanced view reorganize not moving sidecars, add template debug logging
Enhanced album reorganize now moves LRC, cover.jpg, folder.jpg and other
sidecar files alongside audio files. Added debug log to library reorganize
repair job showing which template is loaded from config vs default.
2026-03-24 07:12:35 -07:00
Broque Thomas
f247841665 Fix Album Tag Consistency job: add missing _get_settings method 2026-03-24 06:38:05 -07:00
Broque Thomas
96fa3fe388 Add SoulSync logo to sidebar header next to app name 2026-03-23 21:24:39 -07:00
Broque Thomas
f5177f9879 Update README for v2.1: Deezer downloads, stats, cache discovery, full feature list 2026-03-23 21:14:50 -07:00
Broque Thomas
e652726c22 Invert Tidal/Qobuz hero badges, add Artist Radio button and Last.fm play buttons
- Tidal and Qobuz SVG logos inverted on artist detail hero badges
- New Artist Radio button: clears queue, plays random artist track, enables radio
- Play buttons on Last.fm top tracks (hover reveal, resolves from library)
- Fixed inline JS escaping with data attribute delegation
2026-03-23 20:42:33 -07:00
Broque Thomas
4c3375745c Invert Tidal and Qobuz badge logos on library artist cards for visibility 2026-03-23 20:16:03 -07:00
Broque Thomas
21837be84e Fix 403 on followed Spotify playlists: fallback to public embed scraper
When fetching tracks from a followed playlist returns 403 (owner made it
private or API scope insufficient), fall back to the public embed scraper
which doesn't need API auth. Tracks still load with basic metadata.
2026-03-23 19:57:55 -07:00
Broque Thomas
cb32be4922 Refine settings page: glass buttons, accent section borders, softer inputs 2026-03-23 19:32:00 -07:00
Broque Thomas
e8a5e253f6 Rebuild artist SoulID: track-verified canonical ID from Deezer + iTunes
New algorithm: pick first track alphabetically from artist's library, search
both Deezer and iTunes APIs for 'artist track' to find the exact artist,
verify name matches, then use max(deezer_id, itunes_id) as the canonical
differentiator. Deterministic across instances — any SoulSync with the same
artist and at least one matching track will produce the same soul_id.

Fallback chain: canonical API ID → first album title → name only.
Migration clears all artist soul_ids on first v2.1 startup for regeneration.
2026-03-23 18:34:36 -07:00
Broque Thomas
dc6f0db916 Add missing placeholder-album.png to stop 404 spam in console 2026-03-23 18:05:11 -07:00
Broque Thomas
b8ec6d66af Add missing _get_artist_image_from_albums to HydrabaseClient
Method exists on iTunesClient and DeezerClient but was missing from
HydrabaseClient, causing AttributeError when Hydrabase is active and
Build a Playlist tries to fetch artist images.
2026-03-23 17:54:21 -07:00
Broque Thomas
e0827f2ced Update Docker publish workflow default version to 2.1 2026-03-23 16:46:20 -07:00
Broque Thomas
571ba6b532 Version 2.1: Deezer downloads, cache discovery, stats, glass UI, album consistency
Major version bump with 40+ commits of features and fixes:
- Deezer as 6th download source (ARL auth, FLAC/MP3, Blowfish decrypt)
- Cache-powered discovery: 5 sections + Genre Deep Dive modal
- Listening Stats page with charts and play buttons
- Picard-style MB release preflight for consistent album tagging
- Album Tag Consistency repair job
- Unified glass UI across dashboard, sync, and modals
- Mobile responsive overhaul for all pages
- Enrichment fixes: retry loops, rate limits, worker pause during scans
- AcoustID skip for trusted API sources
2026-03-23 16:45:23 -07:00
Broque Thomas
deadfa1e82 Skip AcoustID verification for trusted API download sources
Tidal, Qobuz, Deezer, and HiFi download by exact track ID from official
APIs — files are guaranteed correct. AcoustID fingerprinting only runs
for Soulseek (P2P) and YouTube (extracted audio) where mislabeling is
possible. Users with AcoustID disabled see no change.
2026-03-23 16:08:27 -07:00
Broque Thomas
7eed88c72c Fix Deezer download integration: add deezer_dl to all streaming source checks
- Added deezer_dl to 7 hardcoded streaming source username tuples in web_server
- Streaming sources now bypass Soulseek filename-matching engine in get_valid_candidates
  (API search results are already properly matched, no need for P2P filename scoring)
- Fixes download progress tracking, completion detection, and candidate filtering for Deezer
2026-03-23 15:57:53 -07:00
Broque Thomas
9c60040a9b Integrate Deezer download source into orchestrator
Added deezer_dl to all orchestrator methods: init, is_configured,
get_source_status, check_connection, search (single + hybrid), download,
get_all_downloads, get_download_status, cancel_download, clear_completed,
cancel_all, and reload_settings. Full parity with existing 5 sources.
2026-03-23 15:34:27 -07:00
Broque Thomas
2ae5050ef1 Add Deezer download source: client, settings UI, ARL authentication
- New core/deezer_download_client.py: full download client with ARL auth,
  Blowfish decryption, quality fallback (FLAC/MP3 320/MP3 128), search,
  thread-safe download tracking. Not yet integrated into orchestrator.
- Settings UI: Deezer download quality selector, ARL token input, test
  connection button. Appears in download source dropdown and hybrid list.
- Test endpoint: /api/deezer-download/test verifies ARL and returns tier.
- Added deezer_download to settings save whitelist and sensitive paths.
- Fixed Spotify enrichment worker default to unpaused (like other workers).
2026-03-23 15:06:40 -07:00
Broque Thomas
d4a57ae654 Start Spotify enrichment worker unpaused by default like other workers 2026-03-23 13:23:00 -07:00
Broque Thomas
7070b98756 Fix reorganize modal using hardcoded template instead of saved settings
The enhanced view reorganize modal had a hardcoded default path template
instead of loading the user's saved template from settings. Now fetches
the saved album_path template from /api/settings on modal open.
2026-03-23 12:47:25 -07:00
Broque Thomas
5d6ccee066 Add Picard-style MB release preflight for album downloads
Before album tracks start post-processing, pre-populate the MusicBrainz
release cache with ONE verified release. All tracks then hit the cache
during per-track processing and get the same release MBID — no second pass,
no file lock contention, tags correct on first write.

Handles edition name mismatches (Spotify says 'Super Deluxe', MB says
just the base name) by stripping qualifiers and searching again.
Validates track count to pick the right edition. Three download paths
covered: download missing modal, enhanced album, and matched album.
2026-03-23 12:42:29 -07:00
Broque Thomas
1e54ff54ac Fix album tag consistency handler: open each file once for all field changes 2026-03-23 10:46:28 -07:00
Broque Thomas
d75893bc30 Add Album Tag Consistency repair job: detect and fix inconsistent tags across album tracks
New maintenance job scans albums for tracks with mismatched album names, album
artist names, or MusicBrainz release IDs. These inconsistencies cause Navidrome
and other media servers to split one album into multiple entries. The fix
normalizes outlier tracks to the majority value by rewriting file tags.
2026-03-23 10:44:36 -07:00
Broque Thomas
68f06d663b Pause enrichment workers during database scans to reduce lock contention
All 11 background workers (9 enrichment + repair + SoulID) pause when a DB
scan starts and resume when it finishes. Tracks which workers were running
so manually-paused workers stay paused after scan. Covers incremental,
full refresh, deep scan, automation-triggered, and startup scans.
2026-03-23 10:33:10 -07:00
Broque Thomas
efe8164501 Fix missing album art on wishlist items from mirrored playlists
Embed scraper was pre-marking spotify_public tracks as discovered with
playlist-level images instead of per-track album art. Discover step then
skipped them entirely. Now stores spotify_hint (track ID) without marking
discovered, so Discover runs proper API lookups for real album art.
2026-03-23 09:22:49 -07:00
Broque Thomas
a48018f4ca Fix config save 'database is locked': add 30s timeout, WAL mode, and retry
Settings DB connections had no timeout (default 5s), causing lock failures when
enrichment workers hold concurrent write locks. Added 30s timeout, WAL journal
mode for better concurrency, retry-once before falling back to config.json.
2026-03-23 08:54:53 -07:00
Broque Thomas
df390feece Fix automation signal chain: forward event data (playlist_id) to action handlers
Event-triggered automations now receive playlist_id from the triggering event
when the action config doesn't have one set. Fixes silent 'No playlist specified'
failures in Discover/Sync chains. Added debug logging to trace event matching.
2026-03-23 08:51:52 -07:00
Broque Thomas
655e1e251d Add rate limit check to search_tracks and search_albums in Spotify client
Both methods were calling Spotify API without checking the global rate limit,
causing 429 errors to spam the logs even when the ban was active.
2026-03-23 07:53:46 -07:00
Broque Thomas
429306c7f3 Fix enrichment retry loops, cover art finding dupes, and Spotify rate limit during art scan
- All 9 enrichment workers: stop auto-retrying 'error' status items (was infinite loop)
  Only 'not_found' items retry after configured days; errors require manual full refresh
- Cover art dedup: check both 'pending' AND 'resolved' findings to prevent recreation
- Cover art scanner: top-level Spotify rate limit check skips Spotify entirely when
  banned, falls back to iTunes/Deezer only, logs once instead of spamming 429s
2026-03-22 23:24:42 -07:00
Broque Thomas
d8217d66ba Speed up metadata cache browser: add composite indexes, remove full-scan LIKE filters 2026-03-22 23:13:34 -07:00
Broque Thomas
203f317236 Redesign download missing and wishlist modals with unified glass style 2026-03-22 22:16:25 -07:00
Broque Thomas
8d3d623f10 Redesign sync page playlist cards: unified glass style across all sources and mirrored playlists 2026-03-22 22:10:42 -07:00
Broque Thomas
1ac16ce0d4 Redesign dashboard cards: tool cards, service status, and system stats with unified glass style 2026-03-22 21:52:47 -07:00
Broque Thomas
17e06aaae5 Update What's New modal with cache discovery, genre deep dive, DB storage, performance, mobile, and album split fix 2026-03-22 21:38:24 -07:00
Broque Thomas
e3d70da55a Add DB storage visualization + cache-powered discovery sections + Genre Deep Dive
- Stats page: database storage donut chart with per-table breakdown and total size
- Discover page: 5 new sections mined from metadata cache (zero API calls):
  Undiscovered Albums, New In Your Genres, From Your Labels, Deep Cuts, Genre Explorer
- Genre Deep Dive modal: artists (clickable → artist page), popular tracks,
  albums with download flow, related genre pills, in-library badges
- All cache queries filtered by active metadata source (Spotify/iTunes/Deezer)
- Stale cache entries (404) gracefully fall back to name+artist resolution
- Album cards show "In Library" badge, artist avatars scaled by prominence
2026-03-22 21:35:18 -07:00
Broque Thomas
c937045192 Mobile responsive overhaul: stats, artist detail, enhanced library, automations, hydrabase, docs
- Stats page: full mobile layout with compact cards, charts, ranked lists
- Artist hero: stacked layout, compact image/name/badges, top tracks below
- Enhanced library: meta header/expanded header stack vertically, track table
  collapses action columns into bottom sheet popover on mobile
- Automations: builder sidebar collapses, inputs go full width
- Hydrabase/Issues/Help: responsive stacking and compact layouts
- Fix grid blowout: add min-width:0 to stats grid children and overflow:hidden
2026-03-22 19:32:58 -07:00
Broque Thomas
40a9858f28 Fix album split in Navidrome: normalize MusicBrainz release cache keys across edition variants 2026-03-22 16:51:03 -07:00
Broque Thomas
01d96866e4 Increase stats page top artists/albums/tracks from 10 to 25 2026-03-22 16:39:53 -07:00
Broque Thomas
93005298ee Cap Opus bitrate at 256kbps, fix lossy copy flavor text, redesign artist action buttons 2026-03-22 16:34:36 -07:00
Broque Thomas
21d7e65986 Speed up library page: split DB query, innerHTML rendering, staggered card animation 2026-03-22 16:14:28 -07:00
Broque Thomas
8c84189121 Add per-artist enrichment coverage rings to artist hero section 2026-03-22 15:56:12 -07:00
Broque Thomas
f6225ec9a8 Fix enrichment coverage: correct Spotify column name and add all 9 services 2026-03-22 15:36:25 -07:00