#798: fix Spotify Free not selectable — WebSocket status push missing flags
The Settings dropdown reverted 'Spotify Free' because _isMetadataSourceSelectable reads _lastStatusPayload.spotify.free_installed, but that payload comes from the WebSocket status:update push (_build_status_payload) — which sent the raw spotify dict. The availability flags were only added to the GET /status endpoint, so the frontend never saw free_installed and bounced the selection. Extract _spotify_status_with_availability() (metadata_available + free_installed) and use it in BOTH _build_status_payload (WebSocket) and get_status (HTTP poll), so they can't drift. Now 'Spotify Free' is selectable when SpotipyFree is installed.
This commit is contained in:
parent
217a5eda70
commit
0c03803a30
1 changed files with 22 additions and 20 deletions
|
|
@ -2318,27 +2318,9 @@ def get_status():
|
||||||
if t.get('status') in ('downloading', 'searching', 'post_processing', 'queued', 'pending'):
|
if t.get('status') in ('downloading', 'searching', 'post_processing', 'queued', 'pending'):
|
||||||
active_dl_count += 1
|
active_dl_count += 1
|
||||||
|
|
||||||
# Spotify Free: tell the UI (a) whether Spotify metadata is currently
|
|
||||||
# available (auth or free), and (b) whether the SpotipyFree package is
|
|
||||||
# installed — the latter is what makes 'Spotify Free' selectable in the
|
|
||||||
# source dropdown (selecting it is the opt-in, so it can't depend on
|
|
||||||
# already having selected it).
|
|
||||||
spotify_status = dict(metadata_status['spotify'])
|
|
||||||
try:
|
|
||||||
spotify_status['metadata_available'] = bool(
|
|
||||||
spotify_client and spotify_client.is_spotify_metadata_available()
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
spotify_status['metadata_available'] = bool(spotify_status.get('authenticated'))
|
|
||||||
try:
|
|
||||||
from core.spotify_free_metadata import spotify_free_installed
|
|
||||||
spotify_status['free_installed'] = spotify_free_installed()
|
|
||||||
except Exception:
|
|
||||||
spotify_status['free_installed'] = False
|
|
||||||
|
|
||||||
status_data = {
|
status_data = {
|
||||||
'metadata_source': metadata_status['metadata_source'],
|
'metadata_source': metadata_status['metadata_source'],
|
||||||
'spotify': spotify_status,
|
'spotify': _spotify_status_with_availability(metadata_status['spotify']),
|
||||||
'media_server': _status_cache['media_server'],
|
'media_server': _status_cache['media_server'],
|
||||||
'soulseek': soulseek_data,
|
'soulseek': soulseek_data,
|
||||||
'active_media_server': active_server,
|
'active_media_server': active_server,
|
||||||
|
|
@ -34451,6 +34433,26 @@ def import_staging_suggestions():
|
||||||
# WEBSOCKET (SOCKET.IO) EVENT HANDLERS AND BACKGROUND EMITTERS
|
# WEBSOCKET (SOCKET.IO) EVENT HANDLERS AND BACKGROUND EMITTERS
|
||||||
# ================================================================================================
|
# ================================================================================================
|
||||||
|
|
||||||
|
def _spotify_status_with_availability(spotify_status):
|
||||||
|
"""Augment the spotify status dict with the Spotify-Free availability flags
|
||||||
|
the UI needs: ``metadata_available`` (search picker) and ``free_installed``
|
||||||
|
(Settings source selector — 'Spotify Free' is selectable when the package is
|
||||||
|
installed, since selecting it is the opt-in). Used by BOTH the /status
|
||||||
|
endpoint and the WebSocket status push so they never drift."""
|
||||||
|
out = dict(spotify_status or {})
|
||||||
|
try:
|
||||||
|
out['metadata_available'] = bool(
|
||||||
|
spotify_client and spotify_client.is_spotify_metadata_available())
|
||||||
|
except Exception:
|
||||||
|
out['metadata_available'] = bool(out.get('authenticated'))
|
||||||
|
try:
|
||||||
|
from core.spotify_free_metadata import spotify_free_installed
|
||||||
|
out['free_installed'] = spotify_free_installed()
|
||||||
|
except Exception:
|
||||||
|
out['free_installed'] = False
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
def _build_status_payload():
|
def _build_status_payload():
|
||||||
"""Build the same status payload used by GET /status, reading from the cache."""
|
"""Build the same status payload used by GET /status, reading from the cache."""
|
||||||
download_mode = config_manager.get('download_source.mode', 'hybrid')
|
download_mode = config_manager.get('download_source.mode', 'hybrid')
|
||||||
|
|
@ -34470,7 +34472,7 @@ def _build_status_payload():
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'metadata_source': metadata_status['metadata_source'],
|
'metadata_source': metadata_status['metadata_source'],
|
||||||
'spotify': metadata_status['spotify'],
|
'spotify': _spotify_status_with_availability(metadata_status['spotify']),
|
||||||
'media_server': _status_cache.get('media_server', {}),
|
'media_server': _status_cache.get('media_server', {}),
|
||||||
'soulseek': soulseek_data,
|
'soulseek': soulseek_data,
|
||||||
'active_media_server': config_manager.get_active_media_server(),
|
'active_media_server': config_manager.get_active_media_server(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue