feat: complete academic symbol lexicon heal, 2-column Cooper extraction, and updated assets
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build assets/data/tarot_majors.json from scraped corpus + unified texts."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CORPUS = ROOT / "oracle_enricher" / "data" / "sources" / "tarot_majors_corpus.json"
|
||||
UNIFIED = ROOT / "oracle_enricher" / "out" / "tarot_unify" / "unified.json"
|
||||
CANON = ROOT / "oracle_enricher" / "data" / "traditions_canon.json"
|
||||
ASSET_CANON = ROOT / "assets" / "data" / "traditions_canon.json"
|
||||
OUT = ROOT / "assets" / "data" / "tarot_majors.json"
|
||||
HTML = ROOT / "lexicon_viewer.html"
|
||||
|
||||
ROMAN = ["0", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X",
|
||||
"XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX", "XXI"]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if not CORPUS.exists():
|
||||
raise SystemExit("нет tarot_majors_corpus.json — сначала scrape_tarot_majors.py")
|
||||
corpus = json.loads(CORPUS.read_text(encoding="utf-8"))
|
||||
unified = {}
|
||||
if UNIFIED.exists():
|
||||
unified = json.loads(UNIFIED.read_text(encoding="utf-8"))
|
||||
canon = json.loads(CANON.read_text(encoding="utf-8"))
|
||||
ID_MAP = {"wheel": "wheel_of_fortune"}
|
||||
by_id = {s["id"]: s for s in canon["tarot"]["stations"]}
|
||||
|
||||
cards_out = []
|
||||
for n in range(22):
|
||||
cc = corpus["cards"][str(n)]
|
||||
st = by_id.get(ID_MAP.get(cc["id"], cc["id"]), {})
|
||||
uc = (unified.get("cards") or {}).get(str(n)) or {}
|
||||
umeaning = (uc.get("meaning") or "").strip()
|
||||
pairs = []
|
||||
for other in range(22):
|
||||
if other == n:
|
||||
continue
|
||||
key = f"{min(n, other):02d}-{max(n, other):02d}"
|
||||
bucket = (corpus.get("pairs") or {}).get(key) or {}
|
||||
readings = bucket.get("readings") or []
|
||||
up = (unified.get("pairs") or {}).get(key) or {}
|
||||
utext = (up.get("text") or "").strip()
|
||||
preview = utext[:157] + "…" if len(utext) > 160 else utext
|
||||
if not preview and readings:
|
||||
preview = (readings[0].get("text") or "")[:160]
|
||||
ost = by_id.get(corpus["cards"][str(other)]["id"], {})
|
||||
pairs.append(
|
||||
{
|
||||
"n": other,
|
||||
"id": corpus["cards"][str(other)]["id"],
|
||||
"name": corpus["cards"][str(other)]["name"],
|
||||
"symbol": ost.get("symbol", ""),
|
||||
"preview": preview,
|
||||
"text": utext,
|
||||
"readings": [] if utext else readings,
|
||||
}
|
||||
)
|
||||
cards_out.append(
|
||||
{
|
||||
"n": n,
|
||||
"id": cc["id"],
|
||||
"name": cc["name"],
|
||||
"symbol": st.get("symbol", ""),
|
||||
"lore": (uc.get("core") or st.get("lore") or ""),
|
||||
"group": f"Старшие Арканы · {ROMAN[n]} {cc['name']}",
|
||||
"meaning": umeaning,
|
||||
"shadow": (uc.get("shadow") or "").strip(),
|
||||
"meanings": [] if umeaning else cc.get("meanings") or [],
|
||||
"pairs": pairs,
|
||||
}
|
||||
)
|
||||
|
||||
# fix canon groups
|
||||
for st in canon["tarot"]["stations"]:
|
||||
# id fool → n 0
|
||||
n = next((c["n"] for c in cards_out if c["id"] == st["id"]), None)
|
||||
if n is None:
|
||||
continue
|
||||
st["group"] = f"Старшие Арканы · {ROMAN[n]} {cards_out[n]['name']}"
|
||||
if cards_out[n]["lore"]:
|
||||
st["lore"] = cards_out[n]["lore"]
|
||||
canon["tarot"]["description"] = (
|
||||
"22 Старших Аркана: одно сводное значение и сочетания друг с другом "
|
||||
"(карусель, magya, эзопланета сведены в один текст)."
|
||||
)
|
||||
text_c = json.dumps(canon, ensure_ascii=False, indent=2) + "\n"
|
||||
CANON.write_text(text_c, encoding="utf-8")
|
||||
ASSET_CANON.write_text(text_c, encoding="utf-8")
|
||||
|
||||
blob = {
|
||||
"system": "tarot_majors",
|
||||
"card_count": 22,
|
||||
"pair_count": sum(len(c["pairs"]) for c in cards_out) // 2,
|
||||
"cards": cards_out,
|
||||
}
|
||||
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||
OUT.write_text(json.dumps(blob, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
if HTML.exists():
|
||||
html = HTML.read_text(encoding="utf-8")
|
||||
start = html.find(" const TRADITIONS_CANON = ")
|
||||
end = html.find(" const WORDS_DATA = ")
|
||||
if start > 0 and end > start:
|
||||
html = (
|
||||
html[:start]
|
||||
+ " const TRADITIONS_CANON = "
|
||||
+ json.dumps(canon, ensure_ascii=False, indent=2)
|
||||
+ ";\n\n"
|
||||
+ html[end:]
|
||||
)
|
||||
HTML.write_text(html, encoding="utf-8")
|
||||
print("wrote", OUT, "pairs", blob["pair_count"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user