#!/usr/bin/python3 """Combined update script for various data sources.""" import asyncio import os import smtplib import sys from datetime import date, datetime from email.message import EmailMessage from email.utils import formatdate, make_msgid from time import time import requests import agenda.thespacedevs import agenda.types import agenda.uk_holiday import agenda.waste_schedule from agenda import gwr config = __import__("config.default", fromlist=[""]) async def update_bank_holidays() -> None: """Update cached copy of UK Bank holidays.""" t0 = time() events = await agenda.uk_holiday.get_holiday_list(config.DATA_DIR) time_taken = time() - t0 if not sys.stdin.isatty(): return print(len(events), "bank holidays in list") print(f"took {time_taken:.1f} seconds") async def update_bristol_bins() -> None: """Update waste schedule from Bristol City Council.""" t0 = time() events = await agenda.waste_schedule.get_bristol_gov_uk( date.today(), config.DATA_DIR, config.BRISTOL_UPRN, refresh=True ) time_taken = time() - t0 if not sys.stdin.isatty(): return for event in events: print(event) print(f"took {time_taken:.1f} seconds") def send_mail(subject: str, body: str) -> None: """Send an e-mail.""" msg = EmailMessage() msg["Subject"] = subject msg["To"] = f"{config.NAME} <{config.MAIL_TO}>" msg["From"] = f"{config.NAME} <{config.MAIL_FROM}>" msg["Date"] = formatdate() msg["Message-ID"] = make_msgid() # Add extra mail headers for header, value in config.MAIL_HEADERS: msg[header] = value msg.set_content(body) s = smtplib.SMTP(config.SMTP_HOST) s.sendmail(config.MAIL_TO, [config.MAIL_TO], msg.as_string()) s.quit() def update_gwr_advance_ticket_date() -> None: """Update GWR advance ticket date cache.""" filename = os.path.join(config.DATA_DIR, "advance-tickets.html") existing_html = open(filename).read() existing_date = gwr.extract_weekday_date(existing_html) new_html = requests.get(gwr.url).text open(filename, "w").write(new_html) new_date = gwr.extract_weekday_date(new_html) if existing_date == new_date: if sys.stdin.isatty(): print("date has't changed:", existing_date) return subject = f"New GWR advance ticket booking date: {new_date}" body = f"""Old date: {existing_date} New date: {new_date} {gwr.url} Agenda: https://edwardbetts.com/agenda/ """ send_mail(subject, body) def update_thespacedevs() -> None: """Update cache of space launch API.""" rocket_dir = os.path.join(config.DATA_DIR, "thespacedevs") t0 = time() rockets = agenda.thespacedevs.next_launch_api(rocket_dir) time_taken = time() - t0 if not sys.stdin.isatty(): return print(len(rockets), "launches") print(f"took {time_taken:.1f} seconds") def update_gandi() -> None: """Retrieve list of domains from gandi.net.""" url = "https://api.gandi.net/v5/domain/domains" headers = {"authorization": "Bearer " + config.GANDI_TOKEN} filename = os.path.join(config.DATA_DIR, "gandi_domains.json") r = requests.request("GET", url, headers=headers) items = r.json() assert isinstance(items, list) assert all(item["fqdn"] and item["dates"]["registry_ends_at"] for item in items) with open(filename, "w") as out: out.write(r.text) def main() -> None: """Update caches.""" now = datetime.now() hour = now.hour if hour % 3 == 0: asyncio.run(update_bank_holidays()) asyncio.run(update_bristol_bins()) update_gwr_advance_ticket_date() update_gandi() update_thespacedevs() if __name__ == "__main__": main()