soulsync/core/downloads
BoulderBadgeDad 2824c25ec6 Album bundle: let Soulseek staging-misses fall through to per-track/cross-source fallback (#743)
A Soulseek album bundle stages whichever single folder scored best. If that
folder doesn't contain every track the album needs, the missing tracks were
marked not_found with no fallback — even in hybrid mode where later sources
(Deezer, YouTube, etc.) could fill them. The staging-miss short-circuit fired
for Soulseek because 'soulseek' was lumped into the torrent/usenet source set
when album bundles were added, and album_bundle_partial only reflects whether
the files found IN the folder downloaded, not whether the folder had every
needed track.

Drop 'soulseek' from the short-circuit (keep torrent/usenet). A track not
claimed from the staged Soulseek folder now falls through to the normal
per-track Soulseek search and, in hybrid mode, onward down the configured
chain. Unlike torrent/usenet — where per-track search re-adds the same
release — Soulseek per-track search is a genuine per-file network search, so
this is correct and cheap. Realizes the original author's stated intent
('keep partial bundles from blocking per-track fallback') robustly, since the
partial flag couldn't detect a folder that was simply missing tracks.

Only affects tracks NOT claimed from staging — fully-staged albums claim every
track via try_staging_match and never reach this gate, so working albums are
unchanged. Likely also mitigates #755 (all-album-import failures now fall
through to per-track instead of dying).

Tests: rewrote the two Soulseek staged-miss tests to assert fall-through
(single + hybrid-first); kept the torrent guard; added a usenet guard test.
2026-05-31 11:13:08 -07: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 Fix: Usenet bundle stuck at 99%/100% — SAB reports post-processing in History as non-terminal (#721) 2026-05-29 00:49:02 -04:00
cancel.py diag: log every cancel_download caller with a trigger label 2026-05-19 22:31:29 -07:00
candidates.py Wishlist: harden Spotify backfill — poisoned tn=1 can't mask lean album 2026-05-27 16:47:26 -07: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: Soulseek album-bundle downloads stuck on "failed" after slskd 2026-05-27 21:20:37 -07:00
history.py PR4a: lift sync history recording to core/downloads/history.py 2026-04-27 20:37:16 -07:00
lifecycle.py Album-bundle staging: clean Soulseek copies + sweep orphans at startup 2026-05-27 22:18:42 -07:00
master.py Harden album bundle fallback flow 2026-05-24 16:15:36 -07:00
monitor.py Fix: Usenet bundle stuck at 99%/100% — SAB reports post-processing in History as non-terminal (#721) 2026-05-29 00:49:02 -04: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: Usenet bundle stuck at 99%/100% — SAB reports post-processing in History as non-terminal (#721) 2026-05-29 00:49:02 -04:00
task_worker.py Album bundle: let Soulseek staging-misses fall through to per-track/cross-source fallback (#743) 2026-05-31 11:13:08 -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