include listenbrainz on settings page

This commit is contained in:
Broque Thomas 2025-11-17 22:20:30 -08:00
parent c28d7ff407
commit a50e5a59d9
5 changed files with 59 additions and 2 deletions

View file

@ -46,5 +46,8 @@
},
"playlist_sync": {
"create_backup": true
},
"listenbrainz": {
"token": "LISTENBRAINZ_TOKEN"
}
}

View file

@ -1361,6 +1361,34 @@ def run_service_test(service, test_config):
return True, "Successfully connected to slskd."
else:
return False, "Could not connect to slskd. Check URL and API Key."
elif service == "listenbrainz":
token = test_config.get('token', '')
if not token:
return False, "Missing ListenBrainz user token."
try:
# Test ListenBrainz API by validating the token
url = "https://api.listenbrainz.org/1/validate-token"
headers = {
'Authorization': f'Token {token}'
}
response = requests.get(url, headers=headers, timeout=5)
if response.status_code == 200:
data = response.json()
if data.get('valid'):
username = data.get('user_name', 'Unknown')
return True, f"Successfully connected to ListenBrainz! Connected as: {username}"
else:
return False, "Invalid ListenBrainz token."
elif response.status_code == 401:
return False, "Invalid ListenBrainz token (unauthorized)."
else:
return False, f"Could not connect to ListenBrainz (HTTP {response.status_code})"
except Exception as e:
return False, f"ListenBrainz connection error: {str(e)}"
return False, "Unknown service."
except AttributeError as e:
# This specifically catches the error you reported for Jellyfin
@ -2048,6 +2076,8 @@ def test_connection_endpoint():
elif service == 'soulseek':
# Soulseek doesn't use cache, but update anyway for consistency
print("✅ Soulseek test successful")
elif service == 'listenbrainz':
print("✅ ListenBrainz test successful")
# Add activity for connection test
if success:

View file

@ -2248,12 +2248,25 @@
<input type="password" id="soulseek-api-key" placeholder="Slskd API Key">
</div>
</div>
<!-- ListenBrainz Settings -->
<div class="api-service-frame">
<h4 class="service-title listenbrainz-title">ListenBrainz</h4>
<div class="form-group">
<label>User Token:</label>
<input type="password" id="listenbrainz-token" placeholder="ListenBrainz User Token">
</div>
<div class="callback-info">
<div class="callback-help">Get your token from <a href="https://listenbrainz.org/profile/" target="_blank" style="color: #eb743b;">ListenBrainz Settings</a></div>
</div>
</div>
<!-- Test Connection Buttons -->
<div class="api-test-buttons">
<button class="test-button" onclick="testConnection('spotify')">Test Spotify</button>
<button class="test-button" onclick="testConnection('tidal')">Test Tidal</button>
<button class="test-button" onclick="testConnection('soulseek')">Test Soulseek</button>
<button class="test-button" onclick="testConnection('listenbrainz')">Test ListenBrainz</button>
</div>
</div>

View file

@ -1467,6 +1467,9 @@ async function loadSettingsData() {
document.getElementById('soulseek-url').value = settings.soulseek?.slskd_url || '';
document.getElementById('soulseek-api-key').value = settings.soulseek?.api_key || '';
// Populate ListenBrainz settings
document.getElementById('listenbrainz-token').value = settings.listenbrainz?.token || '';
// Populate Download settings (right column)
document.getElementById('download-path').value = settings.soulseek?.download_path || './downloads';
document.getElementById('transfer-path').value = settings.soulseek?.transfer_path || './Transfer';
@ -1775,6 +1778,9 @@ async function saveSettings() {
download_path: document.getElementById('download-path').value,
transfer_path: document.getElementById('transfer-path').value
},
listenbrainz: {
token: document.getElementById('listenbrainz-token').value
},
database: {
max_workers: parseInt(document.getElementById('max-workers').value)
},

View file

@ -1094,6 +1094,10 @@ body {
color: #5dade2;
}
.listenbrainz-title {
color: #eb743b;
}
/* Server Toggle Buttons */
.server-toggle-container {
display: flex;
@ -1593,7 +1597,8 @@ body {
.api-test-buttons .test-button {
flex: 1;
min-width: 80px;
min-width: 120px;
max-width: calc(33.333% - 6px);
}
/* Server Test Section */