Send alert emails for particular rocket launches

Closes: #156
This commit is contained in:
Edward Betts 2024-06-15 21:35:18 +01:00
parent ce07ae65b1
commit e400360697
2 changed files with 63 additions and 5 deletions

View file

@ -7,13 +7,15 @@ from datetime import datetime
import requests
from .types import StrDict
Launch = dict[str, typing.Any]
Summary = dict[str, typing.Any]
ttl = 60 * 60 * 2 # two hours
def next_launch_api(rocket_dir: str, limit: int = 200) -> list[Launch]:
def next_launch_api_data(rocket_dir: str, limit: int = 200) -> StrDict:
"""Get the next upcoming launches from the API."""
now = datetime.now()
filename = os.path.join(rocket_dir, now.strftime("%Y-%m-%d_%H:%M:%S.json"))
@ -21,8 +23,14 @@ def next_launch_api(rocket_dir: str, limit: int = 200) -> list[Launch]:
params: dict[str, str | int] = {"limit": limit}
r = requests.get(url, params=params)
data = r.json()
data: StrDict = r.json()
open(filename, "w").write(r.text)
return data
def next_launch_api(rocket_dir: str, limit: int = 200) -> list[Launch]:
"""Get the next upcoming launches from the API."""
data = next_launch_api_data(rocket_dir, limit)
return [summarize_launch(launch) for launch in data["results"]]
@ -138,7 +146,7 @@ def summarize_launch(launch: Launch) -> Summary:
}
def read_cached_launches(rocket_dir: str) -> list[Summary]:
def load_cached_launches(rocket_dir: str) -> StrDict:
"""Read the most recent cache of launches."""
existing = [x for x in (filename_timestamp(f) for f in os.listdir(rocket_dir)) if x]
@ -146,7 +154,12 @@ def read_cached_launches(rocket_dir: str) -> list[Summary]:
f = existing[0][1]
filename = os.path.join(rocket_dir, f)
data = json.load(open(filename))
return typing.cast(StrDict, json.load(open(filename)))
def read_cached_launches(rocket_dir: str) -> list[Summary]:
"""Read cached launches."""
data = load_cached_launches(rocket_dir)
return [summarize_launch(launch) for launch in data["results"]]

View file

@ -2,9 +2,11 @@
"""Combined update script for various data sources."""
import asyncio
import json
import os
import smtplib
import sys
import typing
from datetime import date, datetime
from email.message import EmailMessage
from email.utils import formatdate, make_msgid
@ -19,6 +21,7 @@ import agenda.types
import agenda.uk_holiday
import agenda.waste_schedule
from agenda import gwr
from agenda.types import StrDict
from web_view import app
@ -95,15 +98,57 @@ Agenda: https://edwardbetts.com/agenda/
send_mail(config, subject, body)
def report_space_launch_change(
config: flask.config.Config, prev_launch: StrDict, cur_launch: StrDict
) -> None:
"""Send mail to announce change to space launch data."""
subject = f'Change to {cur_launch["name"]}'
body = f"""
A space launch of interest was updated.
Get ready for two big piles of JSON.
Old launch data
{json.dumps(prev_launch, indent=2)}
New launch data
{json.dumps(cur_launch, indent=2)}
"""
send_mail(config, subject, body)
def get_launch_by_slug(data: StrDict, slug: str) -> StrDict:
"""Find last update for space launch."""
return {item["slug"]: typing.cast(StrDict, item) for item in data["results"]}[slug]
def update_thespacedevs(config: flask.config.Config) -> None:
"""Update cache of space launch API."""
rocket_dir = os.path.join(config["DATA_DIR"], "thespacedevs")
existing_data = agenda.thespacedevs.load_cached_launches(rocket_dir)
prev_launches = {
slug: get_launch_by_slug(existing_data, slug)
for slug in config["FOLLOW_LAUNCHES"]
}
t0 = time()
rockets = agenda.thespacedevs.next_launch_api(rocket_dir)
data = agenda.thespacedevs.next_launch_api_data(rocket_dir)
cur_launches = {
slug: get_launch_by_slug(data, slug) for slug in config["FOLLOW_LAUNCHES"]
}
for slug in config["FOLLOW_LAUNCHES"]:
prev, cur = prev_launches[slug], cur_launches[slug]
if prev["last_updated"] != cur["last_updated"]:
report_space_launch_change(config, prev, cur)
time_taken = time() - t0
if not sys.stdin.isatty():
return
rockets = [agenda.thespacedevs.summarize_launch(item) for item in data["results"]]
print(len(rockets), "launches")
print(f"took {time_taken:.1f} seconds")