Files
blog/scripts/photos_ingest.py
wait4xandGLM-5.3 44bfb23efb feat(gallery): 原图查看与下载——仓外 originals store 双轨制
- git 仓只进压缩版(构建用);原图落 ~/docker_apps/blog/photos-originals/
  (迁移器/ingest 双入口写入,幂等),build.sh 独立 rsync 到
  staging/photos-originals/(同一静态根,零 nginx 改动)
- lightbox 增「原图」(新标签全尺寸)+「下载」(download 属性带文件名)
- 原图持久保障:store + Phase 0 备份 tar 双留档;存量 21 张已回填(196M)

验证: astro build 11 页 exit 0;dist/gallery 含 lb-original×2 与
      photos-originals 引用;staging/photos-originals 21 张实测

Spec: none (用户功能补req:原图查看/下载,跨 Phase 独立小特性)

Co-authored-by: GLM-5.3
2026-10-25 09:12:26 +08:00

53 lines
2.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""照片入库处理器:把 content/photos/ 下超限图片压缩到站内规范。
为什么存在:gitea web/本地上传的是原图(曾发生 196M/21 张入仓事故,
见 git log aea21c8 的重写说明);sharp 只派生 dist 缩略图不管仓内体积。
工作流:上传照片到 content/photos/(顺带跑一次 sidecar 生成或手写)后、
git commit 前执行本脚本;幂等,已在规范内的文件原样跳过(零 diff)。
规范与迁移器一致:长边 ≤2400px、JPEG q86(scripts/migrate/photos_migrate.py)。
"""
import sys
from pathlib import Path
PHOTOS = Path("content/photos")
MAX_EDGE = 2400
QUALITY = 86
# 跳过阈值:小于此字节数的 jpg 视为已处理过(2400px q86 成片通常 200KB-1MB)
SKIP_BELOW_BYTES = 1_500_000
def main() -> int:
from PIL import Image
changed, skipped = [], 0
for jpg in sorted(PHOTOS.glob("*.jpg")):
size = jpg.stat().st_size
if size < SKIP_BELOW_BYTES:
skipped += 1
continue
STORE = Path.home() / "docker_apps/blog/photos-originals"
STORE.mkdir(parents=True, exist_ok=True)
# 压缩覆写仓内文件前原件先进 store(幂等:store 已有同名则跳过)
if not (STORE / jpg.name).exists():
(STORE / jpg.name).write_bytes(jpg.read_bytes())
img = Image.open(jpg)
# EXIF 显式保留:重存默认剥离会抽走图库参数条的构建期数据源
exif = img.info.get("exif")
if img.mode not in ("RGB", "L"):
img = img.convert("RGB")
img.thumbnail((MAX_EDGE, MAX_EDGE))
kwargs = {"exif": exif} if exif else {}
img.save(jpg, "JPEG", quality=QUALITY, optimize=True, **kwargs)
changed.append((jpg.name, size, jpg.stat().st_size))
for name, before, after in changed:
print(f" compressed: {name} {before/1e6:.1f}M -> {after/1e6:.2f}M")
print(f"photos ingest: {len(changed)} compressed, {skipped} skipped (within spec)")
return 0
if __name__ == "__main__":
sys.exit(main())