Cover Art Filler: write cover.jpg to the RESOLVED folder, not the raw DB path (Sokhi — the actual bug)
THE bug behind "embeds art but never writes cover.jpgs": _fix_missing_cover_art passed `details['album_folder']` (= dirname of the raw DB path, e.g. Jellyfin's /data/music/...) as the target folder. That path doesn't exist inside the SoulSync container — only the resolved /app/... path does. So apply_art_to_album_ files' `os.path.isdir(target_dir)` was False and the ENTIRE cover.jpg block was silently skipped: embedding still worked (it uses the resolved paths) and the DB thumb updated, but the sidecar was never written. Exactly Sokhi's symptom + the "Cover art already present — database thumbnail updated" toast (cover_written stayed False). Fix: - _fix_missing_cover_art: derive the folder from the RESOLVED file (os.path.dirname(resolved[0])), never the raw album_folder. - apply_art_to_album_files: bulletproof it — if the passed folder doesn't exist, fall back to the real directory of the files instead of silently skipping. Tests: a non-existent folder still writes cover.jpg to the real file dir. 1348 cover/art/repair tests pass.
This commit is contained in:
parent
2f3ade8acb
commit
13dca2dea6
3 changed files with 37 additions and 3 deletions
|
|
@ -198,8 +198,15 @@ def apply_art_to_album_files(
|
|||
logger.warning("Could not embed art into %s: %s", fp, exc)
|
||||
result["failed"] += 1
|
||||
|
||||
target_dir = folder or (os.path.dirname(paths[0]) if paths else None)
|
||||
if target_dir and os.path.isdir(target_dir) and not folder_has_cover_sidecar(target_dir):
|
||||
# Prefer the caller's folder, but if it doesn't actually exist (e.g. a raw
|
||||
# DB path that isn't mounted in this container), fall back to the real
|
||||
# directory of the files we just wrote to — never silently skip the sidecar
|
||||
# because a passed-in folder was wrong (Sokhi: cover.jpg never written).
|
||||
target_dir = folder if (folder and os.path.isdir(folder)) else None
|
||||
if not target_dir and paths:
|
||||
cand = os.path.dirname(paths[0])
|
||||
target_dir = cand if os.path.isdir(cand) else None
|
||||
if target_dir and not folder_has_cover_sidecar(target_dir):
|
||||
# Prefer the album's OWN embedded art for the cover.jpg sidecar: it's
|
||||
# always present once the files are arted (we may have just embedded it),
|
||||
# needs no API call, and the sidecar matches the files exactly
|
||||
|
|
|
|||
|
|
@ -1394,7 +1394,14 @@ class RepairWorker:
|
|||
'album_name': album_title, 'album_image_url': artwork_url,
|
||||
'musicbrainz_release_id': mbid,
|
||||
}
|
||||
folder = details.get('album_folder') or os.path.dirname(resolved[0])
|
||||
# Use the RESOLVED file's directory — NOT details['album_folder'], which
|
||||
# is the raw DB path (e.g. Jellyfin's /data/music) and frequently does
|
||||
# NOT exist inside the SoulSync container (only the resolved /app/...
|
||||
# path does). Passing the raw folder made os.path.isdir() fail in
|
||||
# apply_art_to_album_files, silently skipping the cover.jpg write while
|
||||
# embedding (which uses the resolved paths) still worked — Sokhi's
|
||||
# "embeds art but never writes cover.jpgs".
|
||||
folder = os.path.dirname(resolved[0])
|
||||
art_result = apply_art_to_album_files(resolved, metadata, album_info, folder=folder)
|
||||
|
||||
embedded = art_result.get('embedded', 0)
|
||||
|
|
|
|||
|
|
@ -314,3 +314,23 @@ def test_apply_skips_cover_when_sidecar_exists(tmp_path, monkeypatch):
|
|||
aa.apply_art_to_album_files([str(f)], {}, {}, folder=str(tmp_path))
|
||||
assert (tmp_path / 'cover.jpg').read_bytes() == b'EXISTING' # untouched
|
||||
assert dl_called == []
|
||||
|
||||
|
||||
def test_apply_cover_falls_back_to_file_dir_when_folder_doesnt_exist(tmp_path, monkeypatch):
|
||||
# The Sokhi bug: the caller passed the raw DB folder (e.g. Jellyfin's
|
||||
# /data/music/...) which doesn't exist in the container, so the cover.jpg
|
||||
# write was silently skipped. Now it falls back to the real directory of
|
||||
# the files and writes there anyway.
|
||||
real_dir = tmp_path / 'real'
|
||||
real_dir.mkdir()
|
||||
f = real_dir / '01.flac'; f.write_bytes(b'')
|
||||
audio = SimpleNamespace(pictures=[SimpleNamespace(data=b'EMB')], tags=None, save=lambda: None)
|
||||
monkeypatch.setattr(aa, 'get_mutagen_symbols', lambda: _fake_symbols(audio))
|
||||
monkeypatch.setattr(aa, 'embed_album_art_metadata', lambda *a, **k: True)
|
||||
monkeypatch.setattr(aa, 'download_cover_art', lambda *a, **k: None)
|
||||
|
||||
res = aa.apply_art_to_album_files([str(f)], {}, {},
|
||||
folder='/data/music/does/not/exist/in/container')
|
||||
|
||||
assert (real_dir / 'cover.jpg').read_bytes() == b'EMB' # written to the REAL dir
|
||||
assert res['cover_written'] is True
|
||||
|
|
|
|||
Loading…
Reference in a new issue