soulsync/core/imports
BoulderBadgeDad 3c15041b88 Fix #764: manual import reported quarantined files as a successful "Done"
The manual-import routes (album + singles) call post_process_matched_download
directly. When the pipeline quarantines a file — integrity / AcoustID / FLAC
bit-depth — or hits the race guard, it sets a context flag and RETURNS
NORMALLY (it only marks the task failed + notifies when there's a task_id,
which manual imports don't have). So the inner pipeline raised no exception,
and routes.py counted `processed += 1` for a file that had just been moved to
ss_quarantine, not the library. Result: the UI shows a green "Done" while the
track silently vanished — exactly the #764 report (Coldplay - Yellow.flac ->
ss_quarantine, but "Done").

The download path already handles this in
post_process_matched_download_with_verification (it reads the same flags and
marks the task failed); only the manual-import routes were missing the check.

Fix: new pure helper import_rejection_reason(context) returns a human-readable
reason for any terminal rejection (_integrity_failure_msg / _acoustid_quarantined
/ _bitdepth_rejected / _race_guard_failed) or None for a clean import. Both
manual-import routes now consult it: album_process reports the track in
`errors` instead of counting it processed; process_single_import_file returns
("error", reason) instead of ("ok", ...). Verified every move_to_quarantine
call site (4, all in pipeline.py) sets one of those flags, so no quarantine
path slips through. This also delivers the "direct display of the error" the
reporter asked for — the reason now surfaces in the response `errors` list.

Does NOT address the reverse symptom ("failed even though it moved correctly")
— not yet root-caused — nor the separate bit-depth hole on the download-path
wrapper.

Tests: tests/imports/test_import_rejection_reason.py (10) — each trigger
detected, falsy flags ignored, deterministic ordering, plus two route-level
tests driving the REAL process_single_import_file (quarantine -> "error";
clean -> "ok").
2026-06-02 08:40:26 -07:00
..
__init__.py Rehome import helpers into core/imports 2026-04-27 19:54:44 +03:00
album.py Show MusicBrainz release variants in import 2026-05-24 09:33:19 -07:00
album_matching.py Auto-import matching: fix Deezer source classification + bump tolerance 2026-05-09 15:53:17 -07:00
album_naming.py Rehome import helpers into core/imports 2026-04-27 19:54:44 +03:00
context.py Wishlist payloads: preserve real track_number + release_date end-to-end 2026-05-27 14:25:03 -07:00
file_integrity.py Integrity check: don't quarantine valid streamed FLAC as 'zero-length' (#756) 2026-05-31 11:28:40 -07:00
file_ops.py Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
filename.py Fix album-bundle downloads landing every track as track 1 2026-05-26 21:04:27 -07:00
guards.py Quarantine management — list, approve, delete, recover 2026-05-14 08:06:19 -07:00
paths.py Path builder: validate $year, never blind-slice release_date (#745) 2026-05-30 00:31:14 -07:00
pipeline.py Fix #764: manual import reported quarantined files as a successful "Done" 2026-06-02 08:40:26 -07:00
quarantine.py Quarantine: manage a quarantined file from the download modal (Listen / Accept / Search) 2026-05-31 15:41:04 -07:00
resolution.py Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
routes.py Fix #764: manual import reported quarantined files as a successful "Done" 2026-06-02 08:40:26 -07:00
side_effects.py Add torrent and usenet release staging support 2026-05-21 14:22:21 -07:00
staging.py Fix album-bundle downloads landing every track as track 1 2026-05-26 21:04:27 -07:00
track_number.py Wishlist: fix three regressions causing all imports to land as track 01 with no year 2026-05-27 15:39:22 -07:00