include listenbrainz on settings page
This commit is contained in:
parent
c28d7ff407
commit
a50e5a59d9
5 changed files with 59 additions and 2 deletions
|
|
@ -46,5 +46,8 @@
|
||||||
},
|
},
|
||||||
"playlist_sync": {
|
"playlist_sync": {
|
||||||
"create_backup": true
|
"create_backup": true
|
||||||
|
},
|
||||||
|
"listenbrainz": {
|
||||||
|
"token": "LISTENBRAINZ_TOKEN"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1361,6 +1361,34 @@ def run_service_test(service, test_config):
|
||||||
return True, "Successfully connected to slskd."
|
return True, "Successfully connected to slskd."
|
||||||
else:
|
else:
|
||||||
return False, "Could not connect to slskd. Check URL and API Key."
|
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."
|
return False, "Unknown service."
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
# This specifically catches the error you reported for Jellyfin
|
# This specifically catches the error you reported for Jellyfin
|
||||||
|
|
@ -2048,6 +2076,8 @@ def test_connection_endpoint():
|
||||||
elif service == 'soulseek':
|
elif service == 'soulseek':
|
||||||
# Soulseek doesn't use cache, but update anyway for consistency
|
# Soulseek doesn't use cache, but update anyway for consistency
|
||||||
print("✅ Soulseek test successful")
|
print("✅ Soulseek test successful")
|
||||||
|
elif service == 'listenbrainz':
|
||||||
|
print("✅ ListenBrainz test successful")
|
||||||
|
|
||||||
# Add activity for connection test
|
# Add activity for connection test
|
||||||
if success:
|
if success:
|
||||||
|
|
|
||||||
|
|
@ -2249,11 +2249,24 @@
|
||||||
</div>
|
</div>
|
||||||
</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 -->
|
<!-- Test Connection Buttons -->
|
||||||
<div class="api-test-buttons">
|
<div class="api-test-buttons">
|
||||||
<button class="test-button" onclick="testConnection('spotify')">Test Spotify</button>
|
<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('tidal')">Test Tidal</button>
|
||||||
<button class="test-button" onclick="testConnection('soulseek')">Test Soulseek</button>
|
<button class="test-button" onclick="testConnection('soulseek')">Test Soulseek</button>
|
||||||
|
<button class="test-button" onclick="testConnection('listenbrainz')">Test ListenBrainz</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1467,6 +1467,9 @@ async function loadSettingsData() {
|
||||||
document.getElementById('soulseek-url').value = settings.soulseek?.slskd_url || '';
|
document.getElementById('soulseek-url').value = settings.soulseek?.slskd_url || '';
|
||||||
document.getElementById('soulseek-api-key').value = settings.soulseek?.api_key || '';
|
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)
|
// Populate Download settings (right column)
|
||||||
document.getElementById('download-path').value = settings.soulseek?.download_path || './downloads';
|
document.getElementById('download-path').value = settings.soulseek?.download_path || './downloads';
|
||||||
document.getElementById('transfer-path').value = settings.soulseek?.transfer_path || './Transfer';
|
document.getElementById('transfer-path').value = settings.soulseek?.transfer_path || './Transfer';
|
||||||
|
|
@ -1775,6 +1778,9 @@ async function saveSettings() {
|
||||||
download_path: document.getElementById('download-path').value,
|
download_path: document.getElementById('download-path').value,
|
||||||
transfer_path: document.getElementById('transfer-path').value
|
transfer_path: document.getElementById('transfer-path').value
|
||||||
},
|
},
|
||||||
|
listenbrainz: {
|
||||||
|
token: document.getElementById('listenbrainz-token').value
|
||||||
|
},
|
||||||
database: {
|
database: {
|
||||||
max_workers: parseInt(document.getElementById('max-workers').value)
|
max_workers: parseInt(document.getElementById('max-workers').value)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1094,6 +1094,10 @@ body {
|
||||||
color: #5dade2;
|
color: #5dade2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.listenbrainz-title {
|
||||||
|
color: #eb743b;
|
||||||
|
}
|
||||||
|
|
||||||
/* Server Toggle Buttons */
|
/* Server Toggle Buttons */
|
||||||
.server-toggle-container {
|
.server-toggle-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -1593,7 +1597,8 @@ body {
|
||||||
|
|
||||||
.api-test-buttons .test-button {
|
.api-test-buttons .test-button {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 80px;
|
min-width: 120px;
|
||||||
|
max-width: calc(33.333% - 6px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Server Test Section */
|
/* Server Test Section */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue