feat(art): replace all 72 posts' artwork with the v2 pipeline
Deploy / build (push) Successful in 17s
Deploy / build (push) Successful in 17s
Every post now carries one unique local-ComfyUI/Ideogram 4 base frame, composited into EN + ZH share cards, a banner and list thumbs. - the shipped prompts_catalog held only 21 distinct metaphors for 72 posts (16 shared one visual), so all 72 were rewritten as unique object+state metaphors and 10 frames re-rolled after OCR found pseudo-text rendered at legible size - render_from_art.mjs emits JPEG by default (558 KB PNG -> 84 KB mozjpeg q85); the ZH 1200x630 card did not exist before this batch - 288 frontmatter fields migrated; the 144 v1 PNGs are gone - PostList's thumb helper keys off the base slug (a ZH card is zh-<slug>.jpg while the thumb is <slug>-800.webp, which 404'd the whole ZH listing) - [...slug].astro's <picture> regex accepts .jpg - the repo now carries the art inputs (metaphors.json, captions/<slug>.json, refreshed prompts_catalog.json) so a frame is reproducible from git alone
This commit is contained in:
1 parent
72a9a2af6f
commit
327d516ed9
802 files changed
+1289
-519
No files matched your search
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""sync_prompts_catalog.py — freeze the art inputs into the repo.
|
||||
|
||||
The metaphors and captions are authored in the Ideogram 4 tool dir
|
||||
(`C:/AI/ideogram4/`), which is NOT in this repository. Without this script the
|
||||
repository could not reproduce a single frame: `prompts_catalog.json` would still
|
||||
describe the 21 shared metaphors that produced the near-duplicate v1-adjacent art.
|
||||
|
||||
This copies the authoring state into the repo so git alone is enough:
|
||||
|
||||
scripts/og-gen/metaphors.json slug -> the unique metaphor (72/72 distinct)
|
||||
scripts/og-gen/captions/<slug>.json the exact structured caption sent to the model
|
||||
scripts/og-gen/prompts_catalog.json same shape as before, refreshed from the above
|
||||
|
||||
Usage:
|
||||
python scripts/og-gen/sync_prompts_catalog.py # uses C:/AI/ideogram4
|
||||
python scripts/og-gen/sync_prompts_catalog.py --tool-dir D:/other
|
||||
python scripts/og-gen/sync_prompts_catalog.py --check # report only, no writes
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import importlib.util
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parents[2]
|
||||
OG = REPO / "scripts" / "og-gen"
|
||||
|
||||
|
||||
def load_metaphors(tool_dir: Path) -> dict[str, str]:
|
||||
src = tool_dir / "build_captions.py"
|
||||
if not src.exists():
|
||||
raise SystemExit(f"no build_captions.py under {tool_dir} (pass --tool-dir)")
|
||||
spec = importlib.util.spec_from_file_location("build_captions", src)
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
return dict(mod.METAPHORS)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--tool-dir", default="C:/AI/ideogram4")
|
||||
ap.add_argument("--check", action="store_true", help="report only, write nothing")
|
||||
args = ap.parse_args()
|
||||
|
||||
tool = Path(args.tool_dir)
|
||||
metaphors = load_metaphors(tool)
|
||||
|
||||
posts = {p.stem for p in (REPO / "src" / "content" / "posts").glob("*.md")}
|
||||
catalog = json.loads((OG / "prompts_catalog.json").read_text(encoding="utf-8"))
|
||||
meta = json.loads((OG / "art-meta.json").read_text(encoding="utf-8"))
|
||||
|
||||
problems = []
|
||||
if set(metaphors) != posts:
|
||||
problems.append(f"slug mismatch: missing={sorted(posts - set(metaphors))[:4]} extra={sorted(set(metaphors) - posts)[:4]}")
|
||||
if len(set(metaphors.values())) != len(metaphors):
|
||||
problems.append(f"only {len(set(metaphors.values()))} distinct metaphors for {len(metaphors)} posts")
|
||||
|
||||
missing_captions = [s for s in metaphors if not (tool / "captions" / f"{s}.json").exists()]
|
||||
if missing_captions:
|
||||
problems.append(f"{len(missing_captions)} captions absent from {tool / 'captions'}")
|
||||
missing_evidence = [s for s in metaphors if not meta.get(s, {}).get("evidence")]
|
||||
if missing_evidence:
|
||||
problems.append(f"{len(missing_evidence)} posts have no evidence line in art-meta.json")
|
||||
|
||||
print(f"posts {len(posts)} · metaphors {len(metaphors)} · distinct {len(set(metaphors.values()))} · catalog {len(catalog)}")
|
||||
print("problems:", problems or "none")
|
||||
if problems:
|
||||
sys.exit(1)
|
||||
if args.check:
|
||||
print("--check: nothing written")
|
||||
return
|
||||
|
||||
(OG / "metaphors.json").write_text(
|
||||
json.dumps({k: metaphors[k] for k in sorted(metaphors)}, indent=2, ensure_ascii=False) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
dest = OG / "captions"
|
||||
dest.mkdir(exist_ok=True)
|
||||
for slug in metaphors:
|
||||
shutil.copyfile(tool / "captions" / f"{slug}.json", dest / f"{slug}.json")
|
||||
|
||||
by_slug = {e["slug"]: e for e in catalog}
|
||||
out = []
|
||||
for slug in sorted(metaphors):
|
||||
entry = by_slug.get(slug, {"slug": slug})
|
||||
caption = json.loads((tool / "captions" / f"{slug}.json").read_text(encoding="utf-8"))
|
||||
elems = caption.get("compositional_details", {}).get("elements", [])
|
||||
entry["unique_elements"] = metaphors[slug]
|
||||
entry["prompt"] = " ".join(e.get("desc", "") for e in elems).strip() or metaphors[slug]
|
||||
entry["evidence_summary"] = meta.get(slug, {}).get("evidence", entry.get("evidence_summary", ""))
|
||||
entry["caption"] = f"captions/{slug}.json"
|
||||
out.append(entry)
|
||||
(OG / "prompts_catalog.json").write_text(json.dumps(out, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
print(f"wrote metaphors.json, captions/ ({len(metaphors)} files), prompts_catalog.json")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user