From b2b22916641f6ac862b09aca283c24db883ca101 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Sun, 29 Oct 2023 14:59:03 +0000 Subject: [PATCH] Add GWR advance ticket availability date Closes: #33 --- agenda/__init__.py | 41 ++++++++++++++++++++++++++++++++++++++++- templates/index.html | 8 ++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/agenda/__init__.py b/agenda/__init__.py index 79a9589..25ab8bc 100644 --- a/agenda/__init__.py +++ b/agenda/__init__.py @@ -2,6 +2,7 @@ import configparser import json import operator import os +import re import typing import warnings from datetime import date, datetime, timedelta, timezone @@ -54,6 +55,43 @@ access_key = config.get("exchangerate", "access_key") data_dir = config.get("data", "dir") +def extract_weekday_date(html: str) -> date | None: + """Furthest date of GWR advance ticket booking.""" + # Compile a regular expression pattern to match the relevant table row + pattern = re.compile( + r"\s*Weekdays\s*(.*?)\s*", re.DOTALL + ) + + # Search the HTML for the pattern + if not (match := pattern.search(html)): + return None + date_str = match.group(1) + + # If the year is missing, use the current year + if not date_str[-1].isdigit(): + date_str += f" {date.today().year}" + + return datetime.strptime(date_str, "%A %d %B %Y").date() + + +def get_gwr_advance_tickets_page_html(ttl: int = 3600) -> str: + """Get advance-tickets web page HTML with cache.""" + filename = os.path.join(data_dir, "advance-tickets.html") + url = "https://www.gwr.com/your-tickets/choosing-your-ticket/advance-tickets" + mtime = os.path.getmtime(filename) if os.path.exists(filename) else 0 + if (unixtime() - mtime) < ttl: # use cache + return open(filename).read() + r = requests.get(url) + open(filename, "w").write(r.text) + return r.text + + +def find_gwr_advance_ticket_date() -> date | None: + """Get GWR advance tickets date with cache.""" + html = get_gwr_advance_tickets_page_html() + return extract_weekday_date(html) + + def next_uk_mothers_day(input_date: date) -> date: """Calculate the date of the next UK Mother's Day from the current date.""" current_year = input_date.year @@ -420,7 +458,7 @@ def waste_collection_events() -> list[Event]: return events -def get_data(now: datetime) -> dict[str, str | object]: +def get_data(now: datetime) -> typing.Mapping[str, str | object]: """Get data to display on agenda dashboard.""" rocket_dir = os.path.join(data_dir, "thespacedevs") today = now.date() @@ -439,6 +477,7 @@ def get_data(now: datetime) -> dict[str, str | object]: "fathers_day": next_uk_fathers_day(today), "uk_financial_year_end": uk_financial_year_end(today), "xmas_last_posting_dates": xmas_last_posting_dates, + "gwr_advance_tickets": find_gwr_advance_ticket_date(), "rockets": thespacedevs.get_launches(rocket_dir, limit=40), } diff --git a/templates/index.html b/templates/index.html index 8b4d99b..b942d06 100644 --- a/templates/index.html +++ b/templates/index.html @@ -24,6 +24,7 @@ "xmas_day": "Christmas day", "next_up_series": "Next Up documentary", "waste_schedule": "Waste schedule", + "gwr_advance_tickets": "GWR advance tickets", } %} @@ -46,6 +47,13 @@