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
This commit is contained in:
wait4xandGLM-5.3 committed 2026-10-25 09:12:26 +08:00
1 parent 382e56431f
commit 44bfb23efb
4 files changed
+50 -4

No files matched your search

+5 -3
View File
@@ -61,9 +61,11 @@ def main() -> int:
fname = unquote(url.rsplit("/", 1)[1])
slug = slugify(spec.get("displayName") or fname)
data = urllib.request.urlopen(BASE + url, timeout=60).read()
# 入仓前压到长边 2400/q86:原图总计 196M(单张最大 28M)会永久膨胀
# 公开仓历史并撞死 nginx 100M 推送上限;原图已随 Phase 0 备份归档,
# 站内展示由 sharp 出 srcset,2400px 足够 lightbox 全屏
# 原图双留档:仓外 originals store(构建时独立 rsync,服务"查看原图/
# 下载")+ Phase 0 备份 tar;git 仓只进压缩版(196M 事故教训)
STORE = Path.home() / "docker_apps/blog/photos-originals"
STORE.mkdir(parents=True, exist_ok=True)
(STORE / f"{slug}.jpg").write_bytes(data)
(OUT / f"{slug}.jpg").write_bytes(compress(data))
(OUT / f"{slug}.json").write_text(json.dumps({
+5
View File
@@ -27,6 +27,11 @@ def main() -> int:
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")