soulsync/core/downloads
dev e594ac9799 fix(downloads): keep terminal tasks visible during active batch + concurrent pool
Three fixes from on-device testing of best-quality mode:

1. clear_completed_local no longer prunes terminal tasks that belong to a
   STILL-ACTIVE batch (one with non-terminal work remaining). The 5-min
   "Clean Completed Downloads" automation was yanking completed/failed/
   unverified rows out of download_tasks mid-run — and failed/cancelled
   aren't in library_history — so they only reappeared after the batch
   ended. Now the whole active batch stays intact until it finishes.

2. search_all_sources runs every source CONCURRENTLY (asyncio.gather)
   instead of sequentially, so the pool waits only for the slowest source
   (e.g. usenet/Prowlarr) in parallel rather than summing all latencies.

3. The pool log now reports per-source contribution counts
   (e.g. "usenet=0, hifi=11, soulseek=1") instead of just echoing the
   chain, so a release-level source that returns nothing for a track-title
   query is visible rather than appearing to have been searched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:08:56 +02:00
..
__init__.py PR4a: lift sync history recording to core/downloads/history.py 2026-04-27 20:37:16 -07:00
album_bundle_dispatch.py Album bundle: fall back to per-track on an I/O error, don't hard-fail the batch 2026-06-01 13:29:05 -07:00
cancel.py fix(downloads): keep terminal tasks visible during active batch + concurrent pool 2026-06-14 20:08:56 +02:00
candidates.py feat(downloads): best-quality search mode + clearer fallback UI 2026-06-14 18:46:01 +02:00
cleanup.py PR4c: lift _automatic_wishlist_cleanup_after_db_update to core/downloads/cleanup.py 2026-04-27 22:23:41 -07:00
file_finder.py Fix: a '/' in a song title was treated as a path separator (#835) 2026-06-10 16:29:09 -07:00
history.py PR4a: lift sync history recording to core/downloads/history.py 2026-04-27 20:37:16 -07:00
lifecycle.py Playlists: reconcile rebuilds touched playlists from the LIBRARY, not task fields 2026-06-12 17:08:27 -07:00
master.py Playlists: all-owned trigger makes batch dict authoritative + logs when nothing rebuilt 2026-06-12 17:34:06 -07:00
monitor.py feat(quality): derive per-source download tier from the global profile 2026-06-14 13:18:01 +02:00
origin.py Download Origins: see (and delete) exactly what watchlist + playlist syncs downloaded 2026-06-07 00:15:31 -07:00
playlist_folder.py Fix #780: Deezer/non-Spotify organize-by-playlist resolved the wrong row 2026-06-03 20:41:04 -07:00
post_processing.py Add torrent and usenet release staging support 2026-05-21 14:22:21 -07:00
staging.py Staging match: log rejection reason on every silent-False exit 2026-05-27 14:12:55 -07:00
status.py fix(downloads): unverified review actions always load + show real quality on completed 2026-06-14 17:11:17 +02:00
task_worker.py feat(downloads): best-quality search mode + clearer fallback UI 2026-06-14 18:46:01 +02:00
track_detail.py Downloads: add per-track detail endpoint for the track-detail modal 2026-05-31 20:18:35 -07:00
track_link.py Manual download search: paste a Tidal/Qobuz track link to grab the exact version (#813) 2026-06-08 15:03:54 -07:00
track_metadata_backfill.py Wishlist: harden Spotify backfill — poisoned tn=1 can't mask lean album 2026-05-27 16:47:26 -07:00
validation.py Add torrent and usenet release staging support 2026-05-21 14:22:21 -07:00
wishlist_aggregator.py Wishlist modal: surface most-advanced live phase, not least-complete 2026-05-26 22:35:53 -07:00
wishlist_failed.py Fix album-bundle staging match + wishlist provenance (#700, #698) 2026-05-26 07:12:49 -07:00