Library Re-tag: pull cover art from the configured cover-art sources
User feedback (Sokhi): after changing cover-art sources, re-tag should re-download fresh covers from THEM. The job took cover_url only from the matched metadata source's album image, ignoring the user's configured cover-art order. Now prefer select_preferred_art_url (the same metadata_enhancement.album_art_order the post-process embed honors), falling back to the source image when no order is configured (non-breaking). 'replace' cover mode already force-refreshes art on every matched album, and the embed replaces existing art (no duplicate pictures) — so 'replace' + a configured art order = fresh covers from those sources. Help text updated. Tests: prefers configured source URL / falls back to source image when unset.
This commit is contained in:
parent
3fe635fcd6
commit
93d2399cf8
2 changed files with 62 additions and 1 deletions
|
|
@ -208,7 +208,11 @@ class LibraryRetagJob(RepairJob):
|
|||
'Turn it off to auto-apply on scan.\n'
|
||||
'- Mode: "overwrite" rewrites every field the source provides; "fill_missing" '
|
||||
'only fills blank tags (keeps your existing values).\n'
|
||||
'- Cover art: replace / fill-missing / skip.\n'
|
||||
'- Cover art: replace / fill-missing / skip. "replace" force-refreshes '
|
||||
'art on every matched album (use this after changing your cover-art '
|
||||
'sources to re-pull fresh covers). When you have configured cover-art '
|
||||
'sources (Settings > metadata enhancement art order), the art is pulled '
|
||||
'from those; otherwise it falls back to the matched source\'s album image.\n'
|
||||
'- Source: which matched source to pull from (default: your source priority).'
|
||||
)
|
||||
icon = 'repair-icon-retag'
|
||||
|
|
@ -339,6 +343,23 @@ class LibraryRetagJob(RepairJob):
|
|||
cover_url = v
|
||||
break
|
||||
|
||||
# Honor the user's configured cover-art sources (the same
|
||||
# `metadata_enhancement.album_art_order` the post-process embed uses), so
|
||||
# changing those sources and re-tagging pulls fresh art FROM them rather
|
||||
# than always using the matched metadata source's album image. Non-
|
||||
# breaking: select_preferred_art_url returns None when no order is
|
||||
# configured, so we keep the source image. Skipped when not embedding art.
|
||||
if cover_mode != 'skip':
|
||||
try:
|
||||
from core.metadata.art_lookup import select_preferred_art_url
|
||||
order = (context.config_manager.get('metadata_enhancement.album_art_order')
|
||||
if context.config_manager else None)
|
||||
preferred = select_preferred_art_url(artist_name, album_title, album_meta, order)
|
||||
if preferred:
|
||||
cover_url = preferred
|
||||
except Exception as e:
|
||||
logger.debug("preferred cover-art lookup failed for album %s: %s", album_id, e)
|
||||
|
||||
# Cover action (album-level), independent of tag changes. Decided first
|
||||
# so cover-only albums (tags fine, art missing) still include their
|
||||
# tracks for the apply to embed art into.
|
||||
|
|
|
|||
|
|
@ -111,6 +111,46 @@ def test_scan_dry_run_off_auto_applies_no_finding(tmp_path, monkeypatch):
|
|||
assert writes and writes[0]['title'] == 'Real Title' # actually wrote
|
||||
|
||||
|
||||
def test_scan_prefers_configured_cover_art_source(tmp_path, monkeypatch):
|
||||
"""Sokhi's request: when cover-art sources are configured, the re-tag pulls
|
||||
art from them (select_preferred_art_url) instead of the matched source's
|
||||
album image — so changing sources + 'replace' re-downloads fresh covers."""
|
||||
track = tmp_path / 'track.flac'; track.write_bytes(b'')
|
||||
conn = _db_with_album(str(tmp_path / 'm.db'), str(track), current_title='Old Title')
|
||||
ctx = _context(conn, {'mode': 'overwrite', 'cover_art': 'replace', 'source': 'spotify'})
|
||||
_patch_source(monkeypatch, {
|
||||
'title': 'Old Title', 'album_artist': 'Real Artist', 'album': 'Real Album',
|
||||
'year': '2021', 'genre': 'Rock', 'track_number': 1, 'disc_number': 1,
|
||||
})
|
||||
monkeypatch.setattr('core.metadata.art_lookup.select_preferred_art_url',
|
||||
lambda artist, album, meta, order, **k: 'http://itunes/big-cover.jpg')
|
||||
|
||||
result = lr.LibraryRetagJob().scan(ctx)
|
||||
|
||||
assert result.findings_created == 1
|
||||
d = ctx.findings[0]['details']
|
||||
assert d['cover_url'] == 'http://itunes/big-cover.jpg' # configured source won
|
||||
assert d['cover_action'] == 'replace'
|
||||
|
||||
|
||||
def test_scan_falls_back_to_source_image_when_no_configured_art(tmp_path, monkeypatch):
|
||||
"""Non-breaking: with no configured cover-art order, keep using the matched
|
||||
source's album image (select_preferred_art_url returns None)."""
|
||||
track = tmp_path / 'track.flac'; track.write_bytes(b'')
|
||||
conn = _db_with_album(str(tmp_path / 'm.db'), str(track), current_title='Old Title')
|
||||
ctx = _context(conn, {'mode': 'overwrite', 'cover_art': 'replace', 'source': 'spotify'})
|
||||
_patch_source(monkeypatch, {
|
||||
'title': 'Old Title', 'album_artist': 'Real Artist', 'album': 'Real Album',
|
||||
'year': '2021', 'genre': 'Rock', 'track_number': 1, 'disc_number': 1,
|
||||
})
|
||||
monkeypatch.setattr('core.metadata.art_lookup.select_preferred_art_url',
|
||||
lambda *a, **k: None)
|
||||
|
||||
result = lr.LibraryRetagJob().scan(ctx)
|
||||
d = ctx.findings[0]['details']
|
||||
assert d['cover_url'] == 'http://art/cover.jpg' # _ALBUM_META['image_url']
|
||||
|
||||
|
||||
def test_scan_full_depth_attaches_full_meta_to_finding(tmp_path, monkeypatch):
|
||||
"""depth=full: each track plan carries a full_meta dict (title/album/artist +
|
||||
source ids) for the enrichment cascade, and details record the depth."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue