diff --git a/agenda/__init__.py b/agenda/__init__.py index b63e609..c7e9850 100644 --- a/agenda/__init__.py +++ b/agenda/__init__.py @@ -1,4 +1,5 @@ import configparser +import dataclasses import json import operator import os @@ -49,6 +50,15 @@ access_key = config.get("exchangerate", "access_key") data_dir = config.get("data", "dir") +@dataclasses.dataclass +class Event: + """Event.""" + + name: str + date: date + title: str | None = None + + 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 @@ -102,7 +112,7 @@ def get_next_timezone_transition(from_dt: datetime, tz_name: str) -> date: return typing.cast(date, dt.date()) -def get_next_bank_holiday(input_date: date) -> dict[str, date | str]: +def get_next_bank_holiday(input_date: date) -> Event: """Date and name of the next UK bank holiday.""" url = "https://www.gov.uk/bank-holidays.json" filename = os.path.join(data_dir, "bank-holidays.json") @@ -117,7 +127,7 @@ def get_next_bank_holiday(input_date: date) -> dict[str, date | str]: event_date = datetime.strptime(event["date"], "%Y-%m-%d").date() if event_date < input_date: continue - next_holiday = {"date": event_date, "title": event["title"]} + next_holiday = Event(name="bank_holiay", date=event_date, title=event["title"]) break assert next_holiday @@ -257,15 +267,15 @@ def stock_markets() -> list[str]: return reply -def get_us_holiday(input_date: date) -> dict[str, date | str]: +def get_us_holiday(input_date: date) -> Event: """Date and name of next US holiday.""" hols = holidays.UnitedStates(years=[input_date.year, input_date.year + 1]) next_hol = next(x for x in sorted(hols.items()) if x[0] >= input_date) - return {"date": next_hol[0], "title": next_hol[1]} + return Event(name="us_holiday", date=next_hol[0], title=next_hol[1]) -def next_birthday(from_date: date, birth_date: date) -> dict[str, int | date]: +def next_birthday(from_date: date, birth_date: date) -> tuple[date, int]: """Calculate the date of the next birthday based on a given birth date.""" next_birthday_date = birth_date.replace(year=from_date.year) @@ -274,23 +284,22 @@ def next_birthday(from_date: date, birth_date: date) -> dict[str, int | date]: age_at_next_birthday = next_birthday_date.year - birth_date.year - return {"next_birthday": next_birthday_date, "age": age_at_next_birthday} + return next_birthday_date, age_at_next_birthday -def get_birthdays( - from_date: date, config: configparser.ConfigParser -) -> list[dict[str, date | str]]: +def get_birthdays(from_date: date, config: configparser.ConfigParser) -> list[Event]: + """Get birthdays from config.""" if "birthdays" not in config: return [] events = [] for name, date_str in config["birthdays"].items(): bday = next_birthday(from_date, datetime.strptime(date_str, "%Y-%m-%d").date()) events.append( - { - "date": bday["next_birthday"], - "name": "birthday", - "title": f"{name} (aged {bday['age']})", - } + Event( + date=bday[0], + name="birthday", + title=f"{name} (aged {bday[1]})", + ) ) return events @@ -321,31 +330,31 @@ def get_data(now: datetime) -> dict[str, str | object]: } skip = {"now", "gbpusd", "rockets", "stock_markets", "xmas_last_posting_dates"} - events = [] + events: list[Event] = [] for key, value in reply.items(): if key in skip: continue if "holiday" in key: - assert isinstance(value, dict) + assert isinstance(value, Event) event = value - event["name"] = key else: - event = {"name": key, "date": value} + assert isinstance(value, date) + event = Event(name=key, date=value) events.append(event) for key, value in xmas_last_posting_dates.items(): - events.append({"name": f"xmas_last_{key}", "date": value}) + events.append(Event(name=f"xmas_last_{key}", date=value)) events += get_birthdays(today, config) - next_up_series = { - "date": date(2026, 6, 1), - "title": "70 Up", - "name": "next_up_series", - } + next_up_series = Event( + date=date(2026, 6, 1), + title="70 Up", + name="next_up_series", + ) events.append(next_up_series) - events.sort(key=operator.itemgetter("date")) + events.sort(key=operator.attrgetter("date")) reply["events"] = events