Files
siftlode/backend/tests/test_thumbnail_poster.py
T
peter b1832afd18 style: apply ruff format across backend + scripts (line-length 100)
Mechanical, whole-tree `ruff format` pass — no behaviour change. Recorded in
.git-blame-ignore-revs (next commit) so git blame skips it.
2026-08-23 07:43:06 +02:00

59 lines
1.8 KiB
Python

"""`thumbnail_to_jpg`: robustly turn a downloaded thumbnail into a real JPEG poster/og:image.
This replaced yt-dlp's `FFmpegThumbnailsConvertor`, whose `-bsf:v mjpeg2jpeg` path crashed on some
already-JPEG thumbnails (Reddit serves a JPEG under a `.png` name) — and because a postprocessor
error is fatal, it used to fail the WHOLE download. The key regression property here is that a bad
thumbnail returns None (poster falls back to a cut frame) instead of raising.
"""
import shutil
import subprocess
from pathlib import Path
import pytest
from app.downloads import edit
_ffmpeg_missing = shutil.which("ffmpeg") is None
needs_ffmpeg = pytest.mark.skipif(_ffmpeg_missing, reason="ffmpeg not available")
def _is_jpeg(p: Path) -> bool:
return p.exists() and p.read_bytes()[:3] == b"\xff\xd8\xff"
@needs_ffmpeg
def test_converts_a_png_to_a_real_jpeg(tmp_path):
src = tmp_path / "thumb.png"
subprocess.run(
[
"ffmpeg",
"-y",
"-loglevel",
"error",
"-f",
"lavfi",
"-i",
"color=c=red:s=64x64",
"-frames:v",
"1",
str(src),
],
check=True,
)
out = edit.thumbnail_to_jpg(src, tmp_path / "poster.jpg")
assert out is not None and _is_jpeg(out)
def test_returns_none_for_a_missing_source(tmp_path):
assert edit.thumbnail_to_jpg(None, tmp_path / "p.jpg") is None
assert edit.thumbnail_to_jpg(tmp_path / "nope.png", tmp_path / "p.jpg") is None
@needs_ffmpeg
def test_returns_none_on_garbage_input_instead_of_raising(tmp_path):
# The whole point: a thumbnail ffmpeg can't decode must NOT crash the download.
bad = tmp_path / "bad.png"
bad.write_bytes(b"this is definitely not an image")
assert edit.thumbnail_to_jpg(bad, tmp_path / "p.jpg") is None