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
This commit is contained in:
parent
deadfa1e82
commit
571ba6b532
2 changed files with 73 additions and 41 deletions
108
web_server.py
108
web_server.py
|
|
@ -31,7 +31,7 @@ from config.settings import config_manager
|
|||
logger = get_logger("web_server")
|
||||
|
||||
# App version — single source of truth for backup metadata, version-info endpoint, etc.
|
||||
SOULSYNC_VERSION = "2.0"
|
||||
SOULSYNC_VERSION = "2.1"
|
||||
|
||||
# Dedicated source reuse logger — writes to logs/source_reuse.log
|
||||
import logging as _logging
|
||||
|
|
@ -18490,6 +18490,18 @@ def get_version_info():
|
|||
"title": "What's New in SoulSync",
|
||||
"subtitle": f"Version {SOULSYNC_VERSION} — Latest Changes",
|
||||
"sections": [
|
||||
{
|
||||
"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",
|
||||
|
|
@ -18565,47 +18577,72 @@ def get_version_info():
|
|||
"• 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 — enter API secret, click Authorize, session key stored permanently",
|
||||
"• ListenBrainz: simple token-based — enable toggle and plays are submitted automatically",
|
||||
"• Batch scrobbling with dedup tracking — events only scrobbled once, never duplicated",
|
||||
"• Both services fully opt-in via Settings toggles"
|
||||
"• Last.fm: full web auth flow, ListenBrainz: simple token-based",
|
||||
"• Batch scrobbling with dedup tracking — events only scrobbled once"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "🧠 Personalized Discovery",
|
||||
"description": "Discovery playlists now use your listening history to recommend better music",
|
||||
"title": "🧠 Personalized Discovery + Listening Stats",
|
||||
"description": "Discovery playlists use your listening history, plus a full stats dashboard",
|
||||
"features": [
|
||||
"• Release Radar: genre affinity (+10), artist familiarity (+15), overplay penalty (-10) scoring",
|
||||
"• Discovery Weekly: serendipity weighting — boosts unheard artists in your favorite genres",
|
||||
"• Recent Albums: adaptive time window (21-60 days) based on how fast you consume music",
|
||||
"• New 'Because You Listen To' sections: personalized carousels for your top 3 artists",
|
||||
"• Familiar Favorites weighted by actual play count, not random sampling",
|
||||
"• All personalization gracefully falls back for new users with no listening data"
|
||||
"• 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": "📊 Listening Stats Page",
|
||||
"description": "Full stats dashboard with Chart.js visualizations of your listening habits",
|
||||
"features": [
|
||||
"• Overview cards: total plays, listening time, unique artists/albums/tracks",
|
||||
"• Listening activity timeline bar chart with 7d/30d/12m/all time ranges",
|
||||
"• Genre breakdown doughnut chart with percentage legend",
|
||||
"• Top artists visual bubbles with profile pictures + ranked lists",
|
||||
"• Top albums and tracks with album art, clickable artist names",
|
||||
"• Library health: format breakdown bar, unplayed tracks, enrichment coverage",
|
||||
"• Sync Now button for instant data refresh from your media server",
|
||||
"• Background worker polls Plex/Jellyfin/Navidrome every 30 minutes",
|
||||
"• Pre-computed cache — tab switching is instant"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "🆔 SoulID Worker",
|
||||
"description": "Deterministic identity system for cross-node artist/album/track matching",
|
||||
}
|
||||
]
|
||||
}
|
||||
return jsonify(version_data)
|
||||
|
||||
_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",
|
||||
|
|
@ -19160,12 +19197,7 @@ def get_version_info():
|
|||
"• 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",
|
||||
"• Full Cleanup automation for quarantine, downloads, staging, and search history"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
return jsonify(version_data)
|
||||
""" # end of _OLD_V2_NOTES_REMOVED
|
||||
|
||||
|
||||
def _simple_monitor_task():
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@
|
|||
</button>
|
||||
<div class="volume-control">
|
||||
<span class="volume-icon">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.16c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.16c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
</span>
|
||||
<input type="range" class="volume-slider" id="volume-slider" min="0" max="100" value="70">
|
||||
</div>
|
||||
|
|
@ -271,7 +271,7 @@
|
|||
|
||||
<!-- Version Section -->
|
||||
<div class="version-section">
|
||||
<button class="version-button" onclick="showVersionInfo()">v2.0</button>
|
||||
<button class="version-button" onclick="showVersionInfo()">v2.1</button>
|
||||
</div>
|
||||
|
||||
<!-- Status Section -->
|
||||
|
|
@ -5626,7 +5626,7 @@
|
|||
<!-- Header -->
|
||||
<div class="version-modal-header">
|
||||
<h2 class="version-modal-title">What's New in SoulSync</h2>
|
||||
<div class="version-modal-subtitle">Version 2.0 — Latest Changes</div>
|
||||
<div class="version-modal-subtitle">Version 2.1 — Latest Changes</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Area with Scroll -->
|
||||
|
|
|
|||
Loading…
Reference in a new issue