From ab8e44dafda92c7a64c0562d0e993e979de735e7 Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Mon, 30 Mar 2026 08:45:30 -0700 Subject: [PATCH] Add Qobuz credentials to Settings Connections tab (#218) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qobuz login was only available on the Downloads tab when Qobuz was selected as download source. But Qobuz credentials are also needed for the enrichment worker which runs independently. Users saw "Connect Qobuz in Settings" on the dashboard but couldn't find it. Adds a Qobuz section to Settings → Connections (same pattern as Tidal's existing Connections section). checkQobuzAuthStatus() now syncs both the Connections and Downloads tab sections. Login from either tab updates both. No backend changes — same API endpoints. --- web_server.py | 9 ++++++ webui/index.html | 32 ++++++++++++++++++++ webui/static/helper.js | 1 + webui/static/script.js | 69 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/web_server.py b/web_server.py index 9b5664ae..84a881a2 100644 --- a/web_server.py +++ b/web_server.py @@ -19071,6 +19071,15 @@ def get_version_info(): "title": "What's New in SoulSync", "subtitle": f"Version {SOULSYNC_VERSION} — Latest Changes", "sections": [ + { + "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", diff --git a/webui/index.html b/webui/index.html index 49903477..7bf055d1 100644 --- a/webui/index.html +++ b/webui/index.html @@ -3632,6 +3632,38 @@ + +
+

Qobuz (Metadata & Enrichment)

+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+ Connects Qobuz for metadata enrichment (ISRC, labels, copyright). Also used for downloads if Qobuz is your download source. +
+
+

ListenBrainz

diff --git a/webui/static/helper.js b/webui/static/helper.js index 1f0f0201..9d145aa1 100644 --- a/webui/static/helper.js +++ b/webui/static/helper.js @@ -3403,6 +3403,7 @@ function closeHelperSearch() { const WHATS_NEW = { '2.1': [ // Newest features first + { title: 'Qobuz on Connections Tab', desc: 'Qobuz credentials now on Settings → Connections for metadata enrichment without needing it as download source' }, { title: 'Fix Enrichment Status Widget', desc: 'Enrichment tooltip now shows Rate Limited or Daily Limit instead of stuck on Running' }, { title: 'Cache Maintenance', desc: 'Cache evictor now cleans junk entities, orphaned searches, and stale MusicBrainz nulls' }, { title: 'Fix Wishlist Download Selection', desc: 'Download Selection now only downloads checked tracks instead of the entire category' }, diff --git a/webui/static/script.js b/webui/static/script.js index 0255d9dc..cb7d1c39 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -7602,24 +7602,83 @@ async function checkQobuzAuthStatus() { try { const resp = await fetch('/api/qobuz/auth/status'); const data = await resp.json(); + + // Update downloads tab section const formEl = document.getElementById('qobuz-auth-form'); const loggedInEl = document.getElementById('qobuz-auth-logged-in'); const userInfoEl = document.getElementById('qobuz-auth-user-info'); + // Update connections tab section + const connFormEl = document.getElementById('qobuz-connection-form'); + const connLoggedInEl = document.getElementById('qobuz-connection-logged-in'); + const connUserInfoEl = document.getElementById('qobuz-connection-user-info'); + if (data.authenticated) { const user = data.user || {}; - userInfoEl.textContent = `Connected: ${user.display_name || 'Qobuz User'} (${user.subscription || 'Active'})`; - loggedInEl.style.display = 'flex'; - formEl.style.display = 'none'; + const label = `Connected: ${user.display_name || 'Qobuz User'} (${user.subscription || 'Active'})`; + + if (userInfoEl) { userInfoEl.textContent = label; } + if (loggedInEl) loggedInEl.style.display = 'flex'; + if (formEl) formEl.style.display = 'none'; + + if (connUserInfoEl) { connUserInfoEl.textContent = label; } + if (connLoggedInEl) connLoggedInEl.style.display = 'flex'; + if (connFormEl) connFormEl.style.display = 'none'; } else { - loggedInEl.style.display = 'none'; - formEl.style.display = 'block'; + if (loggedInEl) loggedInEl.style.display = 'none'; + if (formEl) formEl.style.display = 'block'; + + if (connLoggedInEl) connLoggedInEl.style.display = 'none'; + if (connFormEl) connFormEl.style.display = 'block'; } } catch (e) { console.error('Qobuz auth status check failed:', e); } } +async function loginQobuzFromConnections() { + const btn = document.getElementById('qobuz-connection-login-btn'); + const statusEl = document.getElementById('qobuz-connection-status'); + const email = document.getElementById('qobuz-connection-email').value.trim(); + const password = document.getElementById('qobuz-connection-password').value; + + if (!email || !password) { + showToast('Please enter your Qobuz email and password', 'warning'); + return; + } + + btn.disabled = true; + btn.textContent = 'Connecting...'; + statusEl.textContent = ''; + + try { + const resp = await fetch('/api/qobuz/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password }), + }); + const data = await resp.json(); + + if (data.success) { + showToast('Qobuz connected successfully!', 'success'); + document.getElementById('qobuz-connection-password').value = ''; + checkQobuzAuthStatus(); + } else { + statusEl.textContent = data.error || 'Login failed'; + statusEl.style.color = '#ff5555'; + showToast(data.error || 'Qobuz login failed', 'error'); + } + } catch (error) { + console.error('Qobuz login error:', error); + statusEl.textContent = 'Connection error'; + statusEl.style.color = '#ff5555'; + showToast('Failed to connect to Qobuz', 'error'); + } finally { + btn.disabled = false; + btn.textContent = 'Connect Qobuz'; + } +} + async function loginQobuz() { const btn = document.getElementById('qobuz-login-btn'); const statusEl = document.getElementById('qobuz-auth-status');