new-sakura:花枝朝向与分叉修正,素材包一键导出上传到对象存储

- gen_new_sakura.py:花朵加各自旋转角(原来一律朝上,像贴纸);分叉从垂直下垂改成向右上斜;
  新增 --asset-base / --out —— 填前缀就引用对象存储位图,留空仍是内联 SVG。
- export_assets.py(新增):从 gen_new_sakura 的同一份 SVG 出图(直接 import,不另画一套),
  用无头 Chrome 透明底渲染后转 WebP;--upload 一次传 CSS + 5 张 webp + 生成的 INSTALL.txt,
  公开地址按 data/r2.txt 的 image_bucket_cdn_host(与 app.ini 同名)拼。
- serve.upload_files 支持逐文件 cacheControl。原来硬编码 immutable,而 INSTALL.txt 与镜像
  CSS 的键不带版本 —— 重新生成后浏览器/CDN 一年内都还是旧内容。现在位图 1 天、CSS 5 分钟、
  README 60 秒;selftest 补一条覆盖断言。
- 文档更正两处事实:①自定义域 r2.337845818.best 实测可匿名读(S3 endpoint 仍 403);
  ②服务端有 gzip,内联版 51KB 实际传输 3.9KB,比位图版(2.7KB + 5 图 48.9KB)小得多,
  所以「换位图省 CSS 体积」不成立,位图只在素材要复用到非 CSS 场景时才有意义。
  另记:曾以 immutable 传过的键必须去控制台清缓存,重传不会让边缘失效。
This commit is contained in:
tamakyi
2026-10-22 11:06:13 +08:00
parent 48a1938fb2
commit 5c0de805c6
8 changed files with 372 additions and 20 deletions
+11
View File
@@ -63,6 +63,17 @@ def main():
check("Content-Type = image/webp", ctype == "image/webp", str(ctype))
check("Cache-Control = immutable", "immutable" in (cache or ""), str(cache))
# 2b) 逐文件覆盖缓存头:README/清单这类「键不变、内容会变」的文件不能 immutable
serve.upload_files(cfg, [
{"key": "shiroko/INSTALL.txt", "contentType": "text/plain; charset=utf-8",
"cacheControl": "public, max-age=60",
"data": base64.b64encode(b"readme").decode()},
])
_, _, cc = MockS3.store.get("themes/shiroko/INSTALL.txt", (b"", None, None))
check("可覆盖 Cache-Control", cc == "public, max-age=60", str(cc))
# 这一步只为验头,别让它污染后面的对象计数
MockS3.store.pop("themes/shiroko/INSTALL.txt", None)
# 3) 错误密钥:HEAD 拿不到响应体(规范如此),只能按状态码归因;
# 真正能读到 S3 错误码的是带 body 的 PUT,所以用上传路径验证还原能力。
bad = serve.S3Config(dict(base, accessKey="BADKEY"))