Don't write rate-limit/error responses to disk in next_launch_api_data,
so they can't become the "most recent" cache file and cause KeyError crashes
in read_cached_launches. Add defensive results-list checks in
read_cached_launches and get_launches to handle any existing bad files.
Drop refresh=True from the updater's get_active_crewed_flights call so the
2-hour TTL applies; the paginated spacecraft/flight crawl was running on
every hourly cron job and likely causing the burst that triggered throttling.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show 8-day Bristol home weather on the index and weekends pages.
Show destination weather per day on the trip list and trip page.
Cache forecasts in ~/lib/data/weather/ and refresh via update.py.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In addition to the configured FOLLOW_LAUNCHES, also send emails for any
launch whose mission.type == "Test Flight" even if its slug is not in
FOLLOW_LAUNCHES.
Fixes#192.
Implements birthday reminder emails that are sent daily at 9 AM for birthdays
occurring within the next 7 days. Integrates with existing birthday.py module
and mail system to send notifications with appropriate timing-based subjects.
Fixes#171🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace technical YAML diff output with human-readable bullet points that clearly explain what changed. Added structured email format with mission details, rocket emoji, and formatted dates.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>