新六章有 12 节读错公开包字段,整节只剩未判定,而且六章绕过了口径替换。按资料包改读路径,先拼六章再统一替换措辞,并把中文附录实际丢掉的组合句数出来。
Co-Authored-By: Grok (agent loop) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Grok (agent loop)
Cursor
parent
365b1e647e
commit
92b4e220f2
@@ -2107,9 +2107,23 @@ def _render_pl9_ai_density_raw_data_markdown_en(packet: dict, language: str = "e
|
||||
][:6]
|
||||
if language == "zh":
|
||||
try:
|
||||
from scripts.report_render.appendix_language import FIELD_ZH
|
||||
from scripts.report_render.appendix_language import (
|
||||
ANNUAL_COLUMN_NAMES_BEFORE_FIX,
|
||||
FIELD_ZH,
|
||||
note_annual_table,
|
||||
note_dropped_annual_column,
|
||||
)
|
||||
except ModuleNotFoundError: # pragma: no cover
|
||||
from report_render.appendix_language import FIELD_ZH
|
||||
from report_render.appendix_language import (
|
||||
ANNUAL_COLUMN_NAMES_BEFORE_FIX,
|
||||
FIELD_ZH,
|
||||
note_annual_table,
|
||||
note_dropped_annual_column,
|
||||
)
|
||||
note_annual_table()
|
||||
for field in keys:
|
||||
if field not in ANNUAL_COLUMN_NAMES_BEFORE_FIX:
|
||||
note_dropped_annual_column(field)
|
||||
keys = [field for field in keys if field in FIELD_ZH]
|
||||
if not keys:
|
||||
continue
|
||||
@@ -2365,6 +2379,12 @@ def _append_parity_chapters(markdown: str, packet: dict, language: str) -> str:
|
||||
|
||||
def render_full_data_markdown(packet: dict) -> str:
|
||||
"""Upstream `pl9_ai_density` branch at 23be1807, on this site's parity body."""
|
||||
if _pl9_report_language(packet if isinstance(packet, dict) else {}) != "en":
|
||||
try:
|
||||
from scripts.report_render.appendix_language import reset_appendix_drop_log
|
||||
except ModuleNotFoundError: # pragma: no cover
|
||||
from report_render.appendix_language import reset_appendix_drop_log
|
||||
reset_appendix_drop_log()
|
||||
attach_full_data_interpretation, opening_focus_block = _interpretation_tools()
|
||||
if isinstance(packet, dict):
|
||||
attach_full_data_interpretation(packet)
|
||||
@@ -2396,8 +2416,8 @@ def render_full_data_markdown(packet: dict) -> str:
|
||||
english_markdown,
|
||||
_pl9_english_report_title(packet),
|
||||
)
|
||||
rendered = _apply_local_report_conventions(rendered, language="en")
|
||||
return _append_parity_chapters(rendered, packet, "en")
|
||||
rendered = _append_parity_chapters(rendered, packet, "en")
|
||||
return _apply_local_report_conventions(rendered, language="en")
|
||||
zh_structured_appendix = re.sub(
|
||||
r"^#\s+.*?(?:\n{2,}|\n)",
|
||||
"",
|
||||
@@ -2418,8 +2438,8 @@ def render_full_data_markdown(packet: dict) -> str:
|
||||
+ "\n\n</details>\n"
|
||||
)
|
||||
rendered = _sanitize_pl9_ai_density_markdown(zh_markdown, _pl9_public_report_title(packet))
|
||||
rendered = _apply_local_report_conventions(rendered, language="zh")
|
||||
return _append_parity_chapters(rendered, packet, "zh")
|
||||
rendered = _append_parity_chapters(rendered, packet, "zh")
|
||||
return _apply_local_report_conventions(rendered, language="zh")
|
||||
|
||||
|
||||
def read_full_data_domain(packet: Mapping, domain: str) -> dict:
|
||||
|
||||
@@ -368,6 +368,63 @@ FIELD_ZH = {
|
||||
"months": "月数",
|
||||
}
|
||||
|
||||
# Names that already had a Chinese header before the #91 fix.
|
||||
# The annual-table filter used to drop every other column. Counts use this set
|
||||
# so a later Chinese name still shows up as a column the old filter removed.
|
||||
ANNUAL_COLUMN_NAMES_BEFORE_FIX = frozenset(FIELD_ZH)
|
||||
|
||||
_APPENDIX_DROPS: dict[str, dict[str, int]] = {
|
||||
"annual_columns": {},
|
||||
"annual_tables": {},
|
||||
"effects": {},
|
||||
"combinations_undetermined": {},
|
||||
"combinations_replaced": {},
|
||||
}
|
||||
|
||||
|
||||
def reset_appendix_drop_log() -> None:
|
||||
"""Clear the per-render drop counts. One Chinese render, then snapshot."""
|
||||
for bucket in _APPENDIX_DROPS.values():
|
||||
bucket.clear()
|
||||
|
||||
|
||||
def snapshot_appendix_drop_log() -> dict[str, dict[str, int]]:
|
||||
return {name: dict(bucket) for name, bucket in _APPENDIX_DROPS.items()}
|
||||
|
||||
|
||||
def note_dropped_annual_column(field: str) -> None:
|
||||
key = str(field)
|
||||
bucket = _APPENDIX_DROPS["annual_columns"]
|
||||
bucket[key] = bucket.get(key, 0) + 1
|
||||
|
||||
|
||||
def note_annual_table() -> None:
|
||||
bucket = _APPENDIX_DROPS["annual_tables"]
|
||||
bucket["seen"] = bucket.get("seen", 0) + 1
|
||||
|
||||
|
||||
def _drop_identity(item: dict, text: str) -> str:
|
||||
parts = [
|
||||
str(item.get("rule_id") or ""),
|
||||
str(item.get("source") or ""),
|
||||
str(item.get("bvr_id") or ""),
|
||||
str(item.get("name") or ""),
|
||||
" ".join(str(text).split()),
|
||||
]
|
||||
return " | ".join(parts)[:240]
|
||||
|
||||
|
||||
def _note_effect(item: dict, text: str) -> None:
|
||||
key = _drop_identity(item, text)
|
||||
bucket = _APPENDIX_DROPS["effects"]
|
||||
bucket[key] = bucket.get(key, 0) + 1
|
||||
|
||||
|
||||
def _note_combination(item: dict, text: str, kind: str) -> None:
|
||||
key = _drop_identity(item, text)
|
||||
bucket = _APPENDIX_DROPS[kind]
|
||||
bucket[key] = bucket.get(key, 0) + 1
|
||||
|
||||
|
||||
def column_header(field: str, language: str) -> str:
|
||||
if language != "zh":
|
||||
@@ -591,12 +648,19 @@ def chinese_yoga_label(item: dict) -> str:
|
||||
def chinese_combination(item: dict) -> str:
|
||||
"""Use the Chinese combination sentence. An English sentence is not translated word by word."""
|
||||
combination = str(item.get("combination") or "").strip()
|
||||
if combination and re.search(r"[\u4e00-\u9fff]", combination) and not _HAN_FUNCTION_RE.search(combination) and not SIGN_EN_RE.search(combination):
|
||||
han = bool(re.search(r"[\u4e00-\u9fff]", combination))
|
||||
function = bool(_HAN_FUNCTION_RE.search(combination)) if combination else False
|
||||
sign = bool(SIGN_EN_RE.search(combination)) if combination else False
|
||||
if combination and han and not function and not sign:
|
||||
return combination
|
||||
planets = item.get("planets") if isinstance(item.get("planets"), list) else []
|
||||
names = [planet_name(planet, "zh") for planet in planets if planet]
|
||||
if names:
|
||||
if combination:
|
||||
_note_combination(item, combination, "combinations_replaced")
|
||||
return "与".join(names)
|
||||
if combination:
|
||||
_note_combination(item, combination, "combinations_undetermined")
|
||||
return "未判定"
|
||||
|
||||
|
||||
@@ -610,7 +674,15 @@ def yoga_cells(item: dict, language: str) -> list[Any]:
|
||||
category_text = "未判定"
|
||||
strength = item.get("strength") or "-"
|
||||
effects = item.get("effects") if isinstance(item.get("effects"), list) else []
|
||||
kept = [str(effect) for effect in effects if str(effect).strip() and not _has_prose_glue(str(effect))]
|
||||
kept = []
|
||||
for effect in effects:
|
||||
text = str(effect).strip()
|
||||
if not text:
|
||||
continue
|
||||
if _has_prose_glue(text):
|
||||
_note_effect(item, text)
|
||||
continue
|
||||
kept.append(text)
|
||||
effects_text = ";".join(kept) or "-"
|
||||
return [chinese_yoga_label(item), category_text, strength, chinese_combination(item), effects_text]
|
||||
|
||||
|
||||
@@ -470,6 +470,84 @@ def _rows_from(items: list[Any], language: str, columns: list[tuple[str, str]])
|
||||
return _md_table(headers, rows)
|
||||
|
||||
|
||||
_PLANETS = ("Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn", "Rahu", "Ketu")
|
||||
_MISSING_MODULE = {
|
||||
"zh": "公开报告资料包未带此模块",
|
||||
"en": "This module is not in the public report packet",
|
||||
}
|
||||
|
||||
|
||||
def _missing_module(language: str, columns: list[str]) -> str:
|
||||
"""The public worksheet does not carry this module. Keep the undetermined row."""
|
||||
return _MISSING_MODULE[language] + "\n\n" + _blank(language, columns)
|
||||
|
||||
|
||||
def _is_planet(value: Any) -> bool:
|
||||
return isinstance(value, str) and value.strip() in _PLANETS
|
||||
|
||||
|
||||
def _dignity_token(value: Any, language: str) -> Any:
|
||||
if not isinstance(value, str):
|
||||
return value
|
||||
key = " ".join(value.strip().split()).lower()
|
||||
if key == "neutral":
|
||||
return "中性" if language == "zh" else "Neutral"
|
||||
return {
|
||||
"exalted": "exalted",
|
||||
"debilitated": "debilitated",
|
||||
"own sign": "own",
|
||||
"own": "own",
|
||||
"moolatrikona": "mooltrikona",
|
||||
}.get(key, value)
|
||||
|
||||
|
||||
def _named_planets(chart: Any) -> list[tuple[str, dict]]:
|
||||
if not isinstance(chart, dict):
|
||||
return []
|
||||
nested = chart.get("planets")
|
||||
source = nested if isinstance(nested, dict) else chart
|
||||
rows = []
|
||||
for name in _PLANETS:
|
||||
item = source.get(name)
|
||||
if isinstance(item, dict):
|
||||
rows.append((name, item))
|
||||
return rows
|
||||
|
||||
|
||||
def _varga_chart(packet: dict, *keys: str) -> dict:
|
||||
varga = _first(packet, ("divisional_and_special_charts", "varga_full")) or {}
|
||||
if not isinstance(varga, dict):
|
||||
return {}
|
||||
for key in keys:
|
||||
chart = varga.get(key)
|
||||
if isinstance(chart, dict):
|
||||
return chart
|
||||
return {}
|
||||
|
||||
|
||||
def _varga_label(name: str, chart: dict) -> str:
|
||||
meta = chart.get("_meta") if isinstance(chart.get("_meta"), dict) else {}
|
||||
div = meta.get("div")
|
||||
title = str(meta.get("name") or "")
|
||||
if div and title and "_" not in title and not re.search(r"[\u4e00-\u9fff]", title):
|
||||
return f"D{div} {title}".strip()
|
||||
return " ".join(str(name).replace("_", " ").split())
|
||||
|
||||
|
||||
def _cycle_label(value: str, language: str) -> str | None:
|
||||
body = value.split(":", 1)[1]
|
||||
parts = [part.strip(" .") for part in body.replace("->", "|").replace("→", "|").split("|")]
|
||||
names = []
|
||||
for part in parts:
|
||||
if not _is_planet(part):
|
||||
return None
|
||||
names.append(planet_name(part, language))
|
||||
if len(names) < 2:
|
||||
return None
|
||||
prefix = "循环" if language == "zh" else "Cycle"
|
||||
return prefix + " " + " → ".join(names)
|
||||
|
||||
|
||||
def _months(start: Any, end: Any) -> str | None:
|
||||
if not isinstance(start, str) or not isinstance(end, str):
|
||||
return None
|
||||
@@ -560,25 +638,8 @@ def _tribhagi_periods(packet: dict, language: str) -> str:
|
||||
|
||||
|
||||
def _navamsha(packet: dict, language: str) -> str:
|
||||
module = _first(packet, ("timing_and_predictive_systems", "navamsha_dasha"))
|
||||
periods = []
|
||||
if isinstance(module, dict):
|
||||
majors = module.get("periods") or module.get("native_result", {}).get("periods") if isinstance(module.get("native_result"), dict) else module.get("periods")
|
||||
if isinstance(module.get("native_result"), dict):
|
||||
majors = module["native_result"].get("periods") or majors
|
||||
for major in majors or []:
|
||||
if not isinstance(major, dict):
|
||||
continue
|
||||
for child in major.get("antardasha") or []:
|
||||
if not isinstance(child, dict):
|
||||
continue
|
||||
copied = dict(child)
|
||||
copied["months"] = child.get("duration_months") or _months(child.get("start"), child.get("end"))
|
||||
periods.append(copied)
|
||||
if not periods:
|
||||
note = "公开报告包没有带上 Navamsha 小运行。" if language == "zh" else "The public packet does not carry the Navamsha sub-period rows."
|
||||
return note + "\n\n" + _blank(language, ["sign", "start", "end", "months"])
|
||||
return _rows_from(periods, language, [("sign", "sign"), ("start", "text"), ("end", "text"), ("months", "text")])
|
||||
del packet
|
||||
return _missing_module(language, ["sign", "start", "end", "months"])
|
||||
|
||||
|
||||
def _nakshatra_context(packet: dict, language: str) -> str:
|
||||
@@ -675,31 +736,8 @@ def _sandhi(packet: dict, language: str) -> str:
|
||||
|
||||
|
||||
def _convergence(packet: dict, language: str) -> str:
|
||||
timing = _first(packet, ("ai_and_audit", "ai_prompt_pack", "evidence_snapshot", "timing")) or {}
|
||||
pairs = timing.get("convergence_top_domains") if isinstance(timing, dict) else None
|
||||
module = _first(packet, ("timing_and_predictive_systems", "dasa_convergence"))
|
||||
activations = module.get("domain_activations") if isinstance(module, dict) else None
|
||||
rows = []
|
||||
if isinstance(activations, dict) and activations:
|
||||
for domain, info in activations.items():
|
||||
if not isinstance(info, dict):
|
||||
continue
|
||||
rows.append({
|
||||
"domain": domain,
|
||||
"house": info.get("house"),
|
||||
"level": info.get("convergence_level"),
|
||||
"counted": info.get("system_count"),
|
||||
})
|
||||
elif isinstance(pairs, list):
|
||||
for item in pairs:
|
||||
if isinstance(item, (list, tuple)) and len(item) >= 2:
|
||||
rows.append({"domain": item[0], "level": item[1]})
|
||||
elif isinstance(item, dict):
|
||||
rows.append({"domain": item.get("domain") or item.get("name"), "level": item.get("level") or item.get("convergence_level")})
|
||||
if not rows:
|
||||
note = "公开报告包没有带上逐领域激活行。" if language == "zh" else "The public packet does not carry the per-domain activation rows."
|
||||
return note + "\n\n" + _blank(language, ["domain", "level"])
|
||||
return _rows_from(rows, language, [("domain", "text"), ("house", "text"), ("level", "text"), ("counted", "text")])
|
||||
del packet
|
||||
return _missing_module(language, ["domain", "level"])
|
||||
|
||||
|
||||
def _chara(packet: dict, language: str) -> str:
|
||||
@@ -890,12 +928,30 @@ def _bhava(packet: dict, language: str) -> str:
|
||||
|
||||
def _vimsopaka(packet: dict, language: str) -> str:
|
||||
module = _first(packet, ("strengths_and_scores", "vimsopaka")) or {}
|
||||
nested = module.get("planets") if isinstance(module, dict) else None
|
||||
planets = nested if isinstance(nested, dict) else module
|
||||
bands = {
|
||||
"High": ("High", "高"),
|
||||
"Moderate": ("Moderate", "中"),
|
||||
"Limited": ("Limited", "有限"),
|
||||
"Low": ("Low", "低"),
|
||||
}
|
||||
rows = []
|
||||
planets = module.get("planets") if isinstance(module, dict) else module
|
||||
if isinstance(planets, dict):
|
||||
for planet, item in planets.items():
|
||||
if isinstance(item, dict) and ("total_score" in item or "category" in item):
|
||||
rows.append({"planet": planet, "score": item.get("total_score"), "category": item.get("category")})
|
||||
if not isinstance(item, dict) or ("total_score" not in item and "category" not in item):
|
||||
continue
|
||||
if planet not in _PLANETS and item.get("planet") not in _PLANETS:
|
||||
continue
|
||||
category = item.get("category")
|
||||
pair = bands.get(str(category))
|
||||
if pair:
|
||||
category = pair[1] if language == "zh" else pair[0]
|
||||
rows.append({
|
||||
"planet": planet if planet in _PLANETS else item.get("planet"),
|
||||
"score": item.get("total_score"),
|
||||
"category": category,
|
||||
})
|
||||
elif isinstance(planets, list):
|
||||
rows = [item for item in planets if isinstance(item, dict)]
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("score", "text"), ("category", "text")])
|
||||
@@ -958,33 +1014,61 @@ def _prastara(packet: dict, language: str) -> str:
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("total", "text")])
|
||||
|
||||
|
||||
def _avastha_state(item: dict) -> Any:
|
||||
states = item.get("avasthas") if isinstance(item.get("avasthas"), dict) else {}
|
||||
for key in ("Jagrat", "Deeptadi"):
|
||||
entry = states.get(key)
|
||||
if isinstance(entry, dict) and entry.get("state"):
|
||||
return entry.get("state")
|
||||
return item.get("jagradadi") or item.get("state") or item.get("avastha")
|
||||
|
||||
|
||||
def _avastha(packet: dict, language: str) -> str:
|
||||
module = _first(packet, ("advanced_systems", "avasthas")) or {}
|
||||
nested = module.get("planets") if isinstance(module, dict) else None
|
||||
planets = nested if isinstance(nested, dict) else module if isinstance(module, dict) else {}
|
||||
rows = []
|
||||
planets = module.get("planets") if isinstance(module, dict) else module
|
||||
if isinstance(planets, dict):
|
||||
for planet, item in planets.items():
|
||||
if isinstance(item, dict):
|
||||
rows.append({"planet": planet, "status": item.get("jagradadi") or item.get("state") or item.get("avastha"), "degree": item.get("degree") or item.get("degree_in_sign")})
|
||||
elif isinstance(planets, list):
|
||||
rows = [item for item in planets if isinstance(item, dict)]
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("status", "text"), ("degree", "text")])
|
||||
for planet, item in planets.items():
|
||||
if planet not in _PLANETS or not isinstance(item, dict):
|
||||
continue
|
||||
degree = item.get("degree")
|
||||
if degree is None:
|
||||
degree = item.get("degree_in_sign")
|
||||
rows.append({
|
||||
"planet": planet,
|
||||
"sign": item.get("sign"),
|
||||
"status": _avastha_state(item),
|
||||
"degree": degree,
|
||||
})
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("sign", "sign"), ("status", "text"), ("degree", "text")])
|
||||
|
||||
|
||||
def _d30(packet: dict, language: str, source: bool) -> str:
|
||||
module = _first(packet, ("advanced_systems", "trimshamsa_d30")) or _first(packet, ("divisional_and_special_charts", "varga_full", "D30"))
|
||||
rows = []
|
||||
planets = module.get("planets") if isinstance(module, dict) else None
|
||||
if isinstance(planets, dict):
|
||||
for planet, item in planets.items():
|
||||
if not isinstance(item, dict):
|
||||
if source:
|
||||
rows = []
|
||||
for planet, item in _shadbala_planets(packet).items():
|
||||
if planet not in _PLANETS or not isinstance(item, dict):
|
||||
continue
|
||||
if source:
|
||||
rows.append({"planet": planet, "degree": item.get("degree_in_sign") or item.get("degree"), "sign": item.get("sign")})
|
||||
else:
|
||||
rows.append({"planet": planet, "sign": item.get("sign"), "status": item.get("dignity") or item.get("status")})
|
||||
columns = [("planet", "planet"), ("degree", "text"), ("sign", "sign")] if source else [("planet", "planet"), ("sign", "sign"), ("status", "text")]
|
||||
return _rows_from(rows, language, columns)
|
||||
sthana = item.get("sthana_bala") if isinstance(item.get("sthana_bala"), dict) else {}
|
||||
score = sthana.get("sapta_d30")
|
||||
if isinstance(score, bool) or not isinstance(score, (int, float)):
|
||||
continue
|
||||
rows.append({"planet": planet, "score": score})
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("score", "text")])
|
||||
chart = _varga_chart(packet, "D30_Trimsamsa", "D30", "Trimsamsa")
|
||||
if not chart:
|
||||
legacy = _first(packet, ("advanced_systems", "trimshamsa_d30"))
|
||||
chart = legacy if isinstance(legacy, dict) else {}
|
||||
dignity = chart.get("_dignity") if isinstance(chart.get("_dignity"), dict) else {}
|
||||
rows = []
|
||||
for planet, item in _named_planets(chart):
|
||||
status = dignity.get(planet) or item.get("dignity") or item.get("status")
|
||||
rows.append({
|
||||
"planet": planet,
|
||||
"sign": item.get("sign"),
|
||||
"status": _dignity_token(status, language),
|
||||
})
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("sign", "sign"), ("status", "text")])
|
||||
|
||||
|
||||
def _pushkara(packet: dict, language: str) -> str:
|
||||
@@ -1112,8 +1196,26 @@ def _chain_rows(module: Any, terminal: bool) -> list[dict]:
|
||||
|
||||
|
||||
def _dispositor(packet: dict, language: str, terminal: bool) -> str:
|
||||
module = _first(packet, ("advanced_systems", "final_dispositors" if terminal else "dispositor_chains"))
|
||||
return _rows_from(_chain_rows(module, terminal), language, [("planet", "planet"), ("sign", "sign"), ("lord", "planet")])
|
||||
if not terminal:
|
||||
module = _first(packet, ("advanced_systems", "dispositor_chains"))
|
||||
return _rows_from(_chain_rows(module, False), language, [("planet", "planet"), ("sign", "sign"), ("lord", "planet")])
|
||||
module = _first(packet, ("advanced_systems", "final_dispositors")) or {}
|
||||
rows = []
|
||||
if isinstance(module, dict):
|
||||
for planet, value in module.items():
|
||||
if planet not in _PLANETS:
|
||||
continue
|
||||
if _is_planet(value):
|
||||
rows.append({"planet": planet, "lord": value})
|
||||
elif isinstance(value, str) and value.startswith("Cycle:"):
|
||||
label = _cycle_label(value, language)
|
||||
if label:
|
||||
rows.append({"planet": planet, "value": label})
|
||||
elif isinstance(value, (dict, list)):
|
||||
rows.extend(_chain_rows({planet: value}, True))
|
||||
if not rows:
|
||||
rows = _chain_rows(module, True)
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("sign", "sign"), ("lord", "planet"), ("value", "text")])
|
||||
|
||||
|
||||
def _aspects(packet: dict, language: str) -> str:
|
||||
@@ -1290,14 +1392,18 @@ def _saham_basis(packet: dict, language: str) -> str:
|
||||
for name, item in module.items():
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
if "formula_status" not in item and "formula_variant" not in item and "formula_operands" not in item:
|
||||
if item.get("sign") in (None, "") and not isinstance(item.get("longitude"), (int, float)):
|
||||
continue
|
||||
label = item.get("name")
|
||||
if not isinstance(label, str) or "_" in label or not label.strip():
|
||||
label = " ".join(str(name).replace("_", " ").split())
|
||||
rows.append({
|
||||
"name": name,
|
||||
"status": item.get("formula_status") or item.get("formula_variant"),
|
||||
"value": item.get("base_longitude_before_exception") or item.get("longitude"),
|
||||
"name": label,
|
||||
"sign": item.get("sign"),
|
||||
"degree": item.get("degree_in_sign"),
|
||||
"longitude": item.get("longitude"),
|
||||
})
|
||||
return _rows_from(rows, language, [("name", "text"), ("status", "text"), ("value", "text")])
|
||||
return _rows_from(rows, language, [("name", "text"), ("sign", "sign"), ("degree", "text"), ("longitude", "text")])
|
||||
|
||||
|
||||
def _special_points(packet: dict, language: str) -> str:
|
||||
@@ -1361,31 +1467,30 @@ def _one_point(packet: dict, language: str, key: str) -> str:
|
||||
item = jaimini.get(key) if isinstance(jaimini, dict) else None
|
||||
if isinstance(item, str):
|
||||
return _rows_from([{"planet": item}], language, [("planet", "planet")])
|
||||
if isinstance(item, dict):
|
||||
return _rows_from([item], language, [("planet", "planet"), ("sign", "sign"), ("house", "text")])
|
||||
return _blank(language, ["planet", "sign"])
|
||||
if not isinstance(item, dict):
|
||||
return _blank(language, ["planet", "sign"])
|
||||
if key == "karakamsha":
|
||||
return _rows_from([{
|
||||
"sign": item.get("karakamsha_sign") or item.get("sign"),
|
||||
"degree": item.get("karakamsha_degree") if "karakamsha_degree" in item else item.get("degree"),
|
||||
"lord": item.get("karakamsha_lord") or item.get("lord") or item.get("planet"),
|
||||
"house": item.get("house"),
|
||||
}], language, [("sign", "sign"), ("degree", "text"), ("lord", "planet"), ("house", "text")])
|
||||
if key == "darakaraka":
|
||||
return _rows_from([{
|
||||
"planet": item.get("dk_planet") or item.get("planet"),
|
||||
"sign": item.get("dk_sign") or item.get("sign"),
|
||||
"house": item.get("dk_house") if item.get("dk_house") is not None else item.get("house"),
|
||||
"degree": item.get("dk_degree") if item.get("dk_degree") is not None else item.get("degree"),
|
||||
"value": item.get("d9_sign"),
|
||||
"dignity": _dignity_token(item.get("d9_dignity") or item.get("dignity"), language),
|
||||
}], language, [("planet", "planet"), ("sign", "sign"), ("house", "text"), ("degree", "text"), ("value", "sign"), ("dignity", "text")])
|
||||
return _rows_from([item], language, [("planet", "planet"), ("sign", "sign"), ("house", "text")])
|
||||
|
||||
|
||||
def _rashi_tulya(packet: dict, language: str) -> str:
|
||||
module = _first(packet, ("advanced_systems", "rashi_tulya_navamsa")) or {}
|
||||
analysis = module.get("analysis") if isinstance(module, dict) else module
|
||||
if not isinstance(analysis, dict):
|
||||
return _blank(language, ["name", "value"])
|
||||
labels = {
|
||||
"lagna_sign": "上升星座" if language == "zh" else "Ascendant sign",
|
||||
"strength_score": "力量分" if language == "zh" else "Strength score",
|
||||
"weakness_score": "薄弱分" if language == "zh" else "Weakness score",
|
||||
}
|
||||
rows = []
|
||||
for key, label in labels.items():
|
||||
if key in analysis:
|
||||
rows.append({"name": label, "value": analysis.get(key)})
|
||||
planets = analysis.get("planets")
|
||||
if isinstance(planets, dict):
|
||||
for planet, item in planets.items():
|
||||
sign = item.get("sign") if isinstance(item, dict) else item
|
||||
rows.append({"name": planet, "value": sign})
|
||||
return _rows_from(rows, language, [("name", "text"), ("value", "text")])
|
||||
del packet
|
||||
return _missing_module(language, ["name", "value"])
|
||||
|
||||
|
||||
def _moon(packet: dict, language: str) -> str:
|
||||
@@ -1403,7 +1508,10 @@ def _moon(packet: dict, language: str) -> str:
|
||||
|
||||
def _sudarshana(packet: dict, language: str) -> str:
|
||||
module = _first(packet, ("divisional_and_special_charts", "sudarshana")) or {}
|
||||
points = module.get("reference_points") if isinstance(module, dict) else {}
|
||||
raw = module.get("raw") if isinstance(module, dict) and isinstance(module.get("raw"), dict) else {}
|
||||
points = raw.get("reference_points") if isinstance(raw.get("reference_points"), dict) else None
|
||||
if not isinstance(points, dict) and isinstance(module, dict):
|
||||
points = module.get("reference_points")
|
||||
rows = []
|
||||
labels = {
|
||||
"ascendant_lagna": ("Ascendant reference", "出生上升参考点"),
|
||||
@@ -1419,16 +1527,37 @@ def _sudarshana(packet: dict, language: str) -> str:
|
||||
|
||||
|
||||
def _transit(packet: dict, language: str) -> str:
|
||||
module = _first(packet, ("timing_and_predictive_systems", "transit_positions")) or _first(packet, ("advanced_systems", "transit_positions"))
|
||||
if not isinstance(module, dict):
|
||||
module = {}
|
||||
planets = module.get("planets") or module.get("positions") or module
|
||||
multi = _first(packet, ("timing_and_predictive_systems", "transit_multi_reference")) or {}
|
||||
analysis = multi.get("transit_analysis") if isinstance(multi, dict) else {}
|
||||
when = multi.get("target_date") if isinstance(multi, dict) else None
|
||||
overlay_root = _first(packet, ("advanced_systems", "nakshatra_dasha")) or {}
|
||||
overlay = overlay_root.get("transit_overlay") if isinstance(overlay_root, dict) else {}
|
||||
if not isinstance(analysis, dict):
|
||||
analysis = {}
|
||||
if not isinstance(overlay, dict):
|
||||
overlay = {}
|
||||
order = [planet for planet in (*analysis.keys(), *overlay.keys()) if planet in _PLANETS]
|
||||
seen = []
|
||||
for planet in order:
|
||||
if planet not in seen:
|
||||
seen.append(planet)
|
||||
rows = []
|
||||
if isinstance(planets, dict):
|
||||
for planet, item in planets.items():
|
||||
if isinstance(item, dict):
|
||||
rows.append({"planet": planet, "sign": item.get("sign"), "date": item.get("date") or module.get("date")})
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("sign", "sign"), ("date", "text")])
|
||||
for planet in seen:
|
||||
item = analysis.get(planet) if isinstance(analysis.get(planet), dict) else {}
|
||||
over = overlay.get(planet) if isinstance(overlay.get(planet), dict) else {}
|
||||
nakshatra = over.get("transit_nakshatra")
|
||||
if isinstance(nakshatra, str) and "_" in nakshatra:
|
||||
nakshatra = nakshatra.replace("_", " ")
|
||||
if not isinstance(nakshatra, str):
|
||||
nakshatra = None
|
||||
rows.append({
|
||||
"planet": planet,
|
||||
"sign": item.get("sign"),
|
||||
"degree": item.get("degree_in_sign"),
|
||||
"date": when if isinstance(when, (str, int, float)) else item.get("date"),
|
||||
"nakshatra": nakshatra,
|
||||
})
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("sign", "sign"), ("degree", "text"), ("date", "text"), ("nakshatra", "text")])
|
||||
|
||||
|
||||
def _multi_transit(packet: dict, language: str) -> str:
|
||||
@@ -1465,19 +1594,15 @@ def _kp(packet: dict, language: str) -> str:
|
||||
|
||||
|
||||
def _d9(packet: dict, language: str) -> str:
|
||||
varga = _first(packet, ("divisional_and_special_charts", "varga_full")) or {}
|
||||
chart = None
|
||||
if isinstance(varga, dict):
|
||||
for key in ("D9", "d9", "Navamsa", "navamsa"):
|
||||
if isinstance(varga.get(key), dict):
|
||||
chart = varga[key]
|
||||
break
|
||||
planets = chart.get("planets") if isinstance(chart, dict) else None
|
||||
chart = _varga_chart(packet, "D9_Navamsa", "D9", "d9", "Navamsa", "navamsa")
|
||||
dignity = chart.get("_dignity") if isinstance(chart.get("_dignity"), dict) else {}
|
||||
rows = []
|
||||
if isinstance(planets, dict):
|
||||
for planet, item in planets.items():
|
||||
if isinstance(item, dict):
|
||||
rows.append({"planet": planet, "sign": item.get("sign"), "dignity": item.get("dignity") or item.get("status")})
|
||||
for planet, item in _named_planets(chart):
|
||||
rows.append({
|
||||
"planet": planet,
|
||||
"sign": item.get("sign"),
|
||||
"dignity": _dignity_token(dignity.get(planet) or item.get("dignity") or item.get("status"), language),
|
||||
})
|
||||
return _rows_from(rows, language, [("planet", "planet"), ("sign", "sign"), ("dignity", "text")])
|
||||
|
||||
|
||||
@@ -1486,13 +1611,19 @@ def _mapping(packet: dict, language: str) -> str:
|
||||
rows = []
|
||||
if isinstance(varga, dict):
|
||||
for name, chart in varga.items():
|
||||
if not isinstance(chart, dict):
|
||||
continue
|
||||
if any(token in str(name).upper() for token in ("D81", "D108", "D144")):
|
||||
continue
|
||||
sign = None
|
||||
if isinstance(chart, dict):
|
||||
asc = chart.get("ascendant") if isinstance(chart.get("ascendant"), dict) else {}
|
||||
sign = asc.get("sign") or chart.get("asc_sign") or chart.get("lagna_sign")
|
||||
rows.append({"name": name, "sign": sign})
|
||||
asc = chart.get("Ascendant") if isinstance(chart.get("Ascendant"), dict) else {}
|
||||
if not asc and isinstance(chart.get("ascendant"), dict):
|
||||
asc = chart.get("ascendant") or {}
|
||||
sign = asc.get("sign") or chart.get("asc_sign") or chart.get("lagna_sign")
|
||||
if sign in (None, "") and isinstance(asc.get("sign_idx"), int):
|
||||
sign = asc.get("sign_idx")
|
||||
if sign in (None, ""):
|
||||
continue
|
||||
rows.append({"name": _varga_label(str(name), chart), "sign": sign})
|
||||
return _rows_from(rows, language, [("name", "text"), ("sign", "sign")])
|
||||
|
||||
|
||||
@@ -1515,7 +1646,9 @@ def _chalit_planets(packet: dict, language: str) -> str:
|
||||
def _chalit_centres(packet: dict, language: str) -> str:
|
||||
raw = _bhava_raw(packet)
|
||||
boundaries = raw.get("boundaries") if isinstance(raw.get("boundaries"), dict) else {}
|
||||
details = boundaries.get("houses_detail") if isinstance(boundaries, dict) else None
|
||||
details = boundaries.get("houses_detail") if isinstance(boundaries.get("houses_detail"), list) else None
|
||||
if not details:
|
||||
details = boundaries.get("houses") if isinstance(boundaries.get("houses"), list) else []
|
||||
rows = []
|
||||
for item in details or []:
|
||||
if isinstance(item, dict):
|
||||
@@ -1625,7 +1758,7 @@ def _render_named(packet: dict, language: str, title: str) -> str:
|
||||
"Tara-Chandra Matrix": lambda: _tara(packet, language),
|
||||
"Natal Tithi Lord": lambda: _tithi(packet, language),
|
||||
"Birth Calendar": lambda: _panchanga(packet, language),
|
||||
"Pancha Pakshi": lambda: _simple_module(packet, ("advanced_systems", "pancha_pakshi"), language, [("name", "text"), ("value", "text"), ("status", "text")]),
|
||||
"Pancha Pakshi": lambda: _missing_module(language, ["name", "value", "status"]),
|
||||
"Natal Vivah Saham": lambda: _vivah(packet, language),
|
||||
"Natal Saham Formula Basis": lambda: _saham_basis(packet, language),
|
||||
"Arudha / UL / A10": lambda: _special_points(packet, language),
|
||||
|
||||
Reference in New Issue
Block a user