Add OpenWeatherMap weather forecasts. Closes #48
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>
This commit is contained in:
parent
61e17d9c96
commit
b4f0a5bf5d
7 changed files with 217 additions and 0 deletions
37
update.py
37
update.py
|
|
@ -19,9 +19,11 @@ import agenda.geomob
|
|||
import agenda.gwr
|
||||
import agenda.mail
|
||||
import agenda.thespacedevs
|
||||
import agenda.trip
|
||||
import agenda.types
|
||||
import agenda.uk_holiday
|
||||
import agenda.uk_school_holiday
|
||||
import agenda.weather
|
||||
from agenda.event import Event
|
||||
from agenda.types import StrDict
|
||||
from web_view import app
|
||||
|
|
@ -406,6 +408,40 @@ def update_gandi(config: flask.config.Config) -> None:
|
|||
out.write(r.text)
|
||||
|
||||
|
||||
def update_weather(config: flask.config.Config) -> None:
|
||||
"""Refresh weather cache for all upcoming trips."""
|
||||
from datetime import date, timedelta
|
||||
|
||||
today = date.today()
|
||||
forecast_window = today + timedelta(days=8)
|
||||
|
||||
trips = agenda.trip.build_trip_list()
|
||||
upcoming = [
|
||||
t
|
||||
for t in trips
|
||||
if (t.end or t.start) >= today and t.start <= forecast_window
|
||||
]
|
||||
|
||||
seen: set[tuple[float, float]] = set()
|
||||
count = 0
|
||||
for trip in upcoming:
|
||||
latlon = agenda.weather.trip_latlon(trip)
|
||||
if not latlon or latlon in seen:
|
||||
continue
|
||||
seen.add(latlon)
|
||||
lat, lon = latlon
|
||||
try:
|
||||
agenda.weather.get_forecast(
|
||||
config["DATA_DIR"], config["OPENWEATHERMAP_API_KEY"], lat, lon
|
||||
)
|
||||
count += 1
|
||||
except Exception as exc:
|
||||
print(f"weather update failed for {lat},{lon}: {exc}")
|
||||
|
||||
if sys.stdin.isatty():
|
||||
print(f"updated weather for {count} location(s)")
|
||||
|
||||
|
||||
def check_birthday_reminders(config: flask.config.Config) -> None:
|
||||
"""Send at most one grouped birthday reminder email per day.
|
||||
|
||||
|
|
@ -497,6 +533,7 @@ def main() -> None:
|
|||
|
||||
agenda.fx.get_rates(app.config)
|
||||
|
||||
update_weather(app.config)
|
||||
update_thespacedevs(app.config)
|
||||
|
||||
# Check for birthday reminders daily at 9 AM
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue