Rename status cache to metadata_source
Expose the primary metadata provider status under a generic cache key and update the websocket fixture plus frontend readers to match.
This commit is contained in:
parent
1d9d399a2f
commit
36267618a3
8 changed files with 73 additions and 73 deletions
|
|
@ -17,7 +17,7 @@ from flask_socketio import SocketIO, join_room, leave_room
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
_DEFAULT_STATUS_CACHE = {
|
||||
'spotify': {'connected': True, 'authenticated': True, 'response_time': 12.5, 'source': 'spotify'},
|
||||
'metadata_source': {'connected': True, 'authenticated': True, 'response_time': 12.5, 'source': 'spotify'},
|
||||
'media_server': {'connected': True, 'response_time': 8.1, 'type': 'plex'},
|
||||
'soulseek': {'connected': True, 'response_time': 5.3, 'source': 'soulseek'},
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ wishlist_stats_state = copy.deepcopy(_DEFAULT_WISHLIST_STATS)
|
|||
|
||||
def _build_status_payload():
|
||||
return {
|
||||
'spotify': dict(_status_cache['spotify']),
|
||||
'metadata_source': dict(_status_cache['metadata_source']),
|
||||
'media_server': dict(_status_cache['media_server']),
|
||||
'soulseek': dict(_status_cache['soulseek']),
|
||||
'active_media_server': _status_cache['media_server'].get('type', 'plex'),
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ class TestServiceStatus:
|
|||
status_events = [e for e in received if e['name'] == 'status:update']
|
||||
assert len(status_events) >= 1
|
||||
data = status_events[0]['args'][0]
|
||||
assert 'spotify' in data
|
||||
assert 'metadata_source' in data
|
||||
assert 'media_server' in data
|
||||
assert 'soulseek' in data
|
||||
assert 'active_media_server' in data
|
||||
assert 'authenticated' in data['spotify']
|
||||
assert 'authenticated' in data['metadata_source']
|
||||
|
||||
def test_status_matches_http(self, test_app, shared_state):
|
||||
"""Socket event data matches HTTP endpoint response exactly."""
|
||||
|
|
@ -73,7 +73,7 @@ class TestServiceStatus:
|
|||
assert len(status_events) >= 1
|
||||
ws_data = status_events[0]['args'][0]
|
||||
|
||||
assert ws_data['spotify'] == http_data['spotify']
|
||||
assert ws_data['metadata_source'] == http_data['metadata_source']
|
||||
assert ws_data['media_server'] == http_data['media_server']
|
||||
assert ws_data['soulseek'] == http_data['soulseek']
|
||||
assert ws_data['active_media_server'] == http_data['active_media_server']
|
||||
|
|
@ -86,13 +86,13 @@ class TestServiceStatus:
|
|||
build = shared_state['build_status_payload']
|
||||
|
||||
# Mutate cache
|
||||
status_cache['spotify']['source'] = 'itunes'
|
||||
status_cache['metadata_source']['source'] = 'itunes'
|
||||
|
||||
socketio.emit('status:update', build())
|
||||
received = client.get_received()
|
||||
status_events = [e for e in received if e['name'] == 'status:update']
|
||||
data = status_events[-1]['args'][0]
|
||||
assert data['spotify']['source'] == 'itunes'
|
||||
assert data['metadata_source']['source'] == 'itunes'
|
||||
|
||||
|
||||
# =========================================================================
|
||||
|
|
|
|||
|
|
@ -811,12 +811,12 @@ _idle_since = {}
|
|||
_IDLE_GRACE_SECONDS = 5
|
||||
|
||||
_status_cache = {
|
||||
'spotify': {'connected': False, 'authenticated': False, 'response_time': 0, 'source': 'itunes'},
|
||||
'metadata_source': {'connected': False, 'authenticated': False, 'response_time': 0, 'source': 'itunes'},
|
||||
'media_server': {'connected': False, 'response_time': 0, 'type': None},
|
||||
'soulseek': {'connected': False, 'response_time': 0},
|
||||
}
|
||||
_status_cache_timestamps: dict[str, float] = {
|
||||
'spotify': 0,
|
||||
'metadata_source': 0,
|
||||
'media_server': 0,
|
||||
'soulseek': 0,
|
||||
}
|
||||
|
|
@ -3447,12 +3447,12 @@ def get_status():
|
|||
active_server = config_manager.get_active_media_server()
|
||||
|
||||
# Test Spotify - with caching to avoid excessive API calls
|
||||
if current_time - _status_cache_timestamps['spotify'] > STATUS_CACHE_TTL:
|
||||
if current_time - _status_cache_timestamps['metadata_source'] > STATUS_CACHE_TTL:
|
||||
# Guard against spotify_client being None (partial init)
|
||||
is_rate_limited = spotify_client.is_rate_limited() if spotify_client else False
|
||||
rate_limit_info = spotify_client.get_rate_limit_info() if (spotify_client and is_rate_limited) else None
|
||||
cooldown_remaining = spotify_client.get_post_ban_cooldown_remaining() if spotify_client else 0
|
||||
spotify_session_active = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
metadata_source_authenticated = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
|
||||
# Read configured source once — no auth validation here, we do that explicitly below
|
||||
configured_source = config_manager.get('metadata.fallback_source', 'deezer') or 'deezer'
|
||||
|
|
@ -3461,27 +3461,27 @@ def get_status():
|
|||
# During rate limit or post-ban cooldown, skip the auth probe entirely.
|
||||
# Probing Spotify here would reset the rate limit timer.
|
||||
music_source = 'deezer' if configured_source == 'spotify' else configured_source
|
||||
spotify_response_time = 0
|
||||
metadata_source_response_time = 0
|
||||
else:
|
||||
spotify_start = time.time()
|
||||
spotify_connected = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
spotify_response_time = (time.time() - spotify_start) * 1000
|
||||
metadata_source_start = time.time()
|
||||
metadata_source_connected = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
metadata_source_response_time = (time.time() - metadata_source_start) * 1000
|
||||
# Use configured source; fall back to deezer only if Spotify isn't authenticated
|
||||
if configured_source == 'spotify':
|
||||
music_source = 'spotify' if spotify_connected else 'deezer'
|
||||
music_source = 'spotify' if metadata_source_connected else 'deezer'
|
||||
else:
|
||||
music_source = configured_source
|
||||
|
||||
_status_cache['spotify'] = {
|
||||
'connected': spotify_session_active,
|
||||
'authenticated': spotify_session_active,
|
||||
'response_time': round(spotify_response_time, 1),
|
||||
_status_cache['metadata_source'] = {
|
||||
'connected': metadata_source_authenticated,
|
||||
'authenticated': metadata_source_authenticated,
|
||||
'response_time': round(metadata_source_response_time, 1),
|
||||
'source': music_source,
|
||||
'rate_limited': is_rate_limited,
|
||||
'rate_limit': rate_limit_info,
|
||||
'post_ban_cooldown': cooldown_remaining if cooldown_remaining > 0 else None
|
||||
}
|
||||
_status_cache_timestamps['spotify'] = current_time
|
||||
_status_cache_timestamps['metadata_source'] = current_time
|
||||
# else: use cached value
|
||||
|
||||
# Test media server - use EXISTING instances (they have internal caching)
|
||||
|
|
@ -3556,7 +3556,7 @@ def get_status():
|
|||
active_dl_count += 1
|
||||
|
||||
status_data = {
|
||||
'spotify': _status_cache['spotify'],
|
||||
'metadata_source': _status_cache['metadata_source'],
|
||||
'media_server': _status_cache['media_server'],
|
||||
'soulseek': _status_cache['soulseek'],
|
||||
'active_media_server': active_server,
|
||||
|
|
@ -4186,7 +4186,7 @@ def handle_settings():
|
|||
if tidal_enrichment_worker:
|
||||
tidal_enrichment_worker.client = tidal_client
|
||||
# Invalidate status cache so next poll reflects new settings (e.g. fallback source change)
|
||||
_status_cache_timestamps['spotify'] = 0
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
logger.info("Service clients re-initialized with new settings.")
|
||||
return jsonify({"success": True, "message": "Settings saved successfully."})
|
||||
except Exception as e:
|
||||
|
|
@ -4804,10 +4804,10 @@ def test_connection_endpoint():
|
|||
current_time = time.time()
|
||||
if service == 'spotify':
|
||||
spotify_session_active = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
_status_cache['spotify']['connected'] = True
|
||||
_status_cache['spotify']['authenticated'] = spotify_session_active
|
||||
_status_cache['spotify']['source'] = _get_metadata_fallback_source()
|
||||
_status_cache_timestamps['spotify'] = current_time
|
||||
_status_cache['metadata_source']['connected'] = True
|
||||
_status_cache['metadata_source']['authenticated'] = spotify_session_active
|
||||
_status_cache['metadata_source']['source'] = _get_metadata_fallback_source()
|
||||
_status_cache_timestamps['metadata_source'] = current_time
|
||||
logger.info("Updated Spotify status cache after successful test")
|
||||
elif service in ['plex', 'jellyfin', 'navidrome', 'soulsync']:
|
||||
_status_cache['media_server']['connected'] = True
|
||||
|
|
@ -4972,10 +4972,10 @@ def test_dashboard_connection_endpoint():
|
|||
current_time = time.time()
|
||||
if service == 'spotify':
|
||||
spotify_session_active = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
_status_cache['spotify']['connected'] = True
|
||||
_status_cache['spotify']['authenticated'] = spotify_session_active
|
||||
_status_cache['spotify']['source'] = _get_metadata_fallback_source()
|
||||
_status_cache_timestamps['spotify'] = current_time
|
||||
_status_cache['metadata_source']['connected'] = True
|
||||
_status_cache['metadata_source']['authenticated'] = spotify_session_active
|
||||
_status_cache['metadata_source']['source'] = _get_metadata_fallback_source()
|
||||
_status_cache_timestamps['metadata_source'] = current_time
|
||||
logger.info("Updated Spotify status cache after successful dashboard test")
|
||||
elif service in ['plex', 'jellyfin', 'navidrome', 'soulsync']:
|
||||
_status_cache['media_server']['connected'] = True
|
||||
|
|
@ -5854,7 +5854,7 @@ def spotify_callback():
|
|||
return _spotify_auth_result_page("Your personal Spotify account is now connected. You can close this window.", authenticated=True)
|
||||
if profile_client:
|
||||
profile_client._invalidate_auth_cache()
|
||||
_status_cache_timestamps['spotify'] = 0
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
add_activity_item("", "Spotify Auth Warning", f"Profile {profile_id_from_state} completed OAuth but Spotify did not confirm an authenticated session", "Now")
|
||||
return _spotify_auth_result_page(
|
||||
"Spotify authorization completed, but SoulSync could not confirm an authenticated Spotify session for this profile. You can close this window and try Authenticate again.",
|
||||
|
|
@ -5890,7 +5890,7 @@ def spotify_callback():
|
|||
_clear_rate_limit()
|
||||
spotify_client._invalidate_auth_cache()
|
||||
# Invalidate status cache so next poll picks up the new connection
|
||||
_status_cache_timestamps['spotify'] = 0
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
# Refresh enrichment worker's client so it picks up new auth
|
||||
if spotify_enrichment_worker and hasattr(spotify_enrichment_worker, 'client'):
|
||||
spotify_enrichment_worker.client.reload_config()
|
||||
|
|
@ -5900,7 +5900,7 @@ def spotify_callback():
|
|||
else:
|
||||
logger.warning("Spotify OAuth token exchange succeeded but authentication validation failed")
|
||||
spotify_client._invalidate_auth_cache()
|
||||
_status_cache_timestamps['spotify'] = 0
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
add_activity_item("", "Spotify Auth Warning", "OAuth completed, but Spotify did not confirm an authenticated session", "Now")
|
||||
return _spotify_auth_result_page(
|
||||
"Spotify authorization completed, but SoulSync could not confirm an authenticated Spotify session. You can close this window and try Authenticate again.",
|
||||
|
|
@ -5929,7 +5929,7 @@ def spotify_disconnect():
|
|||
source_label = get_metadata_source_label(active_source)
|
||||
if configured_source == 'spotify':
|
||||
config_manager.set('metadata.fallback_source', active_source)
|
||||
_status_cache['spotify'] = {
|
||||
_status_cache['metadata_source'] = {
|
||||
'connected': False,
|
||||
'authenticated': False,
|
||||
'response_time': 0,
|
||||
|
|
@ -5938,7 +5938,7 @@ def spotify_disconnect():
|
|||
'rate_limit': None,
|
||||
'post_ban_cooldown': None
|
||||
}
|
||||
_status_cache_timestamps['spotify'] = time.time()
|
||||
_status_cache_timestamps['metadata_source'] = time.time()
|
||||
add_activity_item("", "Spotify Disconnected", f"Using {source_label} for metadata", "Now")
|
||||
return jsonify({
|
||||
'success': True,
|
||||
|
|
@ -32073,7 +32073,7 @@ def start_oauth_callback_servers():
|
|||
_clear_rate_limit()
|
||||
spotify_client._invalidate_auth_cache()
|
||||
# Invalidate status cache so next poll picks up the new connection
|
||||
_status_cache_timestamps['spotify'] = 0
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
# Refresh enrichment worker's client so it picks up new auth
|
||||
if spotify_enrichment_worker and hasattr(spotify_enrichment_worker, 'client'):
|
||||
spotify_enrichment_worker.client.reload_config()
|
||||
|
|
@ -32086,7 +32086,7 @@ def start_oauth_callback_servers():
|
|||
else:
|
||||
_oauth_logger.warning("Spotify token exchange succeeded but authentication validation failed")
|
||||
spotify_client._invalidate_auth_cache()
|
||||
_status_cache_timestamps['spotify'] = 0
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
add_activity_item("", "Spotify Auth Warning", "OAuth completed, but Spotify did not confirm an authenticated session", "Now")
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/html')
|
||||
|
|
@ -34053,14 +34053,14 @@ def _build_status_payload():
|
|||
|
||||
# Always include fresh rate limit info (it changes over time as ban expires)
|
||||
# Call is_rate_limited() first to ensure ban-end timestamp is recorded for cooldown
|
||||
spotify_data = dict(_status_cache.get('spotify', {}))
|
||||
metadata_source_data = dict(_status_cache.get('metadata_source', {}))
|
||||
is_rl = spotify_client.is_rate_limited() if spotify_client else False
|
||||
rate_limit_info = spotify_client.get_rate_limit_info() if is_rl else None
|
||||
cooldown_remaining = spotify_client.get_post_ban_cooldown_remaining() if spotify_client else 0
|
||||
spotify_data['rate_limited'] = is_rl
|
||||
spotify_data['rate_limit'] = rate_limit_info
|
||||
metadata_source_data['rate_limited'] = is_rl
|
||||
metadata_source_data['rate_limit'] = rate_limit_info
|
||||
if cooldown_remaining > 0:
|
||||
spotify_data['post_ban_cooldown'] = cooldown_remaining
|
||||
metadata_source_data['post_ban_cooldown'] = cooldown_remaining
|
||||
|
||||
# Count active downloads for nav badge
|
||||
active_dl_count = 0
|
||||
|
|
@ -34073,7 +34073,7 @@ def _build_status_payload():
|
|||
pass
|
||||
|
||||
return {
|
||||
'spotify': spotify_data,
|
||||
'metadata_source': metadata_source_data,
|
||||
'media_server': _status_cache.get('media_server', {}),
|
||||
'soulseek': soulseek_data,
|
||||
'active_media_server': config_manager.get_active_media_server(),
|
||||
|
|
|
|||
|
|
@ -471,24 +471,24 @@ function initializeWebSocket() {
|
|||
|
||||
function handleServiceStatusUpdate(data) {
|
||||
// Cache for library status card
|
||||
_lastServiceStatus = data;
|
||||
_lastStatusPayload = data;
|
||||
|
||||
if (typeof syncSpotifySettingsAuthState === 'function') {
|
||||
syncSpotifySettingsAuthState(data?.spotify || null);
|
||||
syncSpotifySettingsAuthState(data?.metadata_source || null);
|
||||
}
|
||||
if (typeof syncPrimaryMetadataSourceAvailability === 'function') {
|
||||
syncPrimaryMetadataSourceAvailability(data?.spotify || null);
|
||||
syncPrimaryMetadataSourceAvailability(data?.metadata_source || null);
|
||||
}
|
||||
if (typeof sanitizeMetadataSourceSelection === 'function') {
|
||||
sanitizeMetadataSourceSelection({ quiet: true });
|
||||
}
|
||||
|
||||
// Same logic as fetchAndUpdateServiceStatus response handler
|
||||
updateServiceStatus('spotify', data.spotify);
|
||||
updateServiceStatus('spotify', data.metadata_source);
|
||||
updateServiceStatus('media-server', data.media_server);
|
||||
updateServiceStatus('soulseek', data.soulseek);
|
||||
|
||||
updateSidebarServiceStatus('spotify', data.spotify);
|
||||
updateSidebarServiceStatus('spotify', data.metadata_source);
|
||||
updateSidebarServiceStatus('media-server', data.media_server);
|
||||
updateSidebarServiceStatus('soulseek', data.soulseek);
|
||||
|
||||
|
|
@ -514,10 +514,10 @@ function handleServiceStatusUpdate(data) {
|
|||
if (data.enrichment) renderEnrichmentCards(data.enrichment);
|
||||
|
||||
// Spotify rate limit / cooldown / recovery
|
||||
if (data.spotify?.rate_limited && data.spotify.rate_limit) {
|
||||
handleSpotifyRateLimit(data.spotify.rate_limit);
|
||||
if (data.metadata_source?.rate_limited && data.metadata_source.rate_limit) {
|
||||
handleSpotifyRateLimit(data.metadata_source.rate_limit);
|
||||
_spotifyInCooldown = false;
|
||||
} else if (data.spotify?.post_ban_cooldown > 0) {
|
||||
} else if (data.metadata_source?.post_ban_cooldown > 0) {
|
||||
if (_spotifyRateLimitShown && !_spotifyInCooldown) {
|
||||
_spotifyRateLimitShown = false;
|
||||
_spotifyInCooldown = true;
|
||||
|
|
@ -881,12 +881,12 @@ const API = {
|
|||
}
|
||||
};
|
||||
|
||||
// Track last service status for library card (used by websocket handler in core + artists)
|
||||
let _lastServiceStatus = null;
|
||||
// Track the last `/status` payload (shared service snapshot used across the UI)
|
||||
let _lastStatusPayload = null;
|
||||
let _isSoulsyncStandalone = false; // Global flag: true when no media server (sync buttons hidden)
|
||||
|
||||
function getActiveMetadataSource() {
|
||||
return _lastServiceStatus?.spotify?.source || 'spotify';
|
||||
return _lastStatusPayload?.metadata_source?.source || 'spotify';
|
||||
}
|
||||
|
||||
// ===============================
|
||||
|
|
|
|||
|
|
@ -2974,13 +2974,13 @@ async function _checkSetupStatus() {
|
|||
const completion = _getSetupCompletion();
|
||||
const results = { ...completion };
|
||||
|
||||
// ── /status — checks services (spotify, media_server, soulseek) ─────
|
||||
// ── /status — checks metadata_source, media_server, soulseek ────────
|
||||
try {
|
||||
const resp = await fetch('/status');
|
||||
if (resp.ok) {
|
||||
const data = await resp.json();
|
||||
// Metadata source is available when status reports a source.
|
||||
if (data.spotify?.source) {
|
||||
if (data.metadata_source?.source) {
|
||||
results['metadata-source'] = results['metadata-source'] || Date.now();
|
||||
_markSetupComplete('metadata-source');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ function syncMetadataSourceSelection(source) {
|
|||
|
||||
function _isMetadataSourceSelectable(source) {
|
||||
if (source === 'spotify') {
|
||||
return _lastServiceStatus?.spotify?.authenticated === true;
|
||||
return _lastStatusPayload?.metadata_source?.authenticated === true;
|
||||
}
|
||||
if (source === 'discogs') {
|
||||
const token = document.getElementById('discogs-token');
|
||||
|
|
@ -173,7 +173,7 @@ function initializeSettings() {
|
|||
if (discogsTokenInput) {
|
||||
discogsTokenInput.addEventListener('input', () => {
|
||||
if (typeof syncPrimaryMetadataSourceAvailability === 'function') {
|
||||
syncPrimaryMetadataSourceAvailability(_lastServiceStatus?.spotify || null);
|
||||
syncPrimaryMetadataSourceAvailability(_lastStatusPayload?.metadata_source || null);
|
||||
}
|
||||
sanitizeMetadataSourceSelection({ quiet: true });
|
||||
});
|
||||
|
|
@ -207,10 +207,10 @@ function initializeSettings() {
|
|||
// Test button event listeners removed - they use onclick attributes in HTML to avoid double firing
|
||||
|
||||
if (typeof syncPrimaryMetadataSourceAvailability === 'function') {
|
||||
syncPrimaryMetadataSourceAvailability(_lastServiceStatus?.spotify || null);
|
||||
syncPrimaryMetadataSourceAvailability(_lastStatusPayload?.metadata_source || null);
|
||||
}
|
||||
syncSpotifySettingsAuthState(_lastServiceStatus?.spotify || null);
|
||||
syncMetadataSourceSelection(_lastServiceStatus?.spotify?.source);
|
||||
syncSpotifySettingsAuthState(_lastStatusPayload?.metadata_source || null);
|
||||
syncMetadataSourceSelection(_lastStatusPayload?.metadata_source?.source);
|
||||
sanitizeMetadataSourceSelection({ quiet: true });
|
||||
if (metadataSourceSelect) {
|
||||
metadataSourceSelect.dataset.lastValidSource = metadataSourceSelect.value;
|
||||
|
|
@ -408,7 +408,7 @@ async function applyServiceStatusGradients() {
|
|||
else header.appendChild(spinner);
|
||||
}
|
||||
});
|
||||
syncSpotifySettingsAuthState(_lastServiceStatus?.spotify || null);
|
||||
syncSpotifySettingsAuthState(_lastStatusPayload?.metadata_source || null);
|
||||
} catch (e) {
|
||||
console.warn('[Settings Status] Failed to apply gradients:', e);
|
||||
}
|
||||
|
|
@ -2544,7 +2544,7 @@ async function saveSettings(quiet = false) {
|
|||
const discogsTokenInput = document.getElementById('discogs-token');
|
||||
const discogsTokenPresent = !!discogsTokenInput?.value?.trim();
|
||||
let metadataSource = metadataSourceSelect?.value || 'itunes';
|
||||
const spotifySessionActive = _lastServiceStatus?.spotify?.authenticated === true;
|
||||
const spotifySessionActive = _lastStatusPayload?.metadata_source?.authenticated === true;
|
||||
if (metadataSource === 'spotify' && !spotifySessionActive) {
|
||||
metadataSource = 'deezer';
|
||||
if (metadataSourceSelect) metadataSourceSelect.value = metadataSource;
|
||||
|
|
|
|||
|
|
@ -3143,25 +3143,25 @@ async function fetchAndUpdateServiceStatus() {
|
|||
const data = await response.json();
|
||||
|
||||
// Cache for library status card
|
||||
_lastServiceStatus = data;
|
||||
_lastStatusPayload = data;
|
||||
|
||||
if (typeof syncSpotifySettingsAuthState === 'function') {
|
||||
syncSpotifySettingsAuthState(data?.spotify || null);
|
||||
syncSpotifySettingsAuthState(data?.metadata_source || null);
|
||||
}
|
||||
if (typeof syncPrimaryMetadataSourceAvailability === 'function') {
|
||||
syncPrimaryMetadataSourceAvailability(data?.spotify || null);
|
||||
syncPrimaryMetadataSourceAvailability(data?.metadata_source || null);
|
||||
}
|
||||
if (typeof sanitizeMetadataSourceSelection === 'function') {
|
||||
sanitizeMetadataSourceSelection({ quiet: true });
|
||||
}
|
||||
|
||||
// Update service status indicators and text (dashboard)
|
||||
updateServiceStatus('spotify', data.spotify);
|
||||
updateServiceStatus('spotify', data.metadata_source);
|
||||
updateServiceStatus('media-server', data.media_server);
|
||||
updateServiceStatus('soulseek', data.soulseek);
|
||||
|
||||
// Update sidebar service status indicators
|
||||
updateSidebarServiceStatus('spotify', data.spotify);
|
||||
updateSidebarServiceStatus('spotify', data.metadata_source);
|
||||
updateSidebarServiceStatus('media-server', data.media_server);
|
||||
updateSidebarServiceStatus('soulseek', data.soulseek);
|
||||
|
||||
|
|
@ -3185,8 +3185,8 @@ async function fetchAndUpdateServiceStatus() {
|
|||
if (data.enrichment) renderEnrichmentCards(data.enrichment);
|
||||
|
||||
// Check for Spotify rate limit
|
||||
if (data.spotify && data.spotify.rate_limited && data.spotify.rate_limit) {
|
||||
handleSpotifyRateLimit(data.spotify.rate_limit);
|
||||
if (data.metadata_source && data.metadata_source.rate_limited && data.metadata_source.rate_limit) {
|
||||
handleSpotifyRateLimit(data.metadata_source.rate_limit);
|
||||
} else if (_spotifyRateLimitShown) {
|
||||
handleSpotifyRateLimit(null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6558,8 +6558,8 @@ function updateLibraryStatusCard(dbStats) {
|
|||
const isScanning = window._libraryStatusScanning || false;
|
||||
|
||||
// Determine state
|
||||
const serverConnected = _lastServiceStatus && _lastServiceStatus.media_server && _lastServiceStatus.media_server.connected;
|
||||
const serverType = _lastServiceStatus && _lastServiceStatus.active_media_server;
|
||||
const serverConnected = _lastStatusPayload && _lastStatusPayload.media_server && _lastStatusPayload.media_server.connected;
|
||||
const serverType = _lastStatusPayload && _lastStatusPayload.active_media_server;
|
||||
const hasData = tracks > 0;
|
||||
const hasServer = !!serverType && serverType !== 'none';
|
||||
|
||||
|
|
@ -6668,7 +6668,7 @@ function updateLibraryStatusCard(dbStats) {
|
|||
}
|
||||
}
|
||||
|
||||
// _lastServiceStatus and _isSoulsyncStandalone are declared in core.js
|
||||
// _lastStatusPayload and _isSoulsyncStandalone are declared in core.js
|
||||
const _origFetchServiceStatus = typeof fetchAndUpdateServiceStatus === 'function' ? fetchAndUpdateServiceStatus : null;
|
||||
|
||||
function _capitalize(s) { return s ? s.charAt(0).toUpperCase() + s.slice(1) : ''; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue