Split the enhanced search dropdown into distinct Albums and Singles & EPs sections using the album_type field. Changed the zero-tracks error from a cryptic red error toast to a clear warning message. Fixed the loading text to show the actual music source name instead of hardcoded "Spotify".
Automatically clear completed downloads from slskd after batch completion, matching the cleanup behavior already present in the frontend. Adds a 5-minute periodic sweep as a safety net when no batches are actively running.
Summary: Navidrome incremental updates always found 0 new tracks because _get_recent_albums_navidrome() fetched all artists, sampled only the first 200, collected their albums, and sorted by created date — missing artists beyond the first 200 entirely. Replaced this with a single getAlbumList2?type=newest Subsonic API call that directly returns albums sorted by library addition date, matching how Jellyfin and Plex already use their native "recently added" endpoints.
When clicking a partially-complete album on the Library page, the wishlist modal now shows which tracks are owned (dimmed with checkmark) and which are missing (orange border). Ownership data lazy-loads after the modal opens to avoid blocking the UI, using a batch DB query for speed. Also fixes albums like DAMN. showing "14/15" when all available tracks are owned — the frontend now trusts the backend's "completed" status instead of doing raw track count math against potentially inaccurate Spotify metadata.
Replace blocking DB matching in the Library artist detail view with a two-phase render pattern. The page now renders album cards instantly from Spotify/Itunes data , then streams per-release ownership results via SSE that update cards one-by-one.
Fixed issue where broken iTunes explicit album IDs were preferred over working clean versions during deduplication. Some iTunes explicit albums (e.g., "Mr. Morale & The Big Steppers" ID 1623854804) report track counts in metadata but return 0 tracks when queried.
Added validation in itunes_client.py get_artist_albums() to verify explicit albums actually have tracks before keeping them. If an explicit version has 0 tracks, it's skipped and the clean version is used instead.
This fixes:
- "No tracks found" error when clicking affected albums
- Incorrect track count mismatches (19/18) caused by broken API data
The validation only runs for explicit albums during deduplication, minimal performance impact.
Update version to 1.6 in sidebar and API. Add changelog for local import, enhanced tagging, mobile layout, and performance improvements. Fix track popularity field access for upcoming Spotify API changes (February 2026).
Added an Import feature that lets users process local audio files through the existing post-processing pipeline (metadata enrichment, cover art, lyrics, library organization). Files are placed in a configurable Staging folder and imported via two modes: Album mode (search/match files to a Spotify tracklist) and Singles mode (select individual files for processing). Includes auto-suggested albums based on staging folder contents and real-time per-track progress tracking.
- Add global discovery_match_cache table to cache successful track matches
(title+artist+provider -> matched result) across all discovery sources
- Cache check before API search in YouTube, ListenBrainz, Tidal, and Beatport
discovery workers; cache write after high-confidence matches
- Re-discovering playlists or overlapping tracks across sources skips API lookups
- Fix Spotify tab sidebar forcing 2-column grid on mobile via inline JS styles
- Add mobile responsive styles for Spotify playlist cards (stack layout vertically)
Enrich downloaded audio files with external identifiers and improved genre metadata in a single post-processing write. During metadata enhancement, the app now looks up the MusicBrainz recording and artist MBIDs, retrieves the ISRC and MusicBrainz genres from a follow-up detail lookup, merges them with Spotify's artist-level genres (deduplicated, capped at 5), and embeds everything alongside the Spotify/iTunes track, artist, and album IDs. All MusicBrainz API calls are serialized through the existing global rate limiter, making concurrent download workers safe without needing to pause the background worker. Includes a database migration adding Spotify/iTunes ID columns to the library tables.
Add optional post-download audio fingerprint verification using AcoustID.
Downloads are verified against expected track/artist using fuzzy string
matching on AcoustID results. Mismatched files are quarantined and
automatically added to the wishlist for retry.
- AcoustID verification with title/artist fuzzy matching (not MBID comparison)
- Quarantine system with JSON metadata sidecars for failed verifications
- fpcalc binary auto-download for Windows, macOS (universal), and Linux
- MusicBrainz enrichment worker with live status UI and track badges
- Settings page AcoustID section with real-fingerprint connection test
- Source reuse for album downloads to keep tracks from same Soulseek user
- Enhanced search queries for better track matching
- Bug fixes: wishlist tracking, album splitting, regex & handling, log rotation
MusicBrainz library enrichment with real-time
status monitoring and manual control.
Features:
- Status icon button in dashboard header with glassmorphic design
- Animated loading spinner during active enrichment
- Hover tooltip showing:
- Worker status (Running/Paused/Idle)
- Currently processing item
- Artist matching progress with percentage
- Click-to-toggle pause/resume functionality
- Auto-polling every 2 seconds for live updates
Backend Changes:
- Added GET /api/musicbrainz/status endpoint
- Added POST /api/musicbrainz/pause endpoint
- Added POST /api/musicbrainz/resume endpoint
- Worker tracks current_item for UI display
- get_stats() returns enhanced status data
Frontend Changes:
- New MusicBrainz button component with tooltip
- Premium CSS styling with animations
- JavaScript polling and state management
- Positioned tooltip below button with centered arrow
Files Modified:
- web_server.py: API endpoints and worker initialization
- core/musicbrainz_worker.py: current_item tracking
- webui/index.html: Button and tooltip structure
- webui/static/style.css: Complete styling (240 lines)
- webui/static/script.js: Polling and interaction logic (115 lines)