From 7d481ae02f19e41c687a7eaa727801cac786334f Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Mon, 8 Jun 2026 10:03:43 -0700 Subject: [PATCH] Cover Art Filler: a local album with file art isn't "missing" just because the DB thumb is empty (Boulder) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Boulder (Plex): "flags every album, but everything has art." His albums show art in the library (served from the embedded file art), but the DB thumb_url cache column is empty — and the scan flagged on db_missing (empty thumb_url), so every local album tripped it despite having perfectly good art in the files. Now: a LOCAL album is flagged only when its files actually lack art (disk_missing). An empty thumb_url is just a stale cache when the files have art — not "missing cover art". db_missing still flags media-server-only albums (no local files), where the DB thumb is the only art there is. Tests: local+file-art+empty-thumb → NOT flagged (the bug); local+no-file-art → still flagged; media-server-only+empty-thumb → still flagged. --- core/repair_jobs/missing_cover_art.py | 17 +++++++++-- tests/test_missing_cover_art.py | 43 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/core/repair_jobs/missing_cover_art.py b/core/repair_jobs/missing_cover_art.py index bed11419..a4477c00 100644 --- a/core/repair_jobs/missing_cover_art.py +++ b/core/repair_jobs/missing_cover_art.py @@ -176,8 +176,21 @@ class MissingCoverArtJob(RepairJob): download_folder=download_folder, config_manager=context.config_manager, ) if rep_path else None - disk_missing = bool(resolved_rep) and not album_has_art_on_disk(resolved_rep) - if not db_missing and not disk_missing: + has_local = bool(resolved_rep) + disk_missing = has_local and not album_has_art_on_disk(resolved_rep) + # An album whose FILES already have art is not "missing cover art", + # even if the DB thumb_url cache happens to be empty — the library + # shows the file art either way. So for a local album, flag only when + # the files actually lack art. db_missing alone matters only for + # media-server-only albums (no local files), where the DB thumb is + # the sole art. Without this, every local album with an empty + # thumb_url got flagged despite having perfectly good embedded art + # (Boulder: "flags every album, but everything has art"). + if has_local: + needs_fix = disk_missing + else: + needs_fix = db_missing + if not needs_fix: result.skipped += 1 continue diff --git a/tests/test_missing_cover_art.py b/tests/test_missing_cover_art.py index da952e45..20b4324f 100644 --- a/tests/test_missing_cover_art.py +++ b/tests/test_missing_cover_art.py @@ -326,3 +326,46 @@ def test_scan_unresolvable_path_not_flagged_disk_missing(monkeypatch): assert result.findings_created == 0 # thumb present, disk unknown → not flagged assert called == [] # never checked art on a None path + + +def test_local_album_with_file_art_not_flagged_despite_empty_thumb(monkeypatch): + # Boulder: every album flagged, but "everything has art". Local files HAVE + # embedded art; only the DB thumb_url cache is empty. That is NOT missing + # cover art — must not be flagged. + conn = _make_db((1, 'Album', 1, '', None, None, None, None, None)) # empty thumb + _add_track(conn, '/music/Album/01.flac') + context = _make_context(conn) + monkeypatch.setattr(mca, 'resolve_library_file_path', lambda raw, **k: raw) + monkeypatch.setattr(mca, 'album_has_art_on_disk', lambda p: True) # files have art + + result = mca.MissingCoverArtJob().scan(context) + + assert result.findings_created == 0 # has file art → not "missing" + assert result.skipped == 1 + + +def test_local_album_without_file_art_still_flagged(monkeypatch): + # Local album whose files genuinely lack art → still flagged (real case). + # Give it a source id + findable art so a finding is created when flagged. + conn = _make_db((1, 'Album', 1, '', 'sp-album', None, None, None, None)) + _add_track(conn, '/music/Album/01.flac') + context = _make_context(conn) + monkeypatch.setattr(mca, 'resolve_library_file_path', lambda raw, **k: raw) + monkeypatch.setattr(mca, 'album_has_art_on_disk', lambda p: False) # no art on disk + monkeypatch.setattr(mca, 'get_primary_source', lambda: 'spotify') + monkeypatch.setattr(mca, 'get_client_for_source', lambda s: _FakeClient(album_image='https://img/x')) + + result = mca.MissingCoverArtJob().scan(context) + assert result.findings_created == 1 # files lack art → flagged + + +def test_media_server_only_album_empty_thumb_still_flagged(monkeypatch): + # No local files (media-server-only) + empty thumb → DB thumb is the only + # art, so still flag it. + conn = _make_db((1, 'Album', 1, '', 'sp-album', None, None, None, None)) # no track added + context = _make_context(conn) + monkeypatch.setattr(mca, 'get_primary_source', lambda: 'spotify') + monkeypatch.setattr(mca, 'get_client_for_source', lambda s: _FakeClient(album_image='https://img/x')) + + result = mca.MissingCoverArtJob().scan(context) + assert result.findings_created == 1 # media-server-only + empty thumb → flagged