@ -17136,182 +17136,6 @@ def _execute_retag(group_id, album_id):
" phase " : " Error " ,
" error_message " : str ( e )
} )
def _check_and_remove_from_wishlist ( context ) :
"""
Check if a successfully downloaded track should be removed from wishlist .
Extracts Spotify track data from download context and removes from wishlist if found .
"""
try :
from core . wishlist_service import get_wishlist_service
from core . imports . context import get_import_source , get_import_source_ids
wishlist_service = get_wishlist_service ( )
# Try to extract a source-aware track ID from the context
spotify_track_id = None
# Populated lazily by Method 3 or Method 4. Initialized here so Method 4's
# `if not wishlist_tracks` guard doesn't UnboundLocalError when Methods 1/2
# found nothing and Method 3 never ran (no wishlist_id in track_info).
wishlist_tracks = [ ]
# Method 1: Source-specific track lookup from track_info / source_ids
track_info = context . get ( ' track_info ' , { } )
source = get_import_source ( context )
source_ids = get_import_source_ids ( context )
source_label = {
' spotify ' : ' Spotify ' ,
' itunes ' : ' iTunes ' ,
' deezer ' : ' Deezer ' ,
' discogs ' : ' Discogs ' ,
' hydrabase ' : ' Hydrabase ' ,
} . get ( source , ' Source ' )
if source == ' spotify ' and source_ids . get ( ' track_id ' ) :
spotify_track_id = source_ids [ ' track_id ' ]
logger . info ( f " [Wishlist] Found { source_label } track ID from source_ids: { spotify_track_id } " )
# Method 2: Fallback to the original search result for source-specific IDs
elif source == ' spotify ' and context . get ( ' original_search_result ' , { } ) . get ( ' id ' ) :
spotify_track_id = context [ ' original_search_result ' ] [ ' id ' ]
logger . info ( f " [Wishlist] Found { source_label } track ID from original_search_result: { spotify_track_id } " )
# Method 3: Check if this is a wishlist download (context has wishlist_id)
elif ' wishlist_id ' in track_info :
wishlist_id = track_info [ ' wishlist_id ' ]
logger . info ( f " [Wishlist] Found wishlist_id in context: { wishlist_id } " )
# Get the track ID from the wishlist entry (search all profiles)
database = get_database ( )
all_profiles = database . get_all_profiles ( )
wishlist_tracks = [ ]
for p in all_profiles :
wishlist_tracks . extend ( wishlist_service . get_wishlist_tracks_for_download ( profile_id = p [ ' id ' ] ) )
for wl_track in wishlist_tracks :
if wl_track . get ( ' wishlist_id ' ) == wishlist_id :
spotify_track_id = wl_track . get ( ' spotify_track_id ' ) or wl_track . get ( ' id ' )
logger . info ( f " [Wishlist] Found track ID from wishlist entry: { spotify_track_id } " )
break
# Method 4: Try to construct a track ID from metadata for fuzzy matching
if not spotify_track_id :
track_name = track_info . get ( ' name ' ) or context . get ( ' original_search_result ' , { } ) . get ( ' title ' , ' ' )
artist_name = _get_track_artist_name ( track_info ) or _get_track_artist_name ( context . get ( ' original_search_result ' , { } ) )
if track_name and artist_name :
logger . warning ( f " [Wishlist] No track ID found, checking for fuzzy match: ' { track_name } ' by ' { artist_name } ' " )
# Get all wishlist tracks and find potential matches (search all profiles)
if not wishlist_tracks :
database = get_database ( )
all_profiles = database . get_all_profiles ( )
wishlist_tracks = [ ]
for p in all_profiles :
wishlist_tracks . extend ( wishlist_service . get_wishlist_tracks_for_download ( profile_id = p [ ' id ' ] ) )
for wl_track in wishlist_tracks :
wl_name = wl_track . get ( ' name ' , ' ' ) . lower ( )
wl_artists = wl_track . get ( ' artists ' , [ ] )
wl_artist_name = ' '
# Extract artist name from wishlist track
if wl_artists :
if isinstance ( wl_artists [ 0 ] , dict ) :
wl_artist_name = wl_artists [ 0 ] . get ( ' name ' , ' ' ) . lower ( )
else :
wl_artist_name = str ( wl_artists [ 0 ] ) . lower ( )
# Simple fuzzy matching
if ( wl_name == track_name . lower ( ) and wl_artist_name == artist_name . lower ( ) ) :
spotify_track_id = wl_track . get ( ' spotify_track_id ' ) or wl_track . get ( ' id ' )
logger . info ( f " [Wishlist] Found fuzzy match - track ID: { spotify_track_id } " )
break
# If we found a track ID, remove it from wishlist
if spotify_track_id :
logger . info ( f " [Wishlist] Attempting to remove track from wishlist: { spotify_track_id } " )
removed = wishlist_service . mark_track_download_result ( spotify_track_id , success = True )
if removed :
logger . info ( f " [Wishlist] Successfully removed track from wishlist: { spotify_track_id } " )
else :
logger . warning ( f " ℹ ️ [Wishlist] Track not found in wishlist or already removed: { spotify_track_id } " )
else :
logger . warning ( " ℹ ️ [Wishlist] No track ID found for wishlist removal check" )
except Exception as e :
logger . error ( f " [Wishlist] Error in wishlist removal check: { e } " )
import traceback
traceback . print_exc ( )
def _check_and_remove_track_from_wishlist_by_metadata ( track_data ) :
"""
Check if a track found during database analysis should be removed from wishlist .
Uses track metadata ( name , artists , id ) to find and remove from wishlist .
"""
try :
from core . wishlist_service import get_wishlist_service
wishlist_service = get_wishlist_service ( )
# Extract track info
track_name = track_data . get ( ' name ' , ' ' )
track_id = track_data . get ( ' id ' , ' ' )
artists = track_data . get ( ' artists ' , [ ] )
logger . info ( f " [Analysis] Checking if track should be removed from wishlist: ' { track_name } ' (ID: { track_id } ) " )
# Method 1: Direct Spotify ID match
if track_id :
removed = wishlist_service . mark_track_download_result ( track_id , success = True )
if removed :
logger . info ( f " [Analysis] Removed track from wishlist via direct ID match: { track_id } " )
return True
# Method 2: Fuzzy matching by name and artist if no direct ID match
if track_name and artists :
# Extract primary artist name
primary_artist = ' '
if isinstance ( artists [ 0 ] , dict ) and ' name ' in artists [ 0 ] :
primary_artist = artists [ 0 ] [ ' name ' ]
elif isinstance ( artists [ 0 ] , str ) :
primary_artist = artists [ 0 ]
else :
primary_artist = str ( artists [ 0 ] )
logger . warning ( f " [Analysis] No direct ID match, trying fuzzy match: ' { track_name } ' by ' { primary_artist } ' " )
# Get all wishlist tracks and find matches (search all profiles)
database = get_database ( )
all_profiles = database . get_all_profiles ( )
wishlist_tracks = [ ]
for p in all_profiles :
wishlist_tracks . extend ( wishlist_service . get_wishlist_tracks_for_download ( profile_id = p [ ' id ' ] ) )
for wl_track in wishlist_tracks :
wl_name = wl_track . get ( ' name ' , ' ' ) . lower ( )
wl_artists = wl_track . get ( ' artists ' , [ ] )
wl_artist_name = ' '
# Extract artist name from wishlist track
if wl_artists :
if isinstance ( wl_artists [ 0 ] , dict ) :
wl_artist_name = wl_artists [ 0 ] . get ( ' name ' , ' ' ) . lower ( )
else :
wl_artist_name = str ( wl_artists [ 0 ] ) . lower ( )
# Fuzzy matching - normalize strings for comparison
if ( wl_name == track_name . lower ( ) and wl_artist_name == primary_artist . lower ( ) ) :
spotify_track_id = wl_track . get ( ' spotify_track_id ' ) or wl_track . get ( ' id ' )
if spotify_track_id :
removed = wishlist_service . mark_track_download_result ( spotify_track_id , success = True )
if removed :
logger . info ( f " [Analysis] Removed track from wishlist via fuzzy match: { spotify_track_id } " )
return True
logger . warning ( f " ℹ ️ [Analysis] Track not found in wishlist or already removed: ' { track_name } ' " )
return False
except Exception as e :
logger . error ( f " [Analysis] Error checking wishlist removal by metadata: { e } " )
import traceback
traceback . print_exc ( )
return False
def _automatic_wishlist_cleanup_after_db_update ( ) :
""" Automatic wishlist cleanup that runs after database updates. """
return _cleanup_wishlist_after_db_update ( logger = logger )