fix(rectification): restore classic eight methods and observe KP Placidus cusps
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""Display-only Horary recast for birth-time rectification.
|
||||
|
||||
If the user gives the time they first asked the question, recast a natal-like
|
||||
chart at that local datetime. Never score it. Never block propose or confirm.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
from scripts.rectification.house_table import SIGNS_CN
|
||||
from scripts.rectification.kp_cusp_observation import observe_kp_cusps
|
||||
|
||||
_CLOCK = re.compile(r"(?:[01]?\d|2[0-3]):[0-5]\d")
|
||||
|
||||
|
||||
def _question_clock(event: dict[str, Any]) -> str:
|
||||
summary = str(event.get("summary") or "")
|
||||
match = _CLOCK.search(summary)
|
||||
if match:
|
||||
hour, minute = match.group(0).split(":")
|
||||
return f"{int(hour):02d}:{int(minute):02d}"
|
||||
return "12:00"
|
||||
|
||||
|
||||
def build_horary_observation(request: dict[str, Any]) -> dict[str, Any]:
|
||||
events = [
|
||||
event for event in (request.get("events") or [])
|
||||
if isinstance(event, dict) and event.get("event_kind") == "horary_query"
|
||||
]
|
||||
if not events:
|
||||
return {
|
||||
"status": "skipped",
|
||||
"user_meaning": "没有第一次问起这件事的时间,占问观察未执行。",
|
||||
"unique_minute_claim": False,
|
||||
}
|
||||
try:
|
||||
lat = float(request["lat"])
|
||||
lon = float(request["lon"])
|
||||
tz = float(request["tz"])
|
||||
except (KeyError, TypeError, ValueError):
|
||||
return {
|
||||
"status": "blocked",
|
||||
"user_meaning": "占问时间已记录,但观察盘未能重算。不计分,不挡提出门。",
|
||||
"unique_minute_claim": False,
|
||||
}
|
||||
event = events[0]
|
||||
date_text = str(event.get("date_start") or "")[:10]
|
||||
clock = _question_clock(event)
|
||||
try:
|
||||
year, month, day = (int(part) for part in date_text.split("-"))
|
||||
hour, minute = (int(part) for part in clock.split(":"))
|
||||
import domain_calculation_service
|
||||
chart = domain_calculation_service.compute_chart({
|
||||
"year": year,
|
||||
"month": month,
|
||||
"day": day,
|
||||
"hour": hour,
|
||||
"minute": minute,
|
||||
"lat": float(request["lat"]),
|
||||
"lon": float(request["lon"]),
|
||||
"tz": float(request["tz"]),
|
||||
"ayanamsa": "lahiri",
|
||||
"node_mode": "mean",
|
||||
})
|
||||
asc = chart.get("ascendant") or {}
|
||||
sign = str(asc.get("sign") or "")
|
||||
lagna = SIGNS_CN.get(sign, sign)
|
||||
birth_info = chart.get("birth_info") if isinstance(chart.get("birth_info"), dict) else {}
|
||||
kp = observe_kp_cusps(birth_info.get("julian_day"), float(request["lat"]), float(request["lon"]))
|
||||
angles = {}
|
||||
if kp.get("status") == "executed":
|
||||
for house in ("1", "4", "7", "10"):
|
||||
row = (kp.get("houses") or {}).get(house) or {}
|
||||
angles[house] = {
|
||||
"sub_lord": row.get("sub_lord"),
|
||||
"nakshatra_lord": row.get("nakshatra_lord"),
|
||||
}
|
||||
return {
|
||||
"status": "executed",
|
||||
"question_date": date_text,
|
||||
"question_time": clock,
|
||||
"lagna": lagna if lagna else None,
|
||||
"kp_angles": angles,
|
||||
"user_meaning": (
|
||||
f"已按问起时间 {date_text} {clock} 重算占问盘作观察,不计分,不确认唯一分钟。"
|
||||
),
|
||||
"unique_minute_claim": False,
|
||||
}
|
||||
except (TypeError, ValueError, KeyError, OverflowError, OSError):
|
||||
return {
|
||||
"status": "blocked",
|
||||
"question_date": date_text,
|
||||
"question_time": clock,
|
||||
"user_meaning": "占问时间已记录,但观察盘未能重算。不计分,不挡提出门。",
|
||||
"unique_minute_claim": False,
|
||||
}
|
||||
Reference in New Issue
Block a user