Rename wishlist lifecycle helper

- Switch the download lifecycle over to the neutral wishlist track helper name
- Keep the old Spotify helper as a compatibility alias for older callers
- Store track_data as the primary failed-download wishlist payload key and add regression coverage
pull/435/head
Antti Kettunen 3 weeks ago
parent b1a9c1b458
commit fd30d2a0be
No known key found for this signature in database
GPG Key ID: C6B2A3D250359BD7

@ -57,7 +57,6 @@ class LifecycleDeps:
submit_failed_to_wishlist_with_auto_completion: Callable[[str], None] # async — submits to executor
process_failed_to_wishlist: Callable[[str], None] # sync — direct call (used by v2 path)
process_failed_to_wishlist_with_auto_completion: Callable[[str], None] # sync — direct call (used by v2 path)
ensure_spotify_track_format: Callable
get_track_artist_name: Callable
check_and_remove_from_wishlist: Callable
regenerate_batch_m3u: Callable
@ -65,6 +64,17 @@ class LifecycleDeps:
tidal_discovery_states: dict
deezer_discovery_states: dict
spotify_public_discovery_states: dict
ensure_wishlist_track_format: Callable | None = None
ensure_spotify_track_format: Callable | None = None
def __post_init__(self) -> None:
if self.ensure_wishlist_track_format is None:
self.ensure_wishlist_track_format = self.ensure_spotify_track_format
if self.ensure_spotify_track_format is None:
self.ensure_spotify_track_format = self.ensure_wishlist_track_format
if self.ensure_wishlist_track_format is None:
raise ValueError("LifecycleDeps requires a wishlist track format helper")
# ---------------------------------------------------------------------------
@ -188,8 +198,8 @@ def on_download_completed(batch_id: str, task_id: str, success: bool, deps: Life
# Build track_info structure matching sync.py's permanently_failed_tracks format
original_track_info = task.get('track_info', {})
# Ensure spotify_track has proper structure for wishlist service
spotify_track_data = deps.ensure_spotify_track_format(original_track_info)
# Ensure wishlist track has proper structure for wishlist service
wishlist_track_data = deps.ensure_wishlist_track_format(original_track_info)
track_info = {
'download_index': task.get('track_index', 0),
@ -197,7 +207,8 @@ def on_download_completed(batch_id: str, task_id: str, success: bool, deps: Life
'track_name': original_track_info.get('name', 'Unknown Track'),
'artist_name': deps.get_track_artist_name(original_track_info),
'retry_count': task.get('retry_count', 0),
'spotify_track': spotify_track_data, # Properly formatted spotify track for wishlist
'track_data': wishlist_track_data,
'spotify_track': wishlist_track_data, # Backward-compatible alias for older callers
'failure_reason': 'Download cancelled' if task_status == 'cancelled' else ('No matching track found' if task_status == 'not_found' else 'Download failed'),
'candidates': task.get('cached_candidates', []), # Include search results if available
}

@ -100,7 +100,7 @@ def _build_deps(
submit_failed_to_wishlist_with_auto_completion=submit_failed_auto or rec('submit_failed_auto'),
process_failed_to_wishlist=process_failed or rec('process_failed'),
process_failed_to_wishlist_with_auto_completion=process_failed_auto or rec('process_failed_auto'),
ensure_spotify_track_format=lambda track: track,
ensure_wishlist_track_format=lambda track: track,
get_track_artist_name=lambda track: 'Artist',
check_and_remove_from_wishlist=rec('check_wishlist'),
regenerate_batch_m3u=rec('regen_m3u'),
@ -258,6 +258,8 @@ def test_on_complete_failed_task_appended_to_permanently_failed_tracks():
lc.on_download_completed('b1', 't1', False, deps)
assert len(download_batches['b1']['permanently_failed_tracks']) == 1
assert download_batches['b1']['permanently_failed_tracks'][0]['track_name'] == 'Money'
assert download_batches['b1']['permanently_failed_tracks'][0]['track_data'] == {'name': 'Money'}
assert download_batches['b1']['permanently_failed_tracks'][0]['spotify_track'] == {'name': 'Money'}
def test_on_complete_cancelled_task_added_to_cancelled_tracks():

@ -113,7 +113,7 @@ from core.imports.context import (
from core.wishlist.payloads import (
build_cancelled_task_wishlist_payload as _build_cancelled_task_wishlist_payload,
build_failed_track_wishlist_context as _build_failed_track_wishlist_context,
ensure_spotify_track_format as _ensure_spotify_track_format,
ensure_wishlist_track_format as _ensure_wishlist_track_format,
get_track_artist_name as _get_track_artist_name,
)
from core.wishlist.routes import (
@ -17912,7 +17912,7 @@ def _build_lifecycle_deps():
),
process_failed_to_wishlist=_process_failed_tracks_to_wishlist_exact,
process_failed_to_wishlist_with_auto_completion=_process_failed_tracks_to_wishlist_exact_with_auto_completion,
ensure_spotify_track_format=_ensure_spotify_track_format,
ensure_wishlist_track_format=_ensure_wishlist_track_format,
get_track_artist_name=_get_track_artist_name,
check_and_remove_from_wishlist=_check_and_remove_from_wishlist,
regenerate_batch_m3u=_regenerate_batch_m3u,
@ -18008,9 +18008,9 @@ def _process_failed_tracks_to_wishlist_exact(batch_id):
# Skip wing-it fallback tracks — they had no real metadata match,
# so adding them to wishlist would just retry with the same raw data.
# Check the track ID prefix since _ensure_spotify_track_format overwrites source.
sp_track = failed_track_info.get('spotify_track', {})
sp_id = sp_track.get('id', '') if isinstance(sp_track, dict) else ''
# Check the track ID prefix since the wishlist payload helper overwrites source.
track_data = failed_track_info.get('track_data') or failed_track_info.get('spotify_track', {})
sp_id = track_data.get('id', '') if isinstance(track_data, dict) else ''
if str(sp_id).startswith('wing_it_'):
wing_it_skipped += 1
logger.info(f"[Wishlist Processing] Skipping wing-it track: {track_name}")

Loading…
Cancel
Save