生成器可检测与管理远端主题素材(列表 / 差异 / 覆盖 / 删除)
「传上去」之后还得知道「传得对不对」:同一 slug 传过三次、换过 slug 旧图还在、 重新导出后远端仍是旧版,这些在页面上都看不出来。 - serve.py:s3_request 支持 query;新增 ListObjectsV2(含分页)与 DeleteObject, 端点 /api/s3/list、/api/s3/delete。 - index.html:远端素材清单按对象键名跟本地比 —— 一致 / 旧图(同名但大小不同)/ 多余(当前主题已不引用)/ 缺失。「补齐差异」只传缺的与旧图,「删除多余」批量删, 单行可 ↻ 覆盖或 ✕ 删除;删除走 confirm 二次确认。改过 slug 会提示重新检测。 - 修:list 返回完整键而 upload/delete 收相对键,不剥前缀会删到不存在的键 (S3 回 204,看起来删成功其实没删)。加 relKey() 统一。 - check_sigv4.py 补带 query 的用例(ListObjectsV2 三参数、乱序 token)→ 8/8; selftest_upload.py 补列表/分页/幂等删除 → 20 项全过。
This commit is contained in:
@@ -100,7 +100,34 @@ def main():
|
||||
"data": base64.b64encode(b"x").decode()}])
|
||||
check("空前缀传桶根", up2["ok"] and "root.webp" in MockS3.store, str(list(MockS3.store)))
|
||||
|
||||
# 7) 虚拟主机风格的路径(不带桶名)
|
||||
# 7) 列远端:前缀过滤、大小、分页
|
||||
serve.upload_files(cfg, [{"key": "shiroko/asset3.webp", "contentType": "image/webp",
|
||||
"data": base64.b64encode(b"three").decode()}])
|
||||
ls = serve.list_objects(cfg, "shiroko/")
|
||||
keys = sorted(o["key"] for o in ls["objects"])
|
||||
check("按 <前缀>/<slug>/ 列出 3 个对象",
|
||||
keys == ["themes/shiroko/asset1.webp", "themes/shiroko/asset2.webp",
|
||||
"themes/shiroko/asset3.webp"], str(keys))
|
||||
size1 = [o["size"] for o in ls["objects"] if o["key"].endswith("asset1.webp")]
|
||||
check("对象大小与上传字节一致", size1 == [len(f1)], str(size1))
|
||||
paged = serve.list_objects(cfg, "shiroko/", max_keys=2)
|
||||
check("分页把 3 个都取回来了", len(paged["objects"]) == 3, str(len(paged["objects"])))
|
||||
everything = serve.list_objects(cfg, "")
|
||||
# 空前缀 = 列「路径前缀」之下(跨主题),不扫整个桶:桶里还可能有头像等别的东西。
|
||||
check("空前缀列出 <路径前缀>/ 下全部、且不越界",
|
||||
all(o["key"].startswith("themes/") for o in everything["objects"])
|
||||
and len(everything["objects"]) == 3,
|
||||
str([o["key"] for o in everything["objects"]]))
|
||||
|
||||
# 8) 删除:幂等(不存在的键也当成功),且不影响别的前缀
|
||||
del_res = serve.delete_objects(cfg, ["shiroko/asset3.webp", "shiroko/nonexistent.webp"])
|
||||
check("删除含不存在的键仍算成功", del_res["ok"] and del_res["total"] == 2, str(del_res))
|
||||
after = serve.list_objects(cfg, "shiroko/")
|
||||
check("删完只剩 2 个", len(after["objects"]) == 2,
|
||||
str([o["key"] for o in after["objects"]]))
|
||||
check("桶根对象没被误删", "root.webp" in MockS3.store)
|
||||
|
||||
# 9) 虚拟主机风格的路径(不带桶名)
|
||||
vh = serve.S3Config(dict(base, pathStyle=False))
|
||||
check("虚拟主机路径不含桶名", vh.object_path("themes/a.webp") == "/themes/a.webp", vh.object_path("x"))
|
||||
check("虚拟主机 host 带桶名", vh.host.startswith(BUCKET + "."), vh.host)
|
||||
|
||||
Reference in New Issue
Block a user