| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #!/usr/bin/env python3
- """
- Render test charts for two celebrities and save to /home/shared/.
- Usage:
- python3 render_test_charts.py [--format svg|png|jpg] [--size N]
- """
- import argparse
- import asyncio
- import json
- import sys
- import os
- # Ensure src is on the path
- sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
- from astro_mcp.tools import calculate_natal_chart, render_natal_chart
- # ── Birth data ───────────────────────────────────────────────────────
- PEOPLE = {
- "donald_trump": {
- "birth_datetime": "1946-06-14T11:00:00-04:00",
- "latitude": 40.70,
- "longitude": -73.80,
- "elevation": 10,
- },
- "chaka_khan": {
- "birth_datetime": "1953-03-23T11:00:00-06:00",
- "latitude": 41.88,
- "longitude": -87.63,
- "elevation": 180,
- },
- }
- async def render_person(name: str, birth_data: dict, fmt: str, size: int) -> dict:
- """Calculate and render a natal chart for one person.
- Returns a summary dict with moon info and output path.
- """
- # 1. Calculate chart data
- chart_data = await calculate_natal_chart(
- birth_datetime=birth_data["birth_datetime"],
- latitude=birth_data["latitude"],
- longitude=birth_data["longitude"],
- elevation=birth_data["elevation"],
- )
- if "error" in chart_data:
- print(f" ERROR calculating {name}: {chart_data['error']}")
- return None
- # 2. Render
- result = await render_natal_chart(
- birth_datetime=birth_data["birth_datetime"],
- latitude=birth_data["latitude"],
- longitude=birth_data["longitude"],
- elevation=birth_data["elevation"],
- color_mode="color",
- size=size,
- format=fmt,
- title=f"Natal Chart: {name.replace('_', ' ').title()}",
- )
- if "error" in result:
- print(f" ERROR rendering {name}: {result['error']}")
- return None
- # 3. Save
- ext = fmt
- filename = f"{name}_natal.{ext}"
- outdir = "/home/shared"
- os.makedirs(outdir, exist_ok=True)
- outpath = os.path.join(outdir, filename)
- content = result["content"]
- mode = "w" if isinstance(content, str) else "wb"
- with open(outpath, mode) as f:
- f.write(content)
- # 4. Extract moon info
- moon_info = None
- for p in chart_data.get("planets", []):
- if p.get("body") == "moon":
- moon_info = {
- "absolute_lon": p.get("absolute_lon"),
- "degree_within_sign": p.get("degree_within_sign"),
- "sign": p.get("sign"),
- "house": p.get("house"),
- "retrograde": p.get("retrograde"),
- }
- break
- return {
- "name": name,
- "output": outpath,
- "format": result["format"],
- "content_type": result["content_type"],
- "size_bytes": len(content) if isinstance(content, bytes) else len(content.encode("utf-8")),
- "moon": moon_info,
- "all_planets": [
- {"body": p.get("body"), "absolute_lon": p.get("absolute_lon"),
- "degree_within_sign": p.get("degree_within_sign"),
- "sign": p.get("sign"), "house": p.get("house"),
- "retrograde": p.get("retrograde")}
- for p in chart_data.get("planets", [])
- ],
- "houses_count": len(chart_data.get("houses", [])),
- "aspects_count": len(chart_data.get("aspects", [])),
- }
- async def main():
- parser = argparse.ArgumentParser(description="Render test natal charts")
- parser.add_argument("--format", default="svg", choices=["svg", "png", "jpg"],
- help="Output format (default: svg)")
- parser.add_argument("--size", type=int, default=600,
- help="Canvas size in pixels (default: 600)")
- parser.add_argument("--color-mode", default="color", choices=["color", "bw", "dark"],
- help="Color theme (default: color)")
- args = parser.parse_args()
- print(f"Rendering test charts — format={args.format}, size={args.size}px, theme={args.color_mode}")
- print(f"Output directory: /home/shared/")
- print()
- results = []
- for name, birth_data in PEOPLE.items():
- print(f"Processing {name.replace('_', ' ').title()}...")
- print(f" Birth: {birth_data['birth_datetime']} @ {birth_data['latitude']}, {birth_data['longitude']}")
- result = await render_person(name, birth_data, args.format, args.size)
- if result:
- results.append(result)
- print(f" Saved: {result['output']} ({result['size_bytes']:,} bytes)")
- if result["moon"]:
- m = result["moon"]
- print(f" MOON: {m['sign']} {m['degree_within_sign']:.1f}° (lon={m['absolute_lon']:.2f}°, house {m['house']})")
- else:
- print(f" MOON: not found in data!")
- print(f" Planets: {len(result['all_planets'])}, Houses: {result['houses_count']}, Aspects: {result['aspects_count']}")
- else:
- print(f" FAILED")
- print()
- # Summary comparison
- print("=" * 60)
- print("MOON COMPARISON")
- print("=" * 60)
- for r in results:
- m = r.get("moon", {})
- if m:
- print(f" {r['name']:20s} | Moon in {m.get('sign','?'):12s} {m.get('degree_within_sign',0):5.1f}° | House {m.get('house','?')} | Retrograde: {m.get('retrograde',False)}")
- else:
- print(f" {r['name']:20s} | Moon data MISSING")
- print()
- # Save JSON summary
- summary_path = "/home/shared/test_charts_summary.json"
- with open(summary_path, "w") as f:
- json.dump(results, f, indent=2, default=str)
- print(f"Summary saved to: {summary_path}")
- if __name__ == "__main__":
- asyncio.run(main())
|