Commit graph

587 commits

Author SHA1 Message Date
Broque Thomas
f10beeea0a Add source badges (Spotify/iTunes/Deezer) to watchlist artist cards
Shows which metadata sources each artist is matched to with small
colored badges on the card. Also adds deezer_artist_id to the
watchlist API response and fixes the data-artist-id fallback chain
to include Deezer-only artists.
2026-03-16 13:37:53 -07:00
Broque Thomas
46ac46134b Add Deezer as configurable free metadata fallback source alongside iTunes
Users can now choose between iTunes/Apple Music and Deezer as their free
metadata source in Settings. Spotify always takes priority when authenticated;
the fallback handles all lookups when it's not.

Core changes:
- DeezerClient: full metadata interface (search, albums, artists, tracks)
  matching iTunesClient's API surface with identical dataclass return types
- SpotifyClient: configurable _fallback property switches between iTunes/Deezer
  based on live config reads (no restart needed)
- MetadataService, web_server, watchlist_scanner, api/search, repair_worker,
  seasonal_discovery, personalized_playlists: all direct iTunesClient imports
  replaced with fallback-aware helpers

Database:
- deezer_artist_id on watchlist_artists and similar_artists tables
- deezer_track_id/album_id/artist_id on discovery_pool and discovery_cache
- Full CRUD for Deezer IDs: add, read, update, backfill, metadata enrichment
- Watchlist duplicate detection by artist name prevents re-adding across sources
- SimilarArtist dataclass and all query/insert methods handle Deezer columns

Bug fixes found during review:
- Similar artist backfill was writing Deezer IDs into iTunes columns
- Discover hero was storing resolved Deezer IDs in wrong column
- Status cache not invalidating on settings save (source name lag)
- Watchlist add allowing duplicates when switching metadata sources
2026-03-16 13:12:12 -07:00
Broque Thomas
a02d14a23a Add URL history pills for YouTube, Deezer, and Spotify Link sync tabs
Saves successfully loaded playlist URLs to localStorage and displays
them as clickable pills between the input bar and playlist container.
Clicking a pill re-loads that URL; X button removes it. Max 10 per
source, most recent first. Source-colored hover accents match each
tab's brand styling.

Also fixes duplicate playlist bug — YouTube and Spotify Public now
check for already-loaded playlists before making API calls, preventing
broken duplicate cards when the same URL is entered twice.
2026-03-16 10:35:45 -07:00
Broque Thomas
837c5ff680 Add persistent library history tracking downloads and server imports
New library_history table logs every completed download and every new
track imported from Plex/Jellyfin/Navidrome. A "History" button next
to "Recent Activity" on the dashboard opens a modal with Downloads and
Server Imports tabs, album art thumbnails, quality/source badges, and
pagination.
2026-03-16 09:36:05 -07:00
Broque Thomas
f4af4ea7db Fix missing album cover art in download bubbles for redownload and issue downloads 2026-03-16 08:40:16 -07:00
Broque Thomas
7871f4581c Add cancel button for watchlist scans (manual and automation-triggered) 2026-03-15 23:24:18 -07:00
Broque Thomas
c90fff37f1 Fix service status labels missing HiFi and Qobuz display names 2026-03-15 23:05:56 -07:00
Broque Thomas
ec389c5ae8 Add HiFi as free lossless download source via public hifi-api instances
New download mode alongside Soulseek, YouTube, Tidal, and Qobuz. Uses
community-run REST API instances (no auth required) that serve Tidal CDN
FLAC streams. Features quality fallback chain (hires→lossless→high→low),
automatic instance rotation on failure, and full hybrid mode support.

Also fixes 6 missing streaming source checks for HiFi and Qobuz in the
frontend that were blocking playback with "format not supported" errors.
2026-03-15 22:53:34 -07:00
Broque Thomas
483e45cbc0 Add Spotify Link tab for public playlist/album scraping without API credentials
Scrapes Spotify's embed endpoint to extract track data from any public
playlist or album URL. Full discovery flow with Deezer parity: parse →
card → discovery modal → live progress → sync → download missing.

