"""Thumbnail generation and on-disk caching (~/.cache/SaraFem/Thumbnails).""" import hashlib from pathlib import Path from PIL import Image from Core import ThumbnailCacheDir ImageExtensions = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp"} def IsThumbnailable(EntryPath: Path) -> bool: return EntryPath.suffix.lower() in ImageExtensions def GetThumbnail(EntryPath: Path, Size: tuple[int, int] = (128, 128)) -> Path | None: """Return a cached thumbnail path for `EntryPath`, generating it if stale or missing.""" if not IsThumbnailable(EntryPath): return None Stat = EntryPath.stat() CacheKey = hashlib.sha256(f"{EntryPath}:{Stat.st_mtime}:{Size}".encode()).hexdigest() CachePath = ThumbnailCacheDir / f"{CacheKey}.png" if CachePath.exists(): return CachePath ThumbnailCacheDir.mkdir(parents=True, exist_ok=True) try: with Image.open(EntryPath) as Img: Img.thumbnail(Size) Img.convert("RGB").save(CachePath, "PNG") except Exception: return None return CachePath