Reject junk artist Soulseek results and cancel downloads on wishlist clear

Soulseek results from "Various Artists", "VA", "Unknown Artist", and
"Unknown Album" folders are now rejected before scoring. These
compilation folders rarely contain properly tagged files for the target
artist.

Clearing the wishlist now also cancels any active wishlist download
batch and resets the auto-processing flag, so downloads don't keep
running after the source tracks are removed.
This commit is contained in:
Broque Thomas 2026-04-17 12:24:50 -07:00
parent 9898bd1190
commit 04b8c02ea9
3 changed files with 43 additions and 3 deletions

View file

@ -687,6 +687,20 @@ class MusicMatchingEngine:
title_words = spotify_cleaned_title.split()
is_short_title = len(spotify_cleaned_title) <= 5 or len(title_words) == 1
# --- Junk Artist Gate ---
# Reject results from generic/compilation folders where metadata is unreliable.
# These folders almost never contain properly tagged files for the target artist.
_JUNK_ARTISTS = {'various artists', 'va', 'unknown artist', 'unknown album',
'various artist'}
if not is_youtube:
for seg_norm in _artist_segments_norm:
if seg_norm in _JUNK_ARTISTS:
logger.debug(
f"Junk artist reject: '{spotify_track.name}' — path segment "
f"'{seg_norm}' in '{slskd_track.filename[:80]}'"
)
return 0.0
# --- Minimum Title Gate ---
# Reject matches where the title has almost no resemblance to the target.
# Without this, artist + album bonus alone can push completely wrong tracks

View file

@ -22314,6 +22314,8 @@ def get_version_info():
"• Fix slskd timeout spam — dashboard and download status skip slskd polling when Soulseek is not active or disconnected",
"• Fix Soulseek search queries missing album name — reduces wrong-artist downloads",
"• Downloads batch panel — color-coded batch cards with progress, cancel, expand, and 7-day history",
"• Reject Soulseek results from Various Artists/VA/Unknown Artist folders",
"• Clearing wishlist now cancels the active wishlist download batch",
],
},
{
@ -24931,17 +24933,39 @@ def start_wishlist_missing_downloads():
@app.route('/api/wishlist/clear', methods=['POST'])
def clear_wishlist():
"""Endpoint to clear all tracks from the wishlist."""
"""Endpoint to clear all tracks from the wishlist.
Also cancels any active wishlist download batch so cleared tracks don't keep downloading."""
try:
from core.wishlist_service import get_wishlist_service
wishlist_service = get_wishlist_service()
success = wishlist_service.clear_wishlist(profile_id=get_current_profile_id())
if success:
return jsonify({"success": True, "message": "Wishlist cleared successfully"})
# Cancel any active wishlist download batch
cancelled_count = 0
with tasks_lock:
for batch_id, batch_data in download_batches.items():
if batch_data.get('playlist_id') == 'wishlist' and batch_data.get('phase') not in ('complete', 'error', 'cancelled'):
batch_data['phase'] = 'cancelled'
for task_id in batch_data.get('queue', []):
if task_id in download_tasks and download_tasks[task_id]['status'] not in ('completed', 'failed', 'not_found', 'cancelled'):
download_tasks[task_id]['status'] = 'cancelled'
cancelled_count += 1
# Reset wishlist auto-processing flag
global wishlist_auto_processing, wishlist_auto_processing_timestamp
with wishlist_timer_lock:
wishlist_auto_processing = False
wishlist_auto_processing_timestamp = 0
if cancelled_count > 0:
print(f"[Wishlist Clear] Cancelled {cancelled_count} active wishlist downloads")
add_activity_item("", "Wishlist Cleared", f"Wishlist cleared and {cancelled_count} downloads cancelled", "Now")
return jsonify({"success": True, "message": "Wishlist cleared successfully", "cancelled_downloads": cancelled_count})
else:
return jsonify({"success": False, "error": "Failed to clear wishlist"}), 500
except Exception as e:
print(f"Error clearing wishlist: {e}")
return jsonify({"success": False, "error": str(e)}), 500

View file

@ -3614,6 +3614,8 @@ const WHATS_NEW = {
{ title: 'Fix Wishlist Album Remove', desc: 'Removing albums from the Wishlist Nebula now works — API accepts album_name as fallback when album_id is unavailable' },
{ title: 'Fix Soulseek Timeout Spam', desc: 'Dashboard stats and download status endpoints no longer poll slskd when Soulseek is not the active download source or is known to be disconnected. Eliminates connection timeout errors every 10 seconds for users who have a slskd URL configured but use YouTube/Tidal/etc.' },
{ title: 'Fix Soulseek Search Missing Album Name', desc: 'Soulseek search queries now include the album name (Artist + Album + Track) as the first search attempt for all download sources. Previously this was excluded for Soulseek-only mode, causing wrong-artist downloads when an artist name matched an album folder in another user\'s library' },
{ title: 'Reject Junk Artist Soulseek Results', desc: 'Soulseek search results from "Various Artists", "VA", "Unknown Artist", and "Unknown Album" folders are now automatically rejected. These compilation/junk folders almost never contain properly tagged files for the target artist' },
{ title: 'Clear Wishlist Cancels Downloads', desc: 'Clearing the wishlist now also cancels any active wishlist download batch. Previously the download queue would keep running after the wishlist was cleared' },
{ title: 'Downloads Batch Panel', desc: 'Downloads page now shows a batch context panel on the right side. Each active batch (wishlist, sync, album download) gets a color-coded card with progress, cancel button, and expandable track list. Color indicators on download rows link them to their batch. Completed batch history shows the last 7 days', page: 'active-downloads' },
// --- April 15, 2026 ---