fix(verification): persist status on ALL pipeline success exits + history backfill
The pipeline has three success exits (simple download, playlist folder mode, main) but only the main one persisted the verification status — force-imported playlist tracks got no tag, no history status, and never appeared in the Unverified filter. Extracted _persist_verification_status() and call it at every exit. One-time idempotent backfill derives status for existing history rows from their recorded acoustid_result (pass->verified, skip->unverified). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
8dcad2be4e
commit
41536384c3
2 changed files with 41 additions and 13 deletions
|
|
@ -182,6 +182,26 @@ def build_import_pipeline_runtime(
|
|||
)
|
||||
|
||||
|
||||
|
||||
def _persist_verification_status(context, final_path):
|
||||
"""Compute + persist the verification status (verified / unverified /
|
||||
force_imported) for a finished import: embedded tag on the file, plus
|
||||
context['_verification_status'] for the history row and the Downloads UI.
|
||||
MUST be called on EVERY success exit of post-processing (main, playlist
|
||||
folder mode, simple download) — a missed exit means no badge and no tag.
|
||||
Never raises."""
|
||||
try:
|
||||
from core.matching.verification_status import status_for_import
|
||||
from core.tag_writer import write_verification_status
|
||||
status = status_for_import(context)
|
||||
if status:
|
||||
context['_verification_status'] = status
|
||||
if final_path:
|
||||
write_verification_status(str(final_path), status)
|
||||
except Exception as _vs_err:
|
||||
logger.debug(f"verification-status persist skipped: {_vs_err}")
|
||||
|
||||
|
||||
def post_process_matched_download(context_key, context, file_path, runtime, metadata_runtime=None):
|
||||
on_download_completed = getattr(runtime, "on_download_completed", None)
|
||||
automation_engine = getattr(runtime, "automation_engine", None)
|
||||
|
|
@ -450,6 +470,7 @@ def post_process_matched_download(context_key, context, file_path, runtime, meta
|
|||
logger.info(f"Simple download post-processing complete: {activity_target}")
|
||||
context['_simple_download_completed'] = True
|
||||
context['_final_path'] = str(destination)
|
||||
_persist_verification_status(context, destination)
|
||||
emit_track_downloaded(context, automation_engine)
|
||||
record_library_history_download(context)
|
||||
record_download_provenance(context)
|
||||
|
|
@ -627,6 +648,8 @@ def post_process_matched_download(context_key, context, file_path, runtime, meta
|
|||
final_path = downsampled_path
|
||||
context['_final_processed_path'] = final_path
|
||||
|
||||
_persist_verification_status(context, final_path)
|
||||
|
||||
blasphemy_path = create_lossy_copy(final_path)
|
||||
if blasphemy_path:
|
||||
context['_final_processed_path'] = blasphemy_path
|
||||
|
|
@ -944,19 +967,7 @@ def post_process_matched_download(context_key, context, file_path, runtime, meta
|
|||
final_path = downsampled_path
|
||||
context['_final_processed_path'] = final_path
|
||||
|
||||
# Persist the verification status (verified / unverified / force_imported)
|
||||
# as an embedded tag so it travels with the file and survives DB resets.
|
||||
# Written BEFORE the lossy copy so the copy inherits it. Also stashed on
|
||||
# the context so the wrapper can surface it on the Downloads page.
|
||||
try:
|
||||
from core.matching.verification_status import status_for_import
|
||||
from core.tag_writer import write_verification_status
|
||||
_verif_status = status_for_import(context)
|
||||
if _verif_status:
|
||||
context['_verification_status'] = _verif_status
|
||||
write_verification_status(final_path, _verif_status)
|
||||
except Exception as _vs_err:
|
||||
logger.debug(f"verification-status persist skipped: {_vs_err}")
|
||||
_persist_verification_status(context, final_path)
|
||||
|
||||
blasphemy_path = create_lossy_copy(final_path)
|
||||
if blasphemy_path:
|
||||
|
|
|
|||
|
|
@ -641,6 +641,23 @@ class MusicDatabase:
|
|||
cursor.execute(f"ALTER TABLE library_history ADD COLUMN {_col} TEXT")
|
||||
logger.info(f"Added {_col} column to library_history")
|
||||
|
||||
# One-time backfill: derive verification_status for history rows
|
||||
# written before the column existed (or by pipeline exits that
|
||||
# missed it) from the acoustid_result those imports already
|
||||
# recorded (pass->verified, skip->unverified). force_imported
|
||||
# can't be derived retroactively. Idempotent: only fills NULLs.
|
||||
cursor.execute("""
|
||||
UPDATE library_history SET verification_status =
|
||||
CASE acoustid_result
|
||||
WHEN 'pass' THEN 'verified'
|
||||
WHEN 'skip' THEN 'unverified'
|
||||
END
|
||||
WHERE verification_status IS NULL
|
||||
AND acoustid_result IN ('pass', 'skip')
|
||||
""")
|
||||
if cursor.rowcount:
|
||||
logger.info("Backfilled verification_status from acoustid_result (%d rows)", cursor.rowcount)
|
||||
|
||||
# Migration: download-origin provenance — what TRIGGERED a download
|
||||
# ('watchlist' + artist / 'playlist' + playlist name). Read by the
|
||||
# origin-history modal on the watchlist + sync pages.
|
||||
|
|
|
|||
Loading…
Reference in a new issue