- New scraper: core/spotify_public_scraper.py (embed endpoint parsing)
- 12 API endpoints mirroring Deezer's discovery/sync/download flow
- WebSocket live discovery updates via spotify_public_discovery_states
- Green-branded tab, cards, and input styling (#1DB954)
- Album vs playlist detection with distinct card icons (💿/🎵)
- Download persistence: card click reopens download modal after close
- Card phase reset on cancel/completion (closeDownloadMissingModal)
- Backend download linking for spotify_public_ and deezer_ prefixes
- Completion handlers (V2 + no-missing-tracks) for both platforms
- Source URLs stored on mirrored playlists for future auto-refresh
2026-03-15 21:25:05 -07:00
Broque Thomas
da2b42b59a Add Redownload button to enhanced library view & fix album download mode
- Redownload button on each album in enhanced view (admin only)
- Uses same flow as artist page: fetches API tracklist, opens Download
  Missing modal with force-download option
- Register dashboard bubbles for library redownload and issue downloads
- Add library_redownload_ prefix to album download whitelist so it uses
  1 worker with source reuse and sends full album context (release_date
  for year in folder name)
2026-03-15 19:15:46 -07:00
Broque Thomas
0742cc45e6 Add hemisphere setting for seasonal playlists on Discover page
Southern hemisphere users now see correct seasons (e.g. March = Autumn,
December = Summer). Holidays (Halloween, Christmas, Valentine's) stay
calendar-fixed regardless of hemisphere.

- Hemisphere dropdown in Discovery Pool Settings
- GET/POST /api/discovery/hemisphere endpoints
- Season detection offsets months by 6 for southern hemisphere
- Stored in metadata table, defaults to northern
2026-03-15 18:49:51 -07:00
Broque Thomas
186671aa2e Add play button to repair findings & increase finding image sizes
- Play button on acoustid_mismatch, acoustid_no_match, track_number_mismatch, fake_lossless, dead_file, orphan_file findings
- Uses playLibraryTrack() for proper media player integration (track info, sidebar, album art)
- Data attributes for safe escaping instead of inline onclick strings
- Finding images increased from 56px to 150px with hover effects
- Improved detail panel spacing and media card layout
2026-03-15 15:46:30 -07:00
Broque Thomas
078b1130f8 Fix watchlist migration dropping profile_id & fix profile delete dialog hidden behind overlay
- Watchlist nullable migration now preserves profile_id column and composite
  UNIQUE constraints when rebuilding the table
- Profile support migration always repairs missing profile_id columns on all
  tables, even if the migration metadata key already exists (handles tables
  rebuilt by other migrations)
- Confirm dialog z-index raised to 100000 to appear above profile picker
  overlay (99999), fixing invisible delete confirmation
2026-03-15 15:21:19 -07:00
Broque Thomas
ab21855af3 Enrich repair findings with album art, artist images & live job progress
- All 9 repair jobs now emit report_progress() for real-time card updates
  (phase, log lines, per-item activity) via WebSocket repair:progress events
- Enrich finding details with album/artist thumb URLs across all repair jobs
  (dead_file, duplicate, metadata_gap, album_completeness, missing_cover_art,
  acoustid_scanner, track_number_repair, fake_lossless, orphan_file)
- Track number repair: return match_score from fuzzy matching, add suffix-based
  DB lookup for album/artist art (handles cross-environment path mismatches)
- Fix Plex/Jellyfin relative thumb URLs in findings endpoint via fix_artist_image_url
- Labeled media cards in finding detail panels (album title + artist name under images)
- Dashboard tooltip shows current job name + per-job progress instead of stale stats
2026-03-15 14:08:26 -07:00
Broque Thomas
f08550140f Add whistle logo to maintenance modal header & harden fix handlers
- Add whisoul.png to modal header with subtitle text and gradient background
- Responsive: smaller logo on mobile, hide subtitle
- Share _resolve_file_path in repair_worker for cross-environment path compat
- Use path resolution in orphan and duplicate file deletion
- Guard directory cleanup against removing the transfer folder itself
- Restore correct button label text on fix error recovery
2026-03-15 13:25:40 -07:00
Broque Thomas
0594673cad Polish finding detail renderers with richer visuals
- Cover art findings: show artwork image thumbnail preview
- Duplicate findings: KEEP/REMOVE badges highlighting best quality copy
- Incomplete album: completion progress bar with percentage
- Fake lossless: spectral analysis bar comparing detected vs expected cutoff
- Resolved findings: show descriptive action label (e.g. "Entry Removed")
- Fix operator precedence bug in fake lossless nyquist calculation
2026-03-15 13:00:44 -07:00
Broque Thomas
7a706e8c11 Add fix actions for maintenance findings (dead files, orphans, duplicates, etc.)
- New fix_finding() dispatcher in repair_worker with per-type handlers:
  dead_file (remove DB entry), orphan_file (delete from disk),
  track_number_mismatch (update DB), missing_cover_art (apply artwork URL),
  metadata_gap (apply found fields), duplicate_tracks (keep best quality)
- New POST /api/repair/findings/<id>/fix endpoint
- Frontend: contextual fix buttons per finding type, bulk "Fix Selected"
- Removed path_mismatch from fixable types (dry-run preview only)
2026-03-15 12:51:18 -07:00
Broque Thomas
61ed4086e0 Redesign maintenance findings/history tabs with dashboard & fix path resolution bugs
- Add findings dashboard with summary stats and per-job clickable filter chips
- Redesign findings cards with expandable detail panels and per-type renderers
- Redesign history tab with status dots, stat pills, and full timestamps
- Fix dead file cleaner false positives by using suffix-based path resolution
- Fix orphan file detector false positives by matching via path suffixes
- Add help text modal for each repair job card
- Enlarge maintenance modal (1100px wide, 90vh tall)
2026-03-15 12:20:02 -07:00
Broque Thomas
4635ea895b include a '?' to include more details for each job. 2026-03-15 11:19:09 -07:00
Broque Thomas
dab94ce65d update soulsync repair worker with new jobs 2026-03-15 10:18:50 -07:00
Broque Thomas
cae2bd0c62 Add granular post-processing toggles for metadata services, cover art, and lyrics 2026-03-14 22:45:50 -07:00
Broque Thomas
8f0b9518bc Add per-profile ListenBrainz support with personal settings modal 2026-03-14 20:12:19 -07:00
Broque Thomas
9a22c49a0e Add FLAC bit depth fallback option to quality profile 2026-03-14 19:24:25 -07:00
Broque Thomas
4a73ef6d24 Optimize enhanced view performance with event delegation and scoped DOM queries 2026-03-14 18:36:05 -07:00
Broque Thomas
7db1545208 Optimize enhanced view performance with event delegation and scoped DOM queries 2026-03-14 18:00:20 -07:00
Broque Thomas
7e19e66ef3 Add quality enhance button to upgrade existing library tracks & Add iTunes fallback to Quality Enhance endpoint for full metadata source parity 2026-03-14 17:09:08 -07:00
Broque Thomas
3bbbfb125e Add $albumtype template variable with smart EP/Single/Album detection 2026-03-14 12:40:25 -07:00
Broque Thomas
761052145f Add select all checkbox to watchlist modal for bulk removal 2026-03-14 12:25:58 -07:00
Broque Thomas
fc90ed68a3 Fix debug info copy button failing over HTTP in Docker 2026-03-14 11:37:44 -07:00
Broque Thomas
fead6db379 Fix docs sidebar navigation scroll targeting with lazy-loaded images 2026-03-14 11:16:26 -07:00
Broque Thomas
719980cf5a Hide sync sidebar by default, only show during active sync 2026-03-14 09:56:48 -07:00
Broque Thomas
945f86c643 Library Repair Worker: multi-job background maintenance daemon with 10 jobs, findings system, and management modal 2026-03-14 09:09:18 -07:00
Broque Thomas
6de3ab7cef Add universal metadata cache for Spotify & iTunes API responses with browsable dashboard tool 2026-03-14 01:26:45 -07:00
Broque Thomas
c54e52e18d Add Spotify Library discovery section, instrumental filter, custom exclusion terms & album download modal fixes 2026-03-14 00:21:44 -07:00
Broque Thomas
a5e72cff05 Add instrumental filter & custom exclusion terms to watchlist content filters 2026-03-13 23:09:12 -07:00
Broque Thomas
32f1cc946c Improve watchlist cross-provider matching accuracy and add manual artist linking UI 2026-03-13 22:28:13 -07:00
Broque Thomas
0e89155c15 Add watchlist settings gear button to artist detail and artist card pages 2026-03-13 22:07:54 -07:00
Broque Thomas
e1a5bf678a Add library issue reporting system with actionable detail modal 2026-03-13 21:14:57 -07:00
Broque Thomas
57a8bdd107 Add album file reorganization to Enhanced Library Manager 2026-03-13 18:43:54 -07:00
Broque Thomas
d4eadef374 Add interactive REST API docs with full endpoint tester and complete metadata serialization 2026-03-13 17:45:01 -07:00
Broque Thomas
4dfefc70df Polish settings page styling — premium header, toggle switches, refined inputs 2026-03-13 16:29:02 -07:00
Broque Thomas
f9bdabc0e4 Add particle background toggle & optimize accent color caching 2026-03-13 16:05:22 -07:00
Broque Thomas
2c6f2adce1 Redesign watchlist modal with polished cards, gradient overlays, and rate limit modal 2026-03-13 15:55:26 -07:00
Broque Thomas
a557074d3c Add Spotify rate limit modal with live countdown and ban duration escalation 2026-03-13 15:36:24 -07:00
Broque Thomas
daa55d208e fix issue where album info was not displayed for discover items. 2026-03-13 14:16:20 -07:00
Broque Thomas
02c1da76ba update recent updates and fix spotify worker rate limit button 2026-03-13 14:08:30 -07:00
Broque Thomas
7da7f3b112 Cache similar artist metadata at scan time to eliminate redundant Spotify API calls 2026-03-13 13:35:54 -07:00
Broque Thomas
5ee9390c05 Add album art to discovery pool by extracting image URLs from match data 2026-03-13 12:40:30 -07:00
Broque Thomas
55186c6a51 Add Deezer playlist sync tab with discovery, fix modal, and cache persistence 2026-03-13 12:29:49 -07:00
Broque Thomas
f9d80606e3 Expand debug info with library stats, service status, config, and configurable log output 2026-03-13 08:47:04 -07:00