Files
sky-cam/test_last_full_moon.py
Claude a470879d1e simplify test_last_full_moon.py: delegate to run_phase() with no_upload
Removes the bypass of east-frame verification — the script now runs the
complete production pipeline (dark-window filtering, moon detection on
east frames, NASA Dial-a-Moon fetch, render_phase_closeup) by calling
mpm.run_phase() with no_upload=True and a fixed test output path.

Retains the explicit sun_events_in_range() call as a regression check
for the bare-topos fix before the main pipeline runs.

https://claude.ai/code/session_01JieSeNQZ3X6fhsb11YyJrK
2026-05-02 12:53:14 +00:00

60 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""test_last_full_moon.py — run the full moon pipeline for the most recent full moon.
Identical to `moon-phase-monthly.sh --phase full --no-upload` except the
output is written to test_last_full_moon_out.jpg in the sky-cam directory
instead of the normal movies tree.
Includes east-frame detection, dark-window filtering, NASA Dial-a-Moon
fetch, and render_phase_closeup — the complete production path.
Also calls sun_events_in_range() explicitly as a regression check for
the sunrise_sunset() bare-topos fix.
Run from the sky-cam directory:
python3 test_last_full_moon.py
"""
import sys
import pathlib
from datetime import datetime, timedelta, timezone
HERE = pathlib.Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
OUT_PATH = HERE / 'test_last_full_moon_out.jpg'
def main() -> int:
import moon_phase as mp
import moon_phase_monthly as mpm
# ── Regression check: sun_events_in_range() (bare-topos fix) ─────────────
now = datetime.now(timezone.utc)
candidates = mp.full_moons_in_range(now - timedelta(days=35), now)
if not candidates:
print("ERROR: no full moon found in the last 35 days", file=sys.stderr)
return 1
fm = candidates[-1]
day_start = fm.replace(hour=0, minute=0, second=0, microsecond=0)
events = mp.sun_events_in_range(day_start, day_start + timedelta(days=1))
print(f"sun events on {day_start.strftime('%Y-%m-%d')} UTC (topos fix check):")
for t, is_rise in events:
print(f" {'sunrise' if is_rise else 'sunset '} {t.strftime('%H:%M:%S')} UTC")
print()
# ── Full production pipeline ──────────────────────────────────────────────
return mpm.run_phase(
phase='full',
target_utc=fm,
cam=mpm.SUNRISE_CAM,
dry_run=False,
no_upload=True,
out_path=str(OUT_PATH),
)
if __name__ == "__main__":
sys.exit(main())