Save downloaded covers as folder.jpg (Jellyfin standard), PNG→JPEG on download

- download_cover() now writes folder.jpg instead of _cover_download{ext}
- PNG responses are converted to JPEG via PIL during download (avoids PNG
  in the album directory entirely)
- find_local_cover() priority: folder > front > cover > album (folder.jpg
  is now the canonical name for both downloaded and manually placed covers)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-04-29 08:26:33 +02:00
commit 7516de439f

View file

@ -47,7 +47,7 @@ def _image_ok(path: Path) -> bool:
def find_local_cover(image_files: List[Path]) -> Optional[Path]:
priority = ("front", "folder", "cover", "album")
priority = ("folder", "front", "cover", "album")
# Sort by priority keyword, then size descending
def key(p: Path):
name = p.name.lower()
@ -80,20 +80,27 @@ def download_cover(release_mbid: Optional[str], dest_dir: Path) -> Optional[Path
url = _mb_cover_url(release_mbid)
if not url:
return None
dest = dest_dir / "folder.jpg"
try:
r = requests.get(url, timeout=15)
if r.status_code == 200:
ext = ".jpg"
if r.status_code != 200:
return None
ct = r.headers.get("content-type", "")
if "png" in ct:
ext = ".png"
dest = dest_dir / f"_cover_download{ext}"
if "png" in ct and HAS_PIL:
# PNG → JPEG konvertieren
import io
with Image.open(io.BytesIO(r.content)) as img:
buf = io.BytesIO()
img.convert("RGB").save(buf, format="JPEG", quality=92)
dest.write_bytes(buf.getvalue())
else:
dest.write_bytes(r.content)
if _image_ok(dest):
return dest
dest.unlink(missing_ok=True)
except Exception as e:
print(f" ⚠️ Cover-Download-Fehler: {e}", file=sys.stderr)
dest.unlink(missing_ok=True)
return None