8010245981
Default ayanamsa to Raman with true_pushya support, attach governed Raman packets, restore Path C questionnaires and eight-method verification copy, and keep unique-minute confirmation blocked. Co-authored-by: Cursor <cursoragent@cursor.com>
171 lines
7.2 KiB
Python
171 lines
7.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Positive daily guidance built from auditable chart evidence."""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
import sys
|
|
from typing import Any
|
|
|
|
SCRIPT_DIR = Path(__file__).resolve().parent
|
|
if str(SCRIPT_DIR) not in sys.path:
|
|
sys.path.insert(0, str(SCRIPT_DIR))
|
|
|
|
try:
|
|
import swisseph as swe
|
|
from ayanamsa_utils import apply_ayanamsa, normalize_ayanamsa_name
|
|
from domain_calculation_service import compute_chart, compute_vimshottari_timeline
|
|
except ModuleNotFoundError:
|
|
import swisseph as swe
|
|
from scripts.ayanamsa_utils import apply_ayanamsa, normalize_ayanamsa_name
|
|
from scripts.domain_calculation_service import compute_chart, compute_vimshottari_timeline
|
|
|
|
SIGNS = [
|
|
"Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
|
|
"Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces",
|
|
]
|
|
|
|
HOUSE_THEMES = {
|
|
1: ("自我", "整理状态、重启节奏"),
|
|
2: ("财务", "记账、定价、整理资源"),
|
|
3: ("沟通", "发消息、写计划、更新作品"),
|
|
4: ("家庭", "整理空间、处理家宅事务"),
|
|
5: ("创意", "创作、表达、轻松社交"),
|
|
6: ("执行", "清单推进、修正细节"),
|
|
7: ("合作", "谈合作、修复关系、主动连接"),
|
|
8: ("深度", "复盘、研究、清理旧问题"),
|
|
9: ("学习", "学习、发布观点、远程联络"),
|
|
10: ("事业", "推进项目、展示成果、联系上级"),
|
|
11: ("人脉", "社群互动、资源交换"),
|
|
12: ("休整", "休息、收尾、安静准备"),
|
|
}
|
|
|
|
|
|
def _safe_int(value: Any, default: int = 0) -> int:
|
|
try:
|
|
return int(value)
|
|
except (TypeError, ValueError):
|
|
return default
|
|
|
|
|
|
def _house_from_sign(asc_sign: str | None, transit_sign: str | None) -> int | None:
|
|
if asc_sign not in SIGNS or transit_sign not in SIGNS:
|
|
return None
|
|
return (SIGNS.index(transit_sign) - SIGNS.index(asc_sign)) % 12 + 1
|
|
|
|
|
|
def _chart_from_body(body: dict[str, Any]) -> dict[str, Any]:
|
|
chart = body.get("chart_data") or body.get("chart")
|
|
if isinstance(chart, dict) and chart.get("ascendant") and chart.get("planets"):
|
|
return chart
|
|
return compute_chart(body)
|
|
|
|
|
|
def _moon_transit(reference_date: str, tz: float, ayanamsa: str) -> dict[str, Any]:
|
|
local_dt = datetime.strptime(reference_date[:10], "%Y-%m-%d").replace(hour=12)
|
|
apply_ayanamsa(normalize_ayanamsa_name(ayanamsa), swe)
|
|
jd = swe.julday(local_dt.year, local_dt.month, local_dt.day, 12.0 - float(tz))
|
|
ayanamsa_value = swe.get_ayanamsa(jd)
|
|
position, _flags = swe.calc_ut(jd, swe.MOON)
|
|
longitude = (position[0] - ayanamsa_value) % 360
|
|
sign_index = int(longitude // 30)
|
|
return {
|
|
"planet": "Moon",
|
|
"date": reference_date,
|
|
"longitude": longitude,
|
|
"sign": SIGNS[sign_index],
|
|
"degree_in_sign": longitude % 30,
|
|
}
|
|
|
|
|
|
def _current_mahadasha(chart: dict[str, Any], body: dict[str, Any], reference_date: str) -> str | None:
|
|
birth = chart.get("birth_info") or {}
|
|
moon = (chart.get("planets") or {}).get("Moon") or {}
|
|
moon_lon = moon.get("lon", moon.get("degree_raw", moon.get("degree")))
|
|
try:
|
|
birth_dt = datetime(
|
|
_safe_int(body.get("year"), _safe_int(birth.get("year"))),
|
|
_safe_int(body.get("month"), _safe_int(birth.get("month"), 1)),
|
|
_safe_int(body.get("day"), _safe_int(birth.get("day"), 1)),
|
|
_safe_int(body.get("hour"), _safe_int(birth.get("hour"))),
|
|
_safe_int(body.get("minute"), _safe_int(birth.get("minute"))),
|
|
_safe_int(body.get("second"), _safe_int(birth.get("second"))),
|
|
)
|
|
timeline = compute_vimshottari_timeline(
|
|
birth_dt=birth_dt,
|
|
moon_lon=float(moon_lon),
|
|
current_date=datetime.strptime(reference_date[:10], "%Y-%m-%d"),
|
|
)
|
|
except Exception:
|
|
return None
|
|
periods = timeline.get("periods") if isinstance(timeline, dict) else None
|
|
if isinstance(periods, list):
|
|
for period in periods:
|
|
if not isinstance(period, dict):
|
|
continue
|
|
start = str(period.get("start") or "")
|
|
end = str(period.get("end") or "")
|
|
lord = period.get("lord")
|
|
if start and end and start <= reference_date <= end and lord:
|
|
return str(lord)
|
|
balance = timeline.get("birth_balance") if isinstance(timeline, dict) else None
|
|
lord = balance.get("lord") if isinstance(balance, dict) else None
|
|
return str(lord) if lord else None
|
|
|
|
|
|
def build_daily_guidance(body: dict[str, Any]) -> dict[str, Any]:
|
|
reference_date = str(body.get("date") or body.get("reference_date") or datetime.now().strftime("%Y-%m-%d"))[:10]
|
|
chart = _chart_from_body(body)
|
|
birth = chart.get("birth_info") or {}
|
|
tz = float(body.get("tz", birth.get("tz", 0) or 0))
|
|
ayanamsa = normalize_ayanamsa_name(body.get("ayanamsa") or birth.get("ayanamsa_name"))
|
|
asc_sign = (chart.get("ascendant") or {}).get("sign")
|
|
moon_transit = _moon_transit(reference_date, tz, ayanamsa)
|
|
moon_house = _house_from_sign(asc_sign, moon_transit.get("sign"))
|
|
theme, action = HOUSE_THEMES.get(moon_house or 0, ("今日", "整理计划、稳步推进"))
|
|
dasha_lord = _current_mahadasha(chart, body, reference_date)
|
|
natal_moon = (chart.get("planets") or {}).get("Moon") or {}
|
|
natal_moon_sign = natal_moon.get("sign") if isinstance(natal_moon, dict) else None
|
|
evidence = [
|
|
{
|
|
"layer": "D1",
|
|
"finding": f"本命上升 {asc_sign or 'unknown'};今日月亮过境第{moon_house or '?'}宫",
|
|
"status": "used" if moon_house else "partial",
|
|
},
|
|
{
|
|
"layer": "Vimshottari",
|
|
"finding": f"当前大运主星 {dasha_lord}" if dasha_lord else "当前大运未能稳定提取",
|
|
"status": "used" if dasha_lord else "blocked",
|
|
},
|
|
{
|
|
"layer": "Daily Transit",
|
|
"finding": f"Moon in {moon_transit.get('sign')} on {reference_date}",
|
|
"status": "used",
|
|
},
|
|
]
|
|
text = f"今日星语:今日月亮触发你的{theme}主题,当前大运作背景支持把精力放在可推进的小事上。适合{action};好运来自清楚表达、稳步行动。"
|
|
if len(text) > 100:
|
|
text = f"今日星语:今日月亮触发{theme}主题,适合{action}。把话说清、把事做小,好运来自主动连接与稳步推进。"
|
|
return {
|
|
"success": True,
|
|
"endpoint": "daily_guidance",
|
|
"date": reference_date,
|
|
"theme": theme,
|
|
"theme_action": action,
|
|
"moon_house": moon_house,
|
|
"moon_sign": moon_transit.get("sign"),
|
|
"natal_moon_sign": natal_moon_sign,
|
|
"ascendant_sign": asc_sign,
|
|
"mahadasha_lord": dasha_lord,
|
|
"daily_star_words": text,
|
|
"word_count": len(text),
|
|
"suggested_actions": [item.strip() for item in action.split("、")],
|
|
"evidence": evidence,
|
|
"audit": {
|
|
"mode": "positive_daily_guidance",
|
|
"not_a_prediction": True,
|
|
"required_layers": ["D1", "Vimshottari", "Daily Transit"],
|
|
"partial_layers": ["D9", "D10", "D2", "Narayana", "Panchanga", "Ashtakavarga"],
|
|
},
|
|
}
|