diff --git a/web_server.py b/web_server.py index 4fb243a5..30e7fd79 100644 --- a/web_server.py +++ b/web_server.py @@ -23063,1219 +23063,6 @@ def get_version_info(): } return jsonify(version_data) -_OLD_V22_NOTES = """ - { - "title": "Wing It — Download or Sync Without Discovery", - "description": "Bypass metadata discovery and use raw track names directly", - "features": [ - "• Wing It button on all discovery modals and ListenBrainz Discover page cards", - "• Choose Download or Sync from a compact dropdown — no extra dialogs", - "• Download: sends raw artist/title to the download engine with full post-processing", - "• Sync: creates playlist on media server by matching raw names against library", - "• Failed tracks are NOT added to wishlist — clean wing-it behavior", - "• Live sync progress displayed inline just like normal sync", - "• Download creates a bubble on the dashboard for progress tracking" - ], - "usage_note": "Click the Wing It button next to Start Discovery or Download Missing in any playlist modal." - }, - { - "title": "Global Search Bar — Search From Anywhere", - "description": "Spotlight-style search bar accessible from every page", - "features": [ - "• Persistent search bar at the bottom of the screen — faded when idle, expands on focus", - "• Full enhanced search parity — artists, albums, singles/EPs, tracks with source tabs", - "• Keyboard shortcuts: / or Ctrl+K to focus, Escape to close", - "• Click artists to navigate to their detail page, albums to open download modal", - "• In Library badges and green play buttons for tracks you already own", - "• Source tabs (Spotify, iTunes, Deezer) with result counts", - "• Results collapse on navigation, search bar stays visible" - ], - "usage_note": "Press / or Ctrl+K from any page, or click the search bar at the bottom of the screen." - }, - { - "title": "Redesigned Notification System", - "description": "Modern compact toasts with notification history and bell button", - "features": [ - "• Compact pill-shaped toasts in the bottom-right — one at a time, auto-dismiss after 3.5s", - "• Notification bell button with unread badge counter next to the help button", - "• Click the bell to open the notification history panel with the last 50 notifications", - "• Each notification shows type icon, message, relative timestamp, and optional 'Learn more' link", - "• Unread dot indicators — panel marks all as read when opened", - "• Clear All button to empty notification history", - "• Click any toast to dismiss it immediately" - ] - }, - { - "title": "Track Redownload — Fix Mismatched Downloads", - "description": "Replace wrong downloads with the correct version using manual source selection", - "features": [ - "• Redownload button (↻) on each track in the enhanced library view", - "• Step 1: All metadata sources (Spotify, iTunes, Deezer) searched in columns side-by-side", - "• Step 2: All download sources searched simultaneously — results stream in as each source responds", - "• Step 3: Download with real progress bar, old file deleted, DB path updated automatically", - "• Full pipeline parity — track number, album context, metadata tagging all work correctly", - "• Source Info (ℹ) button shows where each track was downloaded from", - "• Download provenance tracking — every download's source is recorded for future reference", - "• Smart Delete: choose to remove from library only or delete the file from disk too", - "• Download Blacklist: block specific sources from the Source Info popover — blacklisted sources skipped in all future downloads", - "• Blacklist viewer on dashboard Tools section with remove capability" - ], - "usage_note": "In the enhanced library view, click ↻ to redownload, ℹ for source info, or to delete." - }, - { - "title": "Spotify API Rate Limit Improvements", - "description": "Reduced Spotify API usage through caching and smart worker management", - "features": [ - "• get_artist_albums now cached — discography views, completion badges hit cache instead of API", - "• Watchlist scans bypass cache with skip_cache flag to always detect new releases", - "• All 5 discovery workers (Tidal, YouTube, ListenBrainz, Beatport, playlist search) now use cached search methods", - "• Eliminated duplicate API calls — discovery workers were calling sp.search() AND search_tracks() per query", - "• Auth probe cache TTL increased from 5 to 15 minutes — reduces /v1/me calls by 66%", - "• Spotify, Last.fm, and Genius enrichment workers auto-pause during active downloads to preserve rate limit headroom", - "• Dashboard shows 'Yielding for downloads' when workers are auto-paused" - ] - }, - { - "title": "Additional Fixes", - "description": "Bug fixes and quality-of-life improvements", - "features": [ - "• $discnum template variable — unpadded disc number for multi-disc album path templates", - "• Media player no longer collapses in sidebar on short viewports and mobile", - "• Playlist Explorer controls redesigned — prominent Explore button, icons, polish", - "• YouTube '- Topic' suffix stripped from auto-generated channel names (#231)", - "• Cover Art Archive album art now opt-in via Settings toggle (#232)", - "• cover.jpg now correctly uses Cover Art Archive when enabled (was silently failing)", - "• Genius artist search returns multiple results for manual matching (#233)", - "• Genius API interval increased from 1.5s to 2s to reduce 429 rate limits", - "• MusicBrainz cache now visible in Cache Browser with browse, clear, and clear-failed-only options", - "• Cache Health popup shows MusicBrainz alongside other sources, 'Failed Lookups' clarified as MB-specific", - "• Block artists from discovery — hover any track in a discovery playlist and click to permanently exclude that artist", - "• Configurable concurrent downloads (1-10) — Settings → Downloads, Soulseek albums stay at 1", - "• Streaming search sources — Apple Music results load progressively instead of blocking for 9+ seconds", - "• API Rate Monitor — real-time speedometer gauges for all services on Dashboard, click for 24h history", - "• Spotify pagination throttled — prevents 429 bans during watchlist scans with large discographies", - "• Import now triggers full scan → DB update chain through automation engine", - "• Track source-info and redownload work with Jellyfin string IDs (#237)", - "• Clear Match button to undo wrong manual matches (#236)", - "• Tidal auth no longer crashes when download orchestrator not initialized", - "• Download orchestrator hardened — one failing client no longer kills all download sources", - "• Webhook THEN action — send HTTP POST to any URL (Gotify, Home Assistant, Slack, n8n) from automations", - "• M3U auto-export now skips albums — only generates for playlists (#241)", - "• Copy Debug Info includes API call rates, Spotify rate limit state, and download client failures", - "• Discogs integration — new metadata source with enrichment worker, fallback source, search tabs, watchlist, cache", - "• Discogs enriches: genres/styles (400+ taxonomy), labels, catalog numbers, bios, community ratings", - "• Track provenance preserved through lossy transcoding with bit depth/sample rate/bitrate (#245)", - "• spotify_public playlists use full API when authenticated, no longer overwrite discovery data", - "• Watchlist backfills all sources (Spotify, iTunes, Deezer, Discogs) at start of every scan", - "• Collectors edition album matching for library completion checks", - "• Mobile responsive styles for rate monitor, notifications, and global search" - ] - }, - { - "title": "Server Playlist Manager — Compare & Fix Matches", - "description": "Review and fix track matches between your source playlists and media server", - "features": [ - "• New Server Playlists tab (default on Sync page) — shows server playlists that match your mirrored playlists", - "• Dual-column comparison view — source tracks on the left, server tracks on the right with match status", - "• Click any track to highlight and auto-scroll to its pair in the other column", - "• Find & Add — click empty slots to search your library and add tracks at the correct position", - "• Swap — replace a matched track with a different version from your library", - "• Remove — delete incorrect tracks from server playlists with confirmation", - "• Title similarity percentage shown on each match (exact, high, or fuzzy)", - "• Disambiguation modal when multiple mirrored playlists share the same name", - "• Album art shown for source tracks, server tracks, and search results", - "• Smart matching — exact title match first, then fuzzy artist+title match (≥75% threshold)", - "• Works with Plex, Jellyfin, and Navidrome" - ], - "usage_note": "Navigate to Sync → Server Playlists tab. Click any playlist card to open the comparison editor." - }, - { - "title": "Sync History Dashboard with Per-Track Details", - "description": "Dashboard shows recent syncs as visual cards with full per-track match data", - "features": [ - "• Recent Syncs section on dashboard with scrolling cards showing match percentage and health indicators", - "• Click any sync card to see per-track match details — status, confidence score, album art, download/wishlist status", - "• Filter by All, Matched, Unmatched, or Downloaded tracks in the detail modal", - "• Per-track data cached for all sync types — playlist-to-server, download missing tracks, wishlist processing", - "• Auto-refreshes every 30 seconds when viewing dashboard" - ] - }, - { - "title": "Fix Japanese Song Searches Producing Gibberish", - "description": "CJK text no longer mangled by unidecode in Soulseek search queries", - "features": [ - "• Japanese kanji, hiragana, katakana, and Korean hangul preserved in search queries", - "• unidecode was converting Japanese to Chinese pinyin (e.g. 命の灯火 → 'tvanimedei')", - "• Soulseek users typically share files with original CJK characters in filenames" - ] - }, - { - "title": "Fix Partial Name Matching False Positives (#225)", - "description": "Track ownership check no longer falsely matches prefix/suffix variations", - "features": [ - "• 'Believe' no longer matches 'Believe In Me' — length ratio penalty prevents partial title matches", - "• Titles differing in length by more than 30% get their similarity score penalized proportionally", - "• Exact matches and cleaned matches (e.g. remastered tags stripped) are unaffected" - ] - }, - { - "title": "Fix Pipeline Stops When Metadata Match Fails (#224)", - "description": "Playlist sync no longer drops tracks that failed iTunes/Apple Music discovery", - "features": [ - "• Tracks that fail metadata discovery now continue through the pipeline using original playlist data", - "• Track name and artist from the source playlist are used for Soulseek search when discovery fails", - "• Only tracks with completely missing name/artist are skipped (not tracks that simply failed matching)" - ] - }, - { - "title": "Playlist Explorer — Visual Discovery Tree", - "description": "Use playlists as seeds to discover full albums and discographies", - "features": [ - "• New Explorer page with interactive tree visualization", - "• Select any mirrored playlist and choose Albums or Discographies mode", - "• Tree builds progressively — artist nodes appear as Spotify data streams in", - "• Click artists to expand and see all their albums with art, year, and track counts", - "• Select individual albums or entire branches, then add to wishlist in one click", - "• Albums mode shows only albums containing playlist tracks; Discographies shows everything", - "• SVG connecting lines with animated draw-in effect", - "• 'In Library' and 'In Playlist' badges on album cards" - ] - }, - { - "title": "Fix .LRC Files Written Without Timestamps", - "description": "Plain lyrics now saved as .txt instead of invalid .lrc files", - "features": [ - "• Synced (timestamped) lyrics → .lrc file — valid format for Plex, Navidrome, Jellyfin", - "• Plain (unsynced) lyrics → .txt file — no longer written with incorrect .lrc extension", - "• Lyrics still embedded in audio file tags regardless of type (players can display both)", - "• File move/rename operations updated to handle both .lrc and .txt sidecars" - ] - }, - { - "title": "Fix Collaborative Album Artist Not Applied to Singles (#215)", - "description": "Single path template now respects the First Listed Artist setting", - "features": [ - "• Single downloads now include structured artists list for collab artist extraction", - "• $albumartist variable now works in single and playlist path templates", - "• Settings UI updated to show $albumartist as available for single and playlist templates" - ] - }, - { - "title": "Fix Enrichment Overwriting Manual Matches (#221)", - "description": "Enriching an entity that was manually matched no longer reverts the status to not_found", - "features": [ - "• Genius and AudioDB workers now check for existing service IDs before searching by name", - "• Manual matches are used for direct API lookup instead of re-searching by name", - "• If the direct lookup succeeds, metadata is enriched and match status is preserved", - "• If the direct lookup fails, the manual match status is preserved (not overwritten to not_found)", - "• Added AudioDB lookup-by-ID methods for artist, album, and track" - ] - }, - { - "title": "Fix Spotify OAuth ERR_EMPTY_RESPONSE in Docker (#220)", - "description": "OAuth callback server hardened for Docker/SSH tunnel setups", - "features": [ - "• Top-level error handler ensures an HTTP response is always sent (no more ERR_EMPTY_RESPONSE)", - "• All callback logging now goes to app.log (was only in Docker stdout before)", - "• Health check at http://localhost:8888/ to verify the callback server is running", - "• Startup logs the actual bind address for diagnosing port conflicts", - "• Port-in-use errors now logged clearly with explanation" - ] - }, - { - "title": "Show All Services on Dashboard (#219)", - "description": "Dashboard now shows connection status for all external services, not just the core three", - "features": [ - "• Enrichment services shown as color-coded chips below core service cards", - "• API call counts per service: 1-hour and 24-hour windowed totals shown on each chip", - "• Spotify chip includes daily budget bar (used/3000) with color-coded fill", - "• Unconfigured services show dashed border — click to jump directly to their Settings section", - "• All configurable services clickable — navigates to Settings → Connections and scrolls to the service", - "• Spotify card always labeled 'Spotify' — no longer confusingly switches to 'Apple Music'", - "• Fallback state (using iTunes/Deezer) shown with amber indicator when Spotify is not connected" - ] - }, - { - "title": "Add Qobuz to Connections Tab (#218)", - "description": "Qobuz credentials now available on the Connections tab for metadata enrichment", - "features": [ - "• New Qobuz section on Settings → Connections tab for enrichment auth", - "• Users can connect Qobuz for metadata enrichment regardless of download source", - "• Auth status syncs between Connections and Downloads tabs" - ] - }, - { - "title": "Fix Enrichment Widget Showing 'Running' When Rate Limited", - "description": "Enrichment tooltip now shows Rate Limited or Daily Limit Reached instead of stuck on Running", - "features": [ - "• Shows 'Rate Limited' with countdown when Spotify rate limit is active", - "• Shows 'Daily Limit Reached' with reset time when daily budget is exhausted", - "• Shows 'Waiting for next item...' instead of blank when no current item" - ] - }, - { - "title": "Metadata Cache Maintenance", - "description": "The cache evictor now runs four maintenance phases to keep the metadata cache clean", - "features": [ - "• Input validation prevents junk entities (Unknown Artist, empty names) from being cached", - "• Junk cleanup removes existing placeholder entries from the cache", - "• Orphan cleanup removes search results pointing to deleted entities", - "• MusicBrainz null cleanup removes failed lookups after 30 days (was 90) so they get retried", - "• Health stats available in the repair dashboard" - ] - }, - { - "title": "Fix Wishlist Download Selection Ignoring Checkboxes", - "description": "Download Selection now respects which tracks are checked in the wishlist overview", - "features": [ - "• Selected track IDs are collected before closing the overview modal", - "• Only checked tracks are sent to the download analysis board", - "• If nothing is checked, downloads the full category (same as before)" - ] - }, - { - "title": "Fix Tidal OAuth Redirect URI in Docker", - "description": "Tidal OAuth now uses the configured redirect URI instead of the Docker container hostname", - "features": [ - "• Respects the redirect URI set in Settings instead of overriding with request hostname", - "• Falls back to dynamic host detection only if no redirect URI is configured", - "• Fixes Tidal authentication failing in Docker due to internal hostname in OAuth URL" - ] - }, - { - "title": "High-Resolution Cover Art from Cover Art Archive", - "description": "Album art now sourced from Cover Art Archive when available — often 1200x1200+ original quality", - "features": [ - "• Tries Cover Art Archive first using MusicBrainz release ID (full resolution)", - "• Falls back to Spotify/iTunes/Deezer URL (640x640) if CAA unavailable", - "• Source ID embedding now runs before art embedding to make release ID available" - ] - }, - { - "title": "Embedded Lyrics in Audio Files", - "description": "Lyrics are now embedded directly in audio file tags alongside the .lrc sidecar file", - "features": [ - "• Lyrics embedded as USLT (MP3), lyrics (FLAC/OGG), or ©lyr (M4A) tags", - "• Navidrome, Jellyfin, and Plex can now display lyrics without .lrc file support", - "• .lrc sidecar files are still created for compatibility with other players" - ] - }, - { - "title": "Fix AcoustID False Positives for Non-English Tracks", - "description": "AcoustID no longer quarantines correct files when titles are in different languages", - "features": [ - "• High-confidence fingerprint matches (95%+) now SKIP instead of FAIL when title/artist don't match", - "• Prevents Japanese, Chinese, Korean, and other non-Latin tracks from being falsely quarantined", - "• Audio fingerprint confirms the recording is correct — metadata mismatch is just a language difference" - ] - }, - { - "title": "Fix Soulseek Junk Tags Surviving Post-Processing", - "description": "Tags from Soulseek source files are now wiped to disk immediately, before metadata enhancement", - "features": [ - "• Clears and saves tags before any API calls or metadata extraction", - "• If enhancement fails, file has clean empty tags instead of inconsistent junk", - "• Fixes album fragmentation in Navidrome/Jellyfin/Plex caused by partial MusicBrainz data", - "• Happy path unchanged — full metadata still written on success" - ] - }, - { - "title": "Watch All Unwatched Preview Modal", - "description": "The Watch All Unwatched button now opens a modal showing exactly which artists will be added", - "features": [ - "• Preview list shows all eligible artists with images, track counts, and matched sources", - "• Clear separation of eligible vs ineligible artists (no external ID)", - "• Collapsible section explains why some artists can't be added yet", - "• Confirm before adding — no more silent 'Added 0' surprises", - "• Results summary shown after completion" - ] - }, - { - "title": "Fix Watch All Unwatched Skipping Deezer Artists", - "description": "Watch All Unwatched now supports Deezer as an ID source", - "features": [ - "• Added Deezer ID support to the bulk watchlist add flow", - "• Source detection based on actual ID field used instead of numeric heuristic", - "• Fallback chain: active source first, then Spotify, iTunes, Deezer" - ] - }, - { - "title": "Fix Library Maintenance Path Fixes Failing Silently", - "description": "Path mismatch fixes now use fresh config and report errors to the UI", - "features": [ - "• Output folder path is re-read from config before each fix attempt", - "• Fix failure reasons are now shown in the toast notification", - "• Bulk fix failures are logged individually with finding ID and error details" - ] - }, - { - "title": "Fix Spotify Manual Match Storing Wrong IDs", - "description": "Manual match modals no longer store iTunes/Deezer IDs in Spotify ID columns", - "features": [ - "• Detects actual provider from result IDs — Spotify IDs are alphanumeric, iTunes/Deezer are numeric", - "• Match button now stores IDs in the correct service column (itunes_artist_id vs spotify_artist_id)", - "• Results show provider label when falling back (e.g. 'ID: 312095 (itunes)')", - "• Fixes broken Spotify links on artist pages caused by stored iTunes IDs" - ] - }, - { - "title": "Spotify Enrichment Daily Budget", - "description": "The background enrichment worker now caps itself at 3,000 items per day to prevent rate limit bans", - "features": [ - "• Worker-only daily budget — user-initiated searches, playlist operations, etc. are unaffected", - "• Counter resets automatically at midnight each day", - "• Worker sleeps when budget is exhausted and resumes the next day", - "• Budget status exposed in the enrichment worker dashboard widget" - ] - }, - { - "title": "Deezer Download Source", - "description": "Download music directly from Deezer with ARL authentication", - "features": [ - "• New download source: Deezer joins Soulseek, YouTube, Tidal, Qobuz, and HiFi", - "• FLAC lossless, MP3 320, and MP3 128 with automatic quality fallback", - "• ARL token authentication — paste from browser cookies, test connection in Settings", - "• Full hybrid mode support — use Deezer as primary, fallback, or in any priority order", - "• Blowfish CBC decryption handles Deezer's encrypted streams transparently", - "• AcoustID verification automatically skipped for Deezer (and Tidal/Qobuz/HiFi) — trusted API sources" - ] - }, - { - "title": "Cache-Powered Discovery", - "description": "Five new discover sections mined from your metadata cache — zero API calls", - "features": [ - "• Undiscovered Albums: albums by your most-played artists that aren't in your library", - "• New In Your Genres: recently released albums matching your top genres", - "• From Your Labels: popular albums on labels already in your library", - "• Deep Cuts: low-popularity tracks from artists you listen to — find the hidden gems", - "• Genre Explorer: genre landscape pills with artist counts — tap to deep dive", - "• All data sourced from local metadata cache — instant, no API rate limits" - ] - }, - { - "title": "Genre Deep Dive Modal", - "description": "Tap any genre pill to explore artists, tracks, and albums in that genre", - "features": [ - "• Artists section with scaled avatars — top artist gets largest, 'In Library' badges", - "• Click any artist → navigates directly to their page on the Artists tab", - "• Popular tracks list with album art, duration, click to open album download modal", - "• Albums carousel with 'In Library' badges and full download flow on click", - "• Related genres pills — click to seamlessly switch to a sibling genre", - "• Header shows counts: '12 artists · 15 tracks · 20 albums'", - "• Accent gradient header with animated light sweep" - ] - }, - { - "title": "Database Storage Visualization", - "description": "See how your database space is distributed across tables", - "features": [ - "• Donut chart on Stats page showing storage breakdown by table", - "• Uses SQLite dbstat for real byte sizes, falls back to row counts", - "• Top 8 tables shown individually, rest grouped as 'Other'", - "• Center label shows total database file size" - ] - }, - { - "title": "Library Page Performance", - "description": "Library artist grid loads significantly faster with smoother animations", - "features": [ - "• innerHTML batch rendering replaces per-card DOM manipulation — near-instant grid population", - "• Database query split into 3 steps: paginate first, then batch-fetch counts for visible page only", - "• Event delegation — single click listener instead of 75+ individual handlers", - "• Staggered card fade-in animation on page load" - ] - }, - { - "title": "Per-Artist Enrichment Rings", - "description": "See metadata coverage for each artist on their detail page", - "features": [ - "• SVG ring indicators for all 9 enrichment services below the album/EP/singles bars", - "• Rings animate on page load with staggered fill-in effect", - "• Hover glow in each service's brand color", - "• Stats page enrichment coverage also expanded to all 9 services" - ] - }, - { - "title": "Mobile Responsive Overhaul", - "description": "Comprehensive mobile layout fixes across all pages", - "features": [ - "• Stats, Automations, Hydrabase, Issues, Help pages now fully mobile responsive", - "• Artist hero section stacks properly with compact image, wrapping badges, bio clamp", - "• Enhanced library track table: action columns collapse into iOS-style bottom sheet popover", - "• Genre explorer, enrichment rings, filter bars all adapt to narrow screens" - ] - }, - { - "title": "Album Split Fix (Navidrome)", - "description": "Prevent deluxe/standard editions from splitting into separate albums", - "features": [ - "• MusicBrainz release cache key normalized — strips edition suffixes (Deluxe, Remastered, etc.)", - "• First track's MBID locked in for all subsequent tracks in the same album", - "• Handles both parenthetical '(Deluxe Edition)' and bare 'Deluxe Edition' suffixes", - "• Opus bitrate capped at 256kbps to prevent encoding failures" - ] - }, - { - "title": "Picard-Style Album Tagging", - "description": "All tracks in an album now get the same MusicBrainz release ID automatically", - "features": [ - "• Pre-flight MB release lookup before album tracks start downloading", - "• Picks ONE release, validates track count, caches for all tracks in the batch", - "• Strips Spotify edition suffixes (Super Deluxe, Remastered) for better MB matching", - "• New Album Tag Consistency repair job: scan and fix existing albums with mismatched tags" - ] - }, - { - "title": "Enrichment & Repair Fixes", - "description": "Critical fixes for background workers and maintenance jobs", - "features": [ - "• All 9 enrichment workers: error status items no longer auto-retry in infinite loops", - "• Cover art filler: findings no longer recreated after being fixed", - "• Spotify rate limit respected by search_tracks, search_albums, and cover art scanner", - "• Config save: 30s timeout + WAL mode fixes 'database is locked' on busy systems", - "• Enrichment workers auto-pause during DB scans and resume when complete" - ] - }, - { - "title": "Automation Signal Chain Fix", - "description": "Event-triggered automations now receive playlist context properly", - "features": [ - "• playlist_id forwarded from events to action handlers (fixes silent 'No playlist specified')", - "• Mirrored playlist discovery no longer pre-marks tracks as discovered with wrong album art", - "• Reorganize modal now loads saved path template instead of hardcoded default", - "• Spotify enrichment worker starts unpaused by default like all other workers" - ] - }, - { - "title": "Unified Glass UI Redesign", - "description": "Consistent visual style across all cards, modals, and buttons", - "features": [ - "• Dashboard tool cards, service cards, and stat cards: unified glass style", - "• Sync page playlist cards: all sources (Spotify, YouTube, Tidal, Deezer, Mirrored, Beatport)", - "• Download missing and wishlist modals: cleaner backgrounds, softer shadows", - "• Watchlist and enhance quality buttons: glass hover with accent glow", - "• Library page: innerHTML rendering + staggered card animation for faster loads" - ] - }, - { - "title": "Scrobbling to Last.fm & ListenBrainz", - "description": "Automatically scrobble your plays from Plex, Jellyfin, or Navidrome", - "features": [ - "• Listen on your media server — SoulSync automatically scrobbles to Last.fm and/or ListenBrainz", - "• Last.fm: full web auth flow, ListenBrainz: simple token-based", - "• Batch scrobbling with dedup tracking — events only scrobbled once" - ] - }, - { - "title": "Personalized Discovery + Listening Stats", - "description": "Discovery playlists use your listening history, plus a full stats dashboard", - "features": [ - "• Release Radar, Discovery Weekly, and Because You Listen To: personalized by play history", - "• Listening Stats page: timeline chart, genre breakdown, top artists/albums/tracks", - "• Database storage donut chart in Library Health section", - "• Play buttons on stats page tracks with cover art" - ] - }, - { - "title": "Interactive Help System", - "description": "Full contextual help platform accessible from the floating ? button", - "features": [ - "• 200+ contextual help entries — click any UI element to learn what it does", - "• 11 guided tours covering every page (97 steps total) with spotlight overlay", - "• Page-aware menu suggests the relevant tour for your current page", - "• Search across all help topics, tours, and keyboard shortcuts (Ctrl+K)", - "• Setup Progress tracker with auto-detection — checks your services, library, and watchlist", - "• What's New panel with version-tagged highlights and 'Show me' navigation", - "• Troubleshoot mode scans for disconnected services and shows fix steps", - "• Keyboard shortcut overlay showing all hotkeys grouped by scope", - "• Quick action buttons in popovers (e.g., 'Open Settings' on service cards)", - "• First-launch welcome prompt for new users" - ] - }, - { - "title": "Rich Artist Profiles", - "description": "Full-bleed hero section on the Artists page with deep metadata", - "features": [ - "• Large portrait image with blurred background, glassmorphic design", - "• Bio, genres, listening stats from Last.fm, service logo badges", - "• Multi-source genre explorer with Deezer genre support", - "• Similar artist cards with full-bleed library-card styling" - ] - }, - { - "title": "Enhanced Library Manager", - "description": "Inline metadata editing and tag writing from the library view", - "features": [ - "• Toggle between Standard and Enhanced view on any artist detail page", - "• Inline-edit track title, number, BPM; album and artist fields editable", - "• Write tags directly to audio files (MP3, FLAC, OGG, M4A) with diff preview", - "• Bulk select tracks across albums for batch edit and batch tag write", - "• Server sync after writes — Plex per-track, Jellyfin library scan" - ] - }, - { - "title": "In Library Badges + Search Improvements", - "description": "Know what you already own before downloading", - "features": [ - "• 'In Library' badges on enhanced search album and track results", - "• Async post-render matching — search results appear instantly, badges fill in", - "• Multi-source search tabs: compare results from Spotify, iTunes, and Deezer", - "• Clickable artist name in download modal navigates to discography" - ] - }, - { - "title": "FLAC Bit Depth + Quality Filter", - "description": "Finer control over audio quality preferences", - "features": [ - "• Quality profile enforces 16-bit vs 24-bit FLAC preference", - "• Bit depth fallback option: accept other bit depth if preferred unavailable", - "• 1450 kbps threshold separates 16-bit from 24-bit FLAC", - "• Sort prioritizes audio quality (effective kbps) over peer speed" - ] - }, - { - "title": "Enrichment Worker Improvements", - "description": "Better name matching and quieter logs across all 8+ workers", - "features": [ - "• Dash-suffix normalization: 'Title - Remix' now matches 'Title (Remix)' across all workers", - "• AcoustID log noise reduced — individual recording matches moved to DEBUG", - "• Streaming source verification: artist/title fuzzy match prevents wrong track downloads", - "• Deezer enrichment worker caches API calls through metadata cache", - "• Per-source quality fallback toggles for streaming download sources" - ] - }, - { - "title": "Launch PIN Lock Screen", - "description": "Protect SoulSync access with a PIN on every page load", - "features": [ - "• Toggle in Settings → Advanced → Security to require PIN on launch", - "• Full-screen lock overlay with PIN input — closing the tab requires re-entry", - "• PIN validated server-side against admin profile (bcrypt hashed)", - "• Inline PIN creation if admin has no PIN set", - "• Shake animation on wrong PIN, auto-focus input" - ] - }, - { - "title": "Stream Source Setting", - "description": "Choose where track previews come from — independent of download source", - "features": [ - "• New dropdown in Settings → Downloads: YouTube (instant, default) or Active Download Source", - "• If active source is Soulseek, automatically falls back to YouTube", - "• YouTube streams require no auth — instant playback" - ] - }, - { - "title": "YouTube Download Fix", - "description": "Fixed 'Requested format not available' errors affecting all YouTube downloads", - "features": [ - "• Removed stale player_client and HLS/DASH skip overrides that blocked audio formats", - "• Browser cookie fallback — retries without cookies when authenticated sessions restrict formats", - "• Docker containers auto-update yt-dlp on every start" - ] - }, - { - "title": "Accurate Album Completion Badges", - "description": "Album completion now uses exact track counts instead of percentage rounding", - "features": [ - "• Exact match: 'Complete' only when all tracks are present — no more 90% rounding", - "• Deduplicated counting: duplicate album entries don't inflate track counts", - "• Multi-artist album detection: finds albums filed under different artists in your library", - "• Censored title matching: 'B*****t Faucet' now matches 'Bullshit Faucet' (Apple Music)" - ] - }, - { - "title": "Collaborative Album Handling", - "description": "Smart folder naming and matching for albums with multiple artists", - "features": [ - "• New setting: Collaborative Album Artist — use first listed artist or all combined", - "• Spotify: picks first from separate artist objects. Deezer: already first-only", - "• iTunes: resolves primary artist via artistId API lookup (safe for 'Tyler, the Creator')", - "• Album-aware track matching prevents re-downloads of collab albums filed under different artists" - ] - }, - { - "title": "Per-Artist Library Sync", - "description": "Validate and clean up individual artist library entries", - "features": [ - "• New 'Sync' button on enhanced library view", - "• Checks each track's file exists on disk, removes stale entries", - "• Cleans empty albums and updates track counts", - "• Per-artist watchlist lookback period override" - ] - }, - { - "title": "Stability & Bug Fixes", - "description": "Various fixes for crashes, data integrity, and UX", - "features": [ - "• Enrichment worker pause state persists across restarts", - "• Soulseek timeout spam prevention — skips API calls when disconnected", - "• Navidrome playlist sync uses POST (fixes truncation on large playlists)", - "• Deezer metadata cache no longer serves stale data missing track numbers/year", - "• Track numbering fix for non-Spotify metadata sources (Deezer/iTunes)", - "• Album delete endpoint accepts all ID formats (fixes Navidrome string IDs)", - "• Hydrabase auto-reconnect when server restarts", - "• Wishlist process API endpoint for external apps" - ] - } -""" # end of _OLD_V22_NOTES - -_OLD_V2_NOTES = r""" - "features": [ - "• Generates soul IDs using SHA-256 hash of normalized names", - "• Artists: hash(name + debut_year) — debut year from iTunes + Deezer API verification", - "• Albums: hash(artist + album), Tracks: dual IDs (song + album-specific)", - "• Dashboard worker button with rainbow spinner and hover tooltip", - "• SoulSync badge on library artist cards when matched" - ] - }, - { - "title": "Lossy Codec Expansion + Retroactive Converter", - "description": "Opus and AAC support for post-download conversion, plus a repair job for existing files", - "features": [ - "• Lossy copy now supports MP3, Opus, and AAC (M4A) — configurable codec and bitrate", - "• Opus: -map 0:a for clean audio extraction, cover art embedded via METADATA_BLOCK_PICTURE", - "• AAC: MP4Cover embedding, -movflags +faststart for streaming optimization", - "• New Lossy Converter repair job: scans FLAC library, creates findings, Fix/Fix All converts", - "• Job reads codec/bitrate from current settings at fix time (change settings after scanning)", - "• Independent Blasphemy Mode toggle per job (separate from download-time setting)" - ] - }, - { - "title": "Smarter Staging Import", - "description": "Tag-first matching and auto-grouping for the import workflow", - "features": [ - "• Tags take priority over filename parsing — no more '08' as artist name", - "• Auto-detected album groups from file tags shown as one-click import cards", - "• Match scoring rebalanced: title (0.45) + artist (0.15) + track# (0.30) + album bonus (0.10)", - "• Filename parser pattern order fixed — track numbers no longer misidentified as artists" - ] - }, - { - "title": "Library Artist Hero Redesign", - "description": "Expanded artist detail section with Last.fm integration", - "features": [ - "• Horizontal service badge row with hover lift animations", - "• Last.fm bio with Read More toggle, listener/play count stats", - "• Scrollable top 100 tracks from Last.fm in sidebar card", - "• Last.fm tags merged with existing genres", - "• Compact inline progress bars for Albums/EPs/Singles completion" - ] - }, - { - "title": "Hydrabase Search & Routing", - "description": "Hydrabase shows as a search tab with proper ID routing", - "features": [ - "• Hydrabase appears as a source tab on enhanced search when connected", - "• Plugin-aware ID routing: numeric IDs → iTunes, alphanumeric → Spotify", - "• Artist images fetched from iTunes for Hydrabase results", - "• Full Spotify-compatible interface: get_album, get_artist, get_track_details" - ] - }, - { - "title": "Orphan File Detector + MusicBrainz Fixes", - "description": "Better orphan detection and album version matching", - "features": [ - "• Orphan detector: normalized tag matching strips feat./parentheticals to reduce false positives", - "• Orphan fix now prompts 'Move to Staging' or 'Delete' instead of auto-deleting", - "• MusicBrainz release matching: version qualifier scoring prevents deluxe → standard MBID mismatch", - "• Playlist sync crash fixed: profile ID captured at request time, not in background thread" - ] - }, - { - "title": "Release Year Collection", - "description": "Post-processing now collects release year from all metadata sources", - "features": [ - "• Year extracted from MusicBrainz, Deezer, Tidal, Qobuz during post-processing", - "• First source to find a year wins — written to ORIGINALDATE/DATE tags and album DB year", - "• Library Reorganize API year lookup cap raised from 50 to 200" - ] - }, - { - "title": "Multi-Source Search Tabs", - "description": "View search results from Spotify, iTunes, and Deezer side by side", - "features": [ - "• Enhanced search now fires parallel queries against all available metadata sources", - "• Switchable tabs above results — click to view results from Spotify, Apple Music, or Deezer", - "• Tabs load progressively — primary source shows instantly, alternates appear as they complete", - "• Click an artist or album from any tab to browse that source's data temporarily", - "• Downloads use the metadata from whichever source tab you're viewing", - "• Similar artists always use your primary source — no accidental cross-source mixing" - ] - }, - { - "title": "Per-Profile Service Credentials", - "description": "Each profile can connect their own Spotify, Tidal, and media server library", - "features": [ - "• Non-admin profiles can enter their own Spotify credentials and authenticate their own account", - "• Per-profile Tidal authentication — connect your own Tidal account through the shared app", - "• Per-profile media server library selection — choose which Plex library or Jellyfin user playlists sync to", - "• Tabbed personal settings modal: Music Services, Server, and Scrobbling tabs", - "• Server tab auto-detects active server and shows library name dropdowns (not raw IDs)", - "• All credentials encrypted. Admin users see zero change — fully backwards compatible" - ] - }, - { - "title": "Modern Settings Redesign", - "description": "Settings page rebuilt with tabbed single-column layout", - "features": [ - "• Horizontal tab bar: Connections, Downloads, Library, Appearance, Advanced", - "• Single centered column replaces 3-column wall of cards", - "• Clean row layout — label left, control right", - "• Custom styled dropdowns with SVG arrows and hover states", - "• Mobile responsive — rows stack, tab bar scrolls" - ] - }, - { - "title": "Hybrid N-Source Download Priority", - "description": "Hybrid mode now supports all 5 download sources with drag-to-reorder priority", - "features": [ - "• Enable/disable any combination of Soulseek, YouTube, Tidal, Qobuz, and HiFi", - "• Up/down arrows to reorder source priority — downloads try each enabled source in order", - "• Source icons with toggle switches and priority numbers", - "• Configurable download timeout and max peer queue length for Soulseek", - "• Peer quality (upload speed, free slots, queue length) now factors into result ranking" - ] - }, - { - "title": "Automation Hub Pipelines", - "description": "One-click deployment of multi-automation pipelines", - "features": [ - "• 11 pre-built pipelines: Release Radar, Discovery Weekly, Playlist Auto-Sync, Nightly Operations, and more", - "• Each pipeline deploys 2-5 linked automations with signal chaining in one click", - "• Visual pipeline cards with connected flow nodes and accent-colored design", - "• Pipeline detail modal shows full WHEN/DO/THEN breakdown for each automation", - "• Deploy prompts for notification config (Discord/Telegram/Pushbullet) when pipeline includes alerts" - ] - }, - { - "title": "Staging Folder Pre-Download Check", - "description": "Check your import folder for existing files before downloading", - "features": [ - "• Before searching Soulseek/YouTube, checks the import folder for a matching file", - "• Tag-based matching (Mutagen) with filename parsing fallback", - "• On match, copies the file to transfer and runs normal post-processing", - "• Staging scan cached per batch — only scans once for the entire download" - ] - }, - { - "title": "Library Safety & Repair Fixes", - "description": "Critical fixes for library maintenance jobs and safety guards", - "features": [ - "• Mass orphan safety guard — 'witness me' confirmation required when >50% of files flagged as orphans", - "• Tag-based orphan fallback — reads file metadata before marking as orphan to prevent false positives", - "• Album Completeness expanded to support iTunes and Deezer (was Spotify-only)", - "• Album Completeness min completion % filter — skip playlist imports, catch real failed downloads", - "• Fix Track Number Repair returning 400 on fix (entity_id was NULL for file-based findings)", - "• Fix Library Reorganize producing (_) in paths when year is empty", - "• Fix Fix All ignoring Single/Album Dedup findings", - "• Fix enrichment workers looping infinitely on tracks with NULL IDs", - "• Fix Tidal token refresh hammering API when credentials removed", - "• Fix YouTube playlist parsing capped at ~100 tracks", - "• Allow re-sync from download_complete state with Rediscover button" - ] - }, - { - "title": "Deezer Metadata Source", - "description": "Deezer added as a configurable free metadata fallback alongside iTunes/Apple Music", - "features": [ - "• New setting to choose between iTunes and Deezer as your fallback metadata source — switch anytime from Settings", - "• All metadata lookups, watchlist scans, discovery, and enrichment seamlessly use whichever fallback is configured", - "• On-the-fly artist ID resolution — switching sources auto-matches existing watchlist artists by name on the next scan", - "• Source badges on watchlist artist cards show which services (Spotify, iTunes, Deezer) each artist is matched to", - "• Full backward compatibility — existing iTunes users experience zero changes on upgrade", - "• Name-based duplicate detection prevents adding the same artist twice across different metadata sources" - ] - }, - { - "title": "Library History", - "description": "Persistent record of every download and server import — viewable from the dashboard", - "features": [ - "• History button next to Recent Activity opens a modal with Downloads and Server Imports tabs", - "• Every completed SoulSync download is logged with title, artist, album, quality, and cover art", - "• Every new track imported from Plex, Jellyfin, or Navidrome is logged automatically", - "• Paginated browsing with tab count badges and relative timestamps", - "• History persists across restarts — unlike the in-memory activity feed" - ] - }, - { - "title": "MusicBrainz MBID Mismatch Repair", - "description": "New repair job to detect and fix wrong MusicBrainz recording IDs on library tracks", - "features": [ - "• Detects tracks where the stored MusicBrainz recording ID resolves to a different title than expected", - "• Fix action clears the bad MBID so enrichment can re-match correctly", - "• Also fixes MusicBrainz recording matching returning wrong titles due to unstable MBID lookups" - ] - }, - { - "title": "HiFi Download Source", - "description": "Free lossless downloads via public hifi-api instances — no account or subscription required", - "features": [ - "• New download mode alongside Soulseek, YouTube, Tidal, and Qobuz — select HiFi Only or use in hybrid mode", - "• Quality selection: Hi-Res, Lossless, High, or Low with automatic fallback chain (hires → lossless → high → low)", - "• Automatic instance rotation across 6 public API servers — any server error triggers failover to the next instance", - "• Full search, download, streaming, and post-processing support — works identically to other download sources", - "• Test connection button in Settings to verify instance availability" - ] - }, - { - "title": "Spotify Link (No API Credentials)", - "description": "Scrape Spotify playlists and albums by URL without needing Spotify API credentials", - "features": [ - "• New Spotify Link tab on the playlist sync page — paste any public Spotify playlist or album URL", - "• Extracts all track metadata (title, artist, album, duration, cover art) via web scraping", - "• Works without Spotify client ID/secret — great for users who don't want to set up a Spotify developer app", - "• Full download and sync support — tracks are matched and downloaded like any other playlist source" - ] - }, - { - "title": "Library Maintenance Suite", - "description": "Full-featured library repair system with 9 automated jobs, fix actions, and rich findings UI", - "features": [ - "• 9 repair jobs: track number mismatch, dead files, duplicates, metadata gaps, album completeness, missing cover art, AcoustID scanner, orphan files, fake lossless detection", - "• One-click fix actions for findings — remove dead entries, delete orphans, resolve duplicates, apply metadata, update track numbers", - "• Findings dashboard with per-job filter chips, summary stats, and expandable detail panels", - "• Album art and artist images displayed in findings with labeled media cards", - "• Real-time progress on job cards via WebSocket — phase, log lines, and per-item activity", - "• Visual detail renderers: cover art previews, KEEP/REMOVE badges for duplicates, completion progress bars, spectral analysis for fake lossless", - "• Job help text modals explaining what each repair job checks and how to interpret findings" - ] - }, - { - "title": "Post-Processing Enhancements", - "description": "Granular control over post-processing and richer file tagging", - "features": [ - "• Granular toggles for each post-processing step — enable/disable metadata services, cover art, and lyrics individually", - "• Embed Tidal, Qobuz, Last.fm, and Genius metadata directly into audio file tags during post-processing", - "• FLAC bit depth fallback option in quality profiles — accept lower bit depth when preferred isn't available" - ] - }, - { - "title": "Per-Profile ListenBrainz", - "description": "Each profile can connect their own ListenBrainz account for personalized playlists", - "features": [ - "• Personal settings modal with ListenBrainz connect/disconnect flow", - "• Per-profile playlist caching — switching profiles shows that user's playlists", - "• Graceful fallback to global ListenBrainz token when no personal token is set", - "• Stale playlist cache recovery for interrupted syncs" - ] - }, - { - "title": "Quality Enhance", - "description": "Upgrade existing library tracks to higher quality versions", - "features": [ - "• Quality enhance button on library tracks — find and download a higher quality version", - "• iTunes fallback for quality enhance when Spotify metadata isn't available", - "• Full metadata source parity between Spotify and iTunes for upgrade searches" - ] - }, - { - "title": "Hi-Res FLAC Downsampling", - "description": "Automatically convert 24-bit hi-res downloads to 16-bit/44.1kHz CD quality", - "features": [ - "• New toggle in Settings → Post-Download Conversion: downsample hi-res FLAC to CD quality after download", - "• Converts 24-bit and/or high sample rate FLAC files to 16-bit/44.1kHz — saves ~50% disk space with no audible difference", - "• Safe in-place replacement: writes to temp file, verifies output, then atomic swap — original untouched on failure", - "• Runs before lossy copy so MP3s are created from the downsampled version when both are enabled", - "• Automatically updates $quality in filenames and QUALITY tags after conversion", - "• Overrides strict bit depth rejection — files are accepted and converted instead of quarantined" - ] - }, - { - "title": "Recent Bug Fixes & Improvements", - "description": "Stability fixes, UX improvements, and edge case handling", - "features": [ - "• Fix $year template variable empty for playlist/sync downloads — album metadata now backfilled from Spotify API", - "• Fix dead file cleaner reporting 66k+ false positives — transfer path fell back to ./Transfer under DB contention", - "• Fix library reorganize not updating database paths after moving files — suffix-based matching with SQL LIKE escaping", - "• Fix library reorganize not moving cover.jpg and other album-level sidecar files with tracks", - "• Fix orphaned sidecar files left behind after reorganize — post-pass sweep moves remaining non-audio files", - "• Fix Navidrome library scan was a no-op — now triggers actual scan via Subsonic startScan API", - "• Select All, Fix Selected, and Fix All bulk actions for Library Maintenance findings", - "• Fix empty brackets in folder names ($year, $quality etc.) not being cleaned when template variables resolve to empty", - "• Fix missing album cover art in download progress bubbles for redownload and issue modal downloads", - "• Cancel button for watchlist scans — stop manual or automation-triggered scans mid-run", - "• Fix HiFi client not failing over to next instance on HTTP 500 — previously only 502/503/504 triggered rotation", - "• Fix service status labels missing HiFi and Qobuz display names", - "• Redownload button on enhanced library view — re-download any album directly from the library manager", - "• Hemisphere setting for seasonal playlists — southern hemisphere users get correct seasonal recommendations", - "• Play button on repair findings — preview tracks directly from the maintenance findings list", - "• Spotify rate limit guards added to all repair jobs — prevents ban escalation during library maintenance", - "• Fix watchlist migration dropping profile_id & fix profile delete dialog hidden behind overlay", - "• Fix watchlist NOT NULL constraint blocking iTunes-only artists from being added", - "• Fix Windows path mangling for artist names with trailing dots (e.g. Fred again..)", - "• Fix watchlist scan failing entirely when Spotify is rate limited — iTunes provider fallback added", - "• Fix per-profile ListenBrainz playlist cache scoping and stale data recovery", - "• Harden metadata cache — prevent simplified data from overwriting full entries, fix connection leaks", - "• Scope automation-triggered watchlist scans to the calling profile", - "• Fix watchlist scan silently skipping all albums due to metadata cache returning incomplete data", - "• Optimized enhanced library view performance with event delegation and scoped DOM queries", - "• Fix Qobuz and HiFi streaming source checks that blocked playback with 'format not supported' error" - ] - }, - { - "title": "Library Issue Reporting", - "description": "Report and track issues for tracks, albums, and artists directly from the library", - "features": [ - "• Report issues on any library item — tracks, albums, or artists — with category, priority, and notes", - "• Actionable issue detail modal with album art, artist photo overlay, genre tags, and format badges", - "• Download Album and Add to Wishlist buttons directly from the issue modal (admin only)", - "• Enhanced-library-style track listing with format and bitrate indicators", - "• Smart album fetch — uses Spotify ID when available, falls back to enhanced search" - ] - }, - { - "title": "Album File Reorganization", - "description": "Reorganize album files on disk from the Enhanced Library Manager", - "features": [ - "• Move and rename album files to match your configured folder template", - "• Preview the reorganization with before/after file paths before applying", - "• Supports multi-disc albums with automatic disc subfolder creation", - "• Database paths updated automatically after files are moved" - ] - }, - { - "title": "Interactive REST API Docs", - "description": "Full API documentation with a built-in endpoint tester", - "features": [ - "• Comprehensive docs for all API endpoints organized by category", - "• Built-in endpoint tester — execute API calls directly from the docs page", - "• JSON response viewer with syntax highlighting and copy support", - "• Complete metadata serialization for all entity types" - ] - }, - { - "title": "Watchlist Improvements", - "description": "Smarter cross-provider matching, manual artist linking, and scan timestamp fixes", - "features": [ - "• Cross-provider artist matching now uses fuzzy name comparison instead of blindly taking the first result", - "• Manual artist linking UI — change the linked Spotify/iTunes artist from the watchlist config modal", - "• Mismatch warning when the linked provider artist name differs from the watchlist entry", - "• Watchlist settings gear button accessible from artist detail page and artist cards", - "• Scan timestamps preserved for UI display — 'Never scanned' no longer shows after lookback changes", - "• Lookback period changes use a one-time rescan flag instead of wiping all timestamps" - ] - }, - { - "title": "AcoustID Verification Fix", - "description": "More accurate audio file verification with broader title normalization", - "features": [ - "• Strip ALL parentheticals in title normalization — fixes false mismatches for parody, soundtrack, and featured artist suffixes", - "• Previously only whitelisted suffixes like (Live) and (Remastered) were stripped" - ] - }, - { - "title": "Deezer Playlist Sync", - "description": "Full Deezer integration for playlist sync alongside Spotify, Tidal, and YouTube", - "features": [ - "• Import and sync Deezer playlists with full track matching and discovery", - "• Deezer discovery worker with Spotify/iTunes match caching", - "• Fix modal for unmatched Deezer tracks with manual search", - "• Manual fixes persist to discovery cache across restarts" - ] - }, - { - "title": "Discovery Page Improvements", - "description": "Better playlist generation, caching, and iTunes parity", - "features": [ - "• iTunes discovery playlists now produce quality results — synthetic popularity scoring replaces broken 0-popularity tiering", - "• EPs included in iTunes discovery pool (previously excluded)", - "• Popular Picks and Hidden Gems playlists now work correctly for iTunes users", - "• Seasonal playlists fully work with iTunes — album search, watchlist search, and track fetching", - "• Similar artist metadata (images, genres, popularity) cached at scan time — no more redundant API calls", - "• Hero slider loads instantly from cache instead of making 10 Spotify API calls per page load", - "• View Recommended modal uses cached data — only uncached artists trigger API calls", - "• Album art now displays in discovery pool modal for both Spotify and iTunes matches" - ] - }, - { - "title": "Rate Limit Detection Fix", - "description": "Rate limit handling completely overhauled — escalating bans, no more rate limit loops", - "features": [ - "• Fixed rate limits going undetected in get_album, get_artist, and batch artist enrichment", - "• These methods previously swallowed 429 exceptions — global ban was never activated", - "• Escalating ban durations — repeated rate limits within 1 hour double the ban (30m → 1h → 2h → 4h max)", - "• Default ban raised from 10 minutes to 30 minutes — prevents rapid re-ban cycling", - "• Exhausted-retry detection — 5 consecutive 429s trigger a 1-hour ban instead of re-raising", - "• Rate limit modal with live countdown timer, ban duration, and triggering endpoint", - "• Redundant get_album_tracks API call removed from iTunes discovery pool population" - ] - }, - { - "title": "Download & Matching Fixes", - "description": "Accuracy improvements for album downloads and track matching", - "features": [ - "• Album download pre-flight search finds complete album folders before track-by-track downloading", - "• Fix wrong track downloads when album name matches a track title in hybrid mode", - "• Improved album download analysis with album-scoped track matching", - "• Fix Tidal playlist sync dropping remix/version info from track titles", - "• Race guard verification extended to all download source monitors" - ] - }, - { - "title": "Security & Config", - "description": "Encryption at rest and config improvements", - "features": [ - "• Sensitive config values (API keys, passwords, tokens) encrypted at rest with Fernet", - "• Transparent migration — existing plaintext values auto-encrypt on first load", - "• Tidal OAuth fix — override Accept header on token requests" - ] - }, - { - "title": "Recent Bug Fixes", - "description": "Stability and UX fixes", - "features": [ - "• Fix sync stuck at 80% — serialize datetime in SyncResult for WebSocket emit", - "• Fix automated scans for non-Plex servers and incremental scan performance", - "• Fix Tidal/Qobuz enrichment backfill failing on dict-type copyright and isrc fields", - "• Fix false positive track matching and tag writing visibility for library files", - "• Stop unnecessary Spotify API call every 60s from enrichment status polling", - "• Spotify rate limit UX — persistent modal with countdown, dismiss, and disconnect buttons", - "• Navidrome ReportRealPath guidance when library files can't be found", - "• Enhanced library write-all modal and confirmation dialog improvements" - ] - }, - { - "title": "Tidal & Qobuz Enrichment Workers", - "description": "Two new background enrichment workers for Tidal and Qobuz metadata", - "features": [ - "• Tidal worker enriches artists, albums, and tracks with Tidal IDs, thumbnails, and metadata", - "• Qobuz worker enriches artists, albums, and tracks with Qobuz IDs, labels, genres, and metadata", - "• Dashboard buttons with real-time status, progress tracking, and pause/resume controls", - "• Smart no-auth detection — buttons grey out when not authenticated to either service", - "• Module-level rate limiting for Qobuz — shared throttle across all client instances", - "• Full Enhanced Library Manager integration — status chips, manual matching, clickable service badges", - "• Library artist card badges and discography 'View on' buttons for both services", - "• Total enrichment worker count now at 9: Spotify, iTunes, MusicBrainz, AudioDB, Deezer, Last.fm, Genius, Tidal, Qobuz" - ] - }, - { - "title": "Full Qobuz Support", - "description": "Qobuz added as a first-class download source alongside Tidal and Soulseek", - "features": [ - "• Search, browse, and download from Qobuz with quality selection up to Hi-Res 24-bit/192kHz", - "• Qobuz appears as a download source in hybrid mode with configurable priority", - "• Playlist import from Qobuz URLs with mirrored playlist support", - "• Settings page integration with conditional source visibility" - ] - }, - { - "title": "Hybrid Mode Redesign", - "description": "Overhauled download source selection and priority system", - "features": [ - "• Redesigned hybrid mode with drag-and-drop source priority ordering", - "• Tidal, Qobuz, and Soulseek sources with per-source quality preferences", - "• Conditional settings — source-specific options only appear when that source is enabled", - "• Reorganized settings page with clearer Download Source section" - ] - }, - { - "title": "Spotify Rate Limit Protection", - "description": "Smart detection and handling of Spotify API rate limits with escalating bans", - "features": [ - "• Automatic detection of long rate limit bans (Retry-After > 60s) from Spotify", - "• Escalating ban durations — repeated hits within 1 hour double the ban (30m → 1h → 2h → 4h)", - "• Global suppression of all Spotify API calls during a ban — no wasted requests", - "• Seamless iTunes/Apple Music fallback for searches while Spotify is rate limited", - "• Enrichment worker auto-pauses during rate limit and resumes when ban expires", - "• Rate limit modal with live countdown timer, ban duration, triggering endpoint, and dismiss/disconnect buttons", - "• One-click Disconnect Spotify button to clear ban, pause enrichment, and delete cache", - "• Auth probe no longer makes API calls during ban — prevents extending the ban", - "• Cooldown-to-restored transition auto-closes modal and refreshes discover page" - ] - }, - { - "title": "Profile Permissions & Page Access Control", - "description": "Granular admin controls over what each profile can see and do", - "features": [ - "• Admin can control which sidebar pages each profile can access", - "• Per-profile download toggle — disable downloading for specific users (frontend + backend enforced)", - "• Per-user home page — every user can choose their own landing page", - "• Enhanced Library Manager restricted to admin profiles only", - "• Non-admin users default to Discover page instead of Dashboard" - ] - }, - { - "title": "Now Playing Overhaul", - "description": "Redesigned media player with expanded Now Playing modal and smart radio", - "features": [ - "• Expanded Now Playing modal — click the sidebar player to open a full-screen experience", - "• Album art ambient glow — dominant color from cover art tints the modal background", - "• Smart Radio mode — auto-queue up to 50 similar tracks based on genre, mood, and style", - "• Queue system — add tracks from the library, manage queue in Now Playing modal", - "• Web Audio visualizer — real frequency-driven bars responding to actual playback", - "• Repeat modes (off, repeat-all, repeat-one), shuffle, Media Session API controls", - "• Keyboard shortcuts — Space, arrows, M (mute), Escape (close)" - ] - }, - { - "title": "Enhanced Library Manager", - "description": "Professional-grade library management with tag writing and server sync", - "features": [ - "• Toggle between Standard and Enhanced views on any artist's discography", - "• Inline metadata editing — click any field to edit artist, album, or track data", - "• Per-service manual matching for all 9 enrichment services", - "• Write Tags to File — sync database metadata to audio file tags (MP3/FLAC/OGG/M4A)", - "• Tag preview modal showing a diff of file vs database values before writing", - "• Batch write tags for entire albums or bulk-selected tracks with live progress", - "• Optional cover art embedding with per-album caching", - "• Server sync after tag writes — push updated metadata to Plex, Jellyfin, or Navidrome", - "• Bulk select and batch edit tracks across albums", - "• Sortable track table columns, multi-disc support, play tracks from library" - ], - "usage_note": "Open any artist's detail page and click 'Enhanced' in the view toggle to access the library manager." - }, - { - "title": "Last.fm & Genius Enrichment Workers", - "description": "Background enrichment workers for Last.fm and Genius metadata", - "features": [ - "• Last.fm worker enriches artists, albums, and tracks with listener counts, play counts, tags, and bios", - "• Genius worker enriches artists and tracks with descriptions, alternate names, and lyrics", - "• Dashboard buttons with status, progress, and pause/resume controls", - "• No-auth detection — buttons grey out with guidance when API keys are missing", - "• Settings reload — changing API keys takes effect immediately without restarting" - ] - }, - { - "title": "UI & Visual Overhaul", - "description": "Per-page particle animations, sidebar visualizer, watchlist redesign, and design refresh", - "features": [ - "• Per-page particle animations with unique themes for each page", - "• Particle toggle in Settings — disable background particles to reduce GPU usage", - "• Sidebar audio visualizer with 5 reactive styles and settings toggle", - "• Sidebar SVG icons with accent-colored navigation and ambient aura", - "• Watchlist modal redesign — gradient overlay cards, staggered entrance animations, SVG icon buttons, glassmorphic styling", - "• Settings page visual refresh — premium header, custom toggle switches, refined input styling", - "• Page headers with sidebar icons and gradient shimmer styling", - "• Service badges on library artist cards for all 9 enrichment services", - "• Glassmorphic 'View on' buttons on artist discography pages", - "• Help & Docs page — comprehensive in-app documentation covering every feature" - ] - }, - { - "title": "Tidal Download Improvements", - "description": "Stability and accuracy fixes for Tidal downloads", - "features": [ - "• Tidal download validation — detect and clean up unplayable hi-res stubs", - "• Tidal playlist pagination rate limiting with exponential backoff", - "• Include Tidal version field in track names — fixes remixes resolving to base title", - "• Direct single-playlist fetch instead of redundantly re-fetching all playlists" - ] - }, - { - "title": "Bug Fixes & Stability", - "description": "Reliability improvements across the board", - "features": [ - "• Fix Genius search blindly matching wrong artists — all bad matches auto-reset", - "• Fix library page albums merging across different artists with same album title/year", - "• Fix post-processing race condition on files already moved by another thread", - "• iTunes storefront fallback — ID lookups automatically try 10 regional storefronts", - "• Fix infinite Spotify rate limit loop from unguarded auth probes", - "• Fix playlist folder downloads marked as failed despite successful processing", - "• Fix Docker upgrade crashes from stale volume mounts and partial DB migrations", - "• Isolate service client initialization so one failure doesn't break the app", - "• Explicit content filter with configurable toggle to skip explicit tracks", -""" # end of _OLD_V2_NOTES_REMOVED - def _simple_monitor_task(): """The actual monitoring task that runs in the background thread.