Profiles: label the no-auth Spotify composite everywhere it's shown
Follow-up to the modal fix: the sidebar Service Status + dashboard service card
also mislabeled "Spotify (no auth)" as plain "Spotify". They read the status
`source`, which came straight from metadata.fallback_source ('spotify') with no
awareness of the metadata.spotify_free flag.
- get_primary_source_status now reports a DISPLAY source of 'spotify_free' when
fallback_source='spotify' + metadata.spotify_free is set (the raw 'spotify' is
still used for the auth/connected checks), and treats the free path's
availability as "connected" so the dot isn't falsely red on a no-auth setup.
- getMetadataSourceLabel maps 'spotify_free' → "Spotify (no auth)"; the status
presentation treats spotify_free as part of the Spotify family (session /
rate-limit / cooldown display still work). Added a SOURCE_LABELS entry.
- testDashboardConnection normalizes spotify_free → spotify (the only logic
consumer of the source value — the dashboard Test button).
Routing is unchanged (the real source stays 'spotify' + free flag); this is
purely the display layer. Settings was always correct. 64 integrity tests pass;
the 2 failing soundcloud tests are pre-existing (confirmed identical on a clean
tree).
This commit is contained in:
parent
6c05ec3670
commit
22947794e0
3 changed files with 34 additions and 5 deletions
|
|
@ -415,6 +415,14 @@ def get_primary_source_status(
|
||||||
)
|
)
|
||||||
if source == "spotify":
|
if source == "spotify":
|
||||||
connected = bool(client and client.is_spotify_authenticated())
|
connected = bool(client and client.is_spotify_authenticated())
|
||||||
|
# No-auth composite (fallback_source='spotify' + metadata.spotify_free):
|
||||||
|
# works without authentication, so treat the free path's availability
|
||||||
|
# as "connected" too.
|
||||||
|
if not connected and _get_config_value("metadata.spotify_free", False):
|
||||||
|
try:
|
||||||
|
connected = bool(client and client.is_spotify_metadata_available())
|
||||||
|
except Exception:
|
||||||
|
connected = False
|
||||||
elif source == "hydrabase":
|
elif source == "hydrabase":
|
||||||
connected = bool(client and (client.is_connected() if hasattr(client, "is_connected") else client.is_authenticated()))
|
connected = bool(client and (client.is_connected() if hasattr(client, "is_connected") else client.is_authenticated()))
|
||||||
elif client is not None and hasattr(client, "is_authenticated"):
|
elif client is not None and hasattr(client, "is_authenticated"):
|
||||||
|
|
@ -424,8 +432,17 @@ def get_primary_source_status(
|
||||||
except Exception:
|
except Exception:
|
||||||
connected = False
|
connected = False
|
||||||
|
|
||||||
|
# Report the composite-aware source for DISPLAY: "Spotify (no auth)" is
|
||||||
|
# stored as fallback_source='spotify' + metadata.spotify_free=true. The raw
|
||||||
|
# 'spotify' is kept above for the connected/auth checks; consumers that
|
||||||
|
# label the source (sidebar, dashboard card) get 'spotify_free' so they
|
||||||
|
# stop mislabeling no-auth as plain Spotify.
|
||||||
|
display_source = source
|
||||||
|
if source == "spotify" and _get_config_value("metadata.spotify_free", False):
|
||||||
|
display_source = "spotify_free"
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"source": source,
|
"source": display_source,
|
||||||
"connected": connected,
|
"connected": connected,
|
||||||
"response_time": round((time.time() - started) * 1000, 1),
|
"response_time": round((time.time() - started) * 1000, 1),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3438,6 +3438,9 @@ async function revokeApiKey(keyId, label) {
|
||||||
|
|
||||||
// Dashboard-specific test functions that create activity items
|
// Dashboard-specific test functions that create activity items
|
||||||
async function testDashboardConnection(service) {
|
async function testDashboardConnection(service) {
|
||||||
|
// 'spotify_free' is a display-only label for the no-auth composite; the real
|
||||||
|
// service to test is 'spotify'.
|
||||||
|
if (service === 'spotify_free') service = 'spotify';
|
||||||
try {
|
try {
|
||||||
showLoadingOverlay(`Testing ${service} service...`);
|
showLoadingOverlay(`Testing ${service} service...`);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ const SOURCE_LABELS = {
|
||||||
logo: 'https://storage.googleapis.com/pr-newsroom-wp/1/2023/05/Spotify_Primary_Logo_RGB_Green.png',
|
logo: 'https://storage.googleapis.com/pr-newsroom-wp/1/2023/05/Spotify_Primary_Logo_RGB_Green.png',
|
||||||
tabClass: 'enh-tab-spotify', badgeClass: 'enh-badge-spotify',
|
tabClass: 'enh-tab-spotify', badgeClass: 'enh-badge-spotify',
|
||||||
},
|
},
|
||||||
|
spotify_free: {
|
||||||
|
text: 'Spotify (no auth)', icon: '🎵',
|
||||||
|
logo: 'https://storage.googleapis.com/pr-newsroom-wp/1/2023/05/Spotify_Primary_Logo_RGB_Green.png',
|
||||||
|
tabClass: 'enh-tab-spotify', badgeClass: 'enh-badge-spotify',
|
||||||
|
},
|
||||||
itunes: {
|
itunes: {
|
||||||
text: 'Apple Music', icon: '🍎',
|
text: 'Apple Music', icon: '🍎',
|
||||||
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/ITunes_logo.svg/960px-ITunes_logo.svg.png',
|
logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/ITunes_logo.svg/960px-ITunes_logo.svg.png',
|
||||||
|
|
@ -3633,6 +3638,7 @@ function getMetadataSourceLabel(source) {
|
||||||
if (source === 'hydrabase') return 'Hydrabase';
|
if (source === 'hydrabase') return 'Hydrabase';
|
||||||
if (source === 'itunes') return 'iTunes';
|
if (source === 'itunes') return 'iTunes';
|
||||||
if (source === 'musicbrainz') return 'MusicBrainz';
|
if (source === 'musicbrainz') return 'MusicBrainz';
|
||||||
|
if (source === 'spotify_free') return 'Spotify (no auth)';
|
||||||
if (source === 'spotify') return 'Spotify';
|
if (source === 'spotify') return 'Spotify';
|
||||||
return 'Unmapped';
|
return 'Unmapped';
|
||||||
}
|
}
|
||||||
|
|
@ -3641,9 +3647,12 @@ function getMetadataSourcePresentation(metadataStatus, spotifyStatus) {
|
||||||
const source = metadataStatus?.source;
|
const source = metadataStatus?.source;
|
||||||
const sourceLabel = getMetadataSourceLabel(source);
|
const sourceLabel = getMetadataSourceLabel(source);
|
||||||
const connected = metadataStatus?.connected === true;
|
const connected = metadataStatus?.connected === true;
|
||||||
const sessionActive = spotifyStatus?.authenticated === true || (source === 'spotify' && connected);
|
// 'spotify_free' (the no-auth composite) is part of the Spotify family for
|
||||||
const rateLimited = !!(source === 'spotify' && spotifyStatus?.rate_limited && spotifyStatus?.rate_limit);
|
// session/rate-limit/cooldown display.
|
||||||
const cooldown = !!(source === 'spotify' && spotifyStatus?.post_ban_cooldown > 0);
|
const spotifyFamily = (source === 'spotify' || source === 'spotify_free');
|
||||||
|
const sessionActive = spotifyStatus?.authenticated === true || (spotifyFamily && connected);
|
||||||
|
const rateLimited = !!(spotifyFamily && spotifyStatus?.rate_limited && spotifyStatus?.rate_limit);
|
||||||
|
const cooldown = !!(spotifyFamily && spotifyStatus?.post_ban_cooldown > 0);
|
||||||
|
|
||||||
if (rateLimited) {
|
if (rateLimited) {
|
||||||
const remaining = spotifyStatus.rate_limit?.remaining_seconds || 0;
|
const remaining = spotifyStatus.rate_limit?.remaining_seconds || 0;
|
||||||
|
|
@ -3670,7 +3679,7 @@ function getMetadataSourcePresentation(metadataStatus, spotifyStatus) {
|
||||||
if (source) {
|
if (source) {
|
||||||
return {
|
return {
|
||||||
statusClass: connected ? 'connected' : 'disconnected',
|
statusClass: connected ? 'connected' : 'disconnected',
|
||||||
statusText: connected ? (source === 'spotify' ? `Connected (${metadataStatus?.response_time}ms)` : sourceLabel) : 'Disconnected',
|
statusText: connected ? (spotifyFamily ? `Connected (${metadataStatus?.response_time}ms)` : sourceLabel) : 'Disconnected',
|
||||||
dotClass: connected ? 'connected' : 'disconnected',
|
dotClass: connected ? 'connected' : 'disconnected',
|
||||||
dotTitle: connected ? sourceLabel : 'Disconnected',
|
dotTitle: connected ? sourceLabel : 'Disconnected',
|
||||||
sessionActive
|
sessionActive
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue