Files
blog/scripts/migrate/halo_export.py
wait4xandGLM-5.3 aea21c8694 feat(migrate): Halo 全量内容迁移(压缩版)——6文/21图/1瞬间 URL 1:1
- 正文源=线上渲染页(Halo 快照层 patch 残迹:泥潭/赎罪仅 2 字符),
  pandoc html→gfm + tags API 显示名换算后分类:5 书评(五档情绪色)+1 技术
- 图库 21 张:长边 2400/q86 压缩入仓(原图 196M→9.5M——公开仓历史膨胀
  与 nginx 100M 推送上限双杀;原图在 Phase 0 备份 tar 中永久留档)
- 瞬间 1 条;URL 1:1(6 slug 全等,零 301)
- 本提交由 7 个本地提交重写而成(清除已进历史的 196M blob,未推送过);
  因 reset --soft 暂存竞态,一并包含 spec 归档文件
  (.spec/specs/archive/2026-10-24_migrate-blog-content/)

验证: check_urls.py 6==6;astro build 11 页 exit 0(8.67s);
      EXIF 管线跑通;staging 更新;halo healthy+200 全程未动

Co-authored-by: GLM-5.3
2026-10-25 00:39:08 +08:00

66 lines
2.5 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
"""Halo 全量导出(Phase 2 T1):posts/photos/moments → .migration/*.json
对生产仅 GET;正文优先取列表 status.content,缺则回落 head-content 端点。
产物为迁移中间件,不入库(.gitignore .migration/)。
"""
import json
import sys
import urllib.request
from pathlib import Path
BASE = "http://127.0.0.1:18090"
OUT = Path(".migration")
OUT.mkdir(exist_ok=True)
def get(path: str) -> object:
with urllib.request.urlopen(BASE + path, timeout=30) as r:
return json.load(r)
def export_list(api: str, size: int = 100) -> list[dict]:
"""翻页取全量 items。"""
items, page = [], 1
while True:
data = get(f"{api}?page={page}&size={size}")
batch = data.get("items", [])
items.extend(batch)
if page * size >= data.get("total", 0) or not batch:
return items
page += 1
def main() -> int:
posts = export_list("/apis/api.content.halo.run/v1alpha1/posts")
# 正文兜底:head-content 拿完整 HTML(status.content 可能是截断摘要)
for p in posts:
name = p["metadata"]["name"]
content = (p.get("status") or {}).get("content")
if not content:
try:
head = get(f"/apis/api.content.halo.run/v1alpha1/posts/{name}/head-content")
p["_fullContent"] = head.get("content", "")
except Exception as e: # noqa: BLE001 - 单篇失败不阻断全量导出
p["_fullContent"] = ""
print(f" warn: {name} head-content 失败: {e}", file=sys.stderr)
photos = export_list("/apis/api.photo.halo.run/v1alpha1/photos")
try:
groups = get("/apis/api.photo.halo.run/v1alpha1/groups")
except Exception: # noqa: BLE001 - 分组端点缺失时空兜底
groups = {"items": []}
moments = export_list("/apis/api.moment.halo.run/v1alpha1/moments")
(OUT / "posts.json").write_text(json.dumps(posts, ensure_ascii=False, indent=1))
(OUT / "photos.json").write_text(json.dumps(photos, ensure_ascii=False, indent=1))
(OUT / "photo_groups.json").write_text(json.dumps(groups, ensure_ascii=False, indent=1))
(OUT / "moments.json").write_text(json.dumps(moments, ensure_ascii=False, indent=1))
full = sum(1 for p in posts if p.get("_fullContent") or (p.get("status") or {}).get("content"))
print(f"exported: posts={len(posts)}(含正文 {full})photos={len(photos)} groups={len(groups.get('items', []))} moments={len(moments)}")
return 0
if __name__ == "__main__":
sys.exit(main())