Split 'class Event' into its own file

This commit is contained in:
Edward Betts 2024-10-01 11:13:39 +01:00
parent 02fd6dbbe6
commit a324046332
20 changed files with 174 additions and 164 deletions

View file

@ -2,7 +2,7 @@
import yaml import yaml
from .types import Event from .event import Event
def get_events(filepath: str) -> list[Event]: def get_events(filepath: str) -> list[Event]:

View file

@ -4,7 +4,7 @@ from datetime import date
import yaml import yaml
from .types import Event from .event import Event
YEAR_NOT_KNOWN = 1900 YEAR_NOT_KNOWN = 1900

View file

@ -8,7 +8,7 @@ from datetime import date, datetime, timedelta
import httpx import httpx
from .types import Event from .event import Event
from .utils import make_waste_dir from .utils import make_waste_dir
ttl_hours = 12 ttl_hours = 12

View file

@ -7,7 +7,8 @@ from datetime import date, datetime, timedelta
import flask import flask
from . import events_yaml from . import events_yaml
from .types import Event, StrDict, Trip from .event import Event
from .types import StrDict, Trip
def busy_event(e: Event) -> bool: def busy_event(e: Event) -> bool:

View file

@ -3,7 +3,7 @@
import typing import typing
from datetime import timedelta from datetime import timedelta
from .types import Event from .event import Event
event_type_color_map = { event_type_color_map = {
"bank_holiday": "success-subtle", "bank_holiday": "success-subtle",

View file

@ -4,7 +4,7 @@ from datetime import date, timedelta
from dateutil.easter import easter from dateutil.easter import easter
from .types import Event from .event import Event
def rio_carnival_events(start_date: date, end_date: date) -> list[Event]: def rio_carnival_events(start_date: date, end_date: date) -> list[Event]:

View file

@ -6,7 +6,7 @@ from datetime import date, datetime
import yaml import yaml
from .types import Event from .event import Event
@dataclasses.dataclass @dataclasses.dataclass

View file

@ -35,7 +35,8 @@ from . import (
travel, travel,
uk_holiday, uk_holiday,
) )
from .types import Event, StrDict from .event import Event
from .types import StrDict
from .utils import time_function from .utils import time_function
here = dateutil.tz.tzlocal() here = dateutil.tz.tzlocal()

View file

@ -4,7 +4,7 @@ import csv
import os import os
from datetime import datetime from datetime import datetime
from .types import Event from .event import Event
url = "https://admin.gandi.net/domain/01578ef0-a84b-11e7-bdf3-00163e6dc886/" url = "https://admin.gandi.net/domain/01578ef0-a84b-11e7-bdf3-00163e6dc886/"

View file

@ -5,7 +5,7 @@ from datetime import date, time, timedelta
from dateutil.relativedelta import TH, relativedelta from dateutil.relativedelta import TH, relativedelta
from . import uk_time from . import uk_time
from .types import Event from .event import Event
def publication_dates(start_date: date, end_date: date) -> list[Event]: def publication_dates(start_date: date, end_date: date) -> list[Event]:

149
agenda/event.py Normal file
View file

@ -0,0 +1,149 @@
"""Types."""
import datetime
from dataclasses import dataclass
from . import utils
from .types import DateOrDateTime, StrDict
emojis = {
"market": "🧺",
"us_presidential_election": "🗳️🇺🇸",
"bus_route_closure": "🚌❌",
"meetup": "👥",
"dinner": "🍷",
"party": "🍷",
"ba_voucher": "✈️",
"accommodation": "🏨", # alternative: 🧳
"flight": "✈️",
"conference": "🎤",
"rocket": "🚀",
"birthday": "🎈",
"waste_schedule": "🗑️",
"economist": "📰",
"running": "🏃",
"critical_mass": "🚴",
"trip": "🧳",
"hackathon": "💻",
}
@dataclass
class Event:
"""Event."""
name: str
date: DateOrDateTime
end_date: DateOrDateTime | None = None
title: str | None = None
url: str | None = None
going: bool | None = None
@property
def as_datetime(self) -> datetime.datetime:
"""Date/time of event."""
return utils.as_datetime(self.date)
@property
def has_time(self) -> bool:
"""Event has a time associated with it."""
return isinstance(self.date, datetime.datetime)
@property
def as_date(self) -> datetime.date:
"""Date of event."""
return (
self.date.date() if isinstance(self.date, datetime.datetime) else self.date
)
@property
def end_as_date(self) -> datetime.date:
"""Date of event."""
return (
(
self.end_date.date()
if isinstance(self.end_date, datetime.datetime)
else self.end_date
)
if self.end_date
else self.as_date
)
@property
def display_time(self) -> str | None:
"""Time for display on web page."""
return (
self.date.strftime("%H:%M")
if isinstance(self.date, datetime.datetime)
else None
)
@property
def display_timezone(self) -> str | None:
"""Timezone for display on web page."""
return (
self.date.strftime("%z")
if isinstance(self.date, datetime.datetime)
else None
)
def display_duration(self) -> str | None:
"""Duration for display."""
if self.end_as_date != self.as_date or not self.has_time:
return None
assert isinstance(self.date, datetime.datetime)
assert isinstance(self.end_date, datetime.datetime)
secs: int = int((self.end_date - self.date).total_seconds())
hours: int = secs // 3600
mins: int = (secs % 3600) // 60
if mins == 0:
return f"{hours:d}h"
if hours == 0:
return f"{mins:d} mins"
return f"{hours:d}h {mins:02d} mins"
def delta_days(self, today: datetime.date) -> str:
"""Return number of days from today as a string."""
delta = (self.as_date - today).days
match delta:
case 0:
return "today"
case 1:
return "1 day"
case _:
return f"{delta:,d} days"
@property
def display_date(self) -> str:
"""Date for display on web page."""
if isinstance(self.date, datetime.datetime):
return self.date.strftime("%a, %d, %b %Y %H:%M %z")
else:
return self.date.strftime("%a, %d, %b %Y")
@property
def display_title(self) -> str:
"""Name for display."""
return self.title or self.name
@property
def emoji(self) -> str | None:
"""Emoji."""
if self.title == "LHG Run Club":
return "🏃🍻"
return emojis.get(self.name)
@property
def title_with_emoji(self) -> str | None:
"""Title with optional emoji at the start."""
title = self.title or self.name
if title is None:
return None
emoji = self.emoji
return f"{emoji} {title}" if emoji else title

View file

@ -9,7 +9,7 @@ import isodate # type: ignore
import yaml import yaml
from . import uk_tz from . import uk_tz
from .types import Event from .event import Event
def midnight(d: date) -> datetime: def midnight(d: date) -> datetime:

View file

@ -1,7 +1,7 @@
"""Gandi domain renewal dates.""" """Gandi domain renewal dates."""
import os import os
from .types import Event from .event import Event
from datetime import datetime from datetime import datetime
import json import json

View file

@ -5,7 +5,7 @@ from datetime import date, datetime, time, timedelta
import pytz import pytz
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from .types import Event from .event import Event
eastern_time = pytz.timezone("America/New_York") eastern_time = pytz.timezone("America/New_York")

View file

@ -6,7 +6,8 @@ from datetime import date, timedelta
import agenda.uk_holiday import agenda.uk_holiday
import holidays import holidays
from .types import Event, Holiday from .event import Event
from .types import Holiday
def us_holidays(start_date: date, end_date: date) -> list[Holiday]: def us_holidays(start_date: date, end_date: date) -> list[Holiday]:
@ -98,9 +99,9 @@ def combine_holidays(holidays: list[Holiday]) -> list[Event]:
(12, 26): "Boxing Day", (12, 26): "Boxing Day",
} }
combined: collections.defaultdict[ combined: collections.defaultdict[tuple[date, str], set[str]] = (
tuple[date, str], set[str] collections.defaultdict(set)
] = collections.defaultdict(set) )
for h in holidays: for h in holidays:
assert isinstance(h.name, str) and isinstance(h.date, date) assert isinstance(h.name, str) and isinstance(h.date, date)

View file

@ -4,7 +4,7 @@ import json
import os.path import os.path
from datetime import datetime from datetime import datetime
from .types import Event from .event import Event
def get_events(data_dir: str) -> list[Event]: def get_events(data_dir: str) -> list[Event]:

View file

@ -9,7 +9,7 @@ import httpx
import lxml.html import lxml.html
from . import uk_time from . import uk_time
from .types import Event from .event import Event
from .utils import make_waste_dir from .utils import make_waste_dir
ttl_hours = 12 ttl_hours = 12

View file

@ -2,7 +2,7 @@
import yaml import yaml
from .types import Event from .event import Event
def get_events(filepath: str) -> list[Event]: def get_events(filepath: str) -> list[Event]:

View file

@ -9,7 +9,8 @@ import flask
import yaml import yaml
from geopy.distance import geodesic # type: ignore from geopy.distance import geodesic # type: ignore
from .types import Event, StrDict from .event import Event
from .types import StrDict
Leg = dict[str, str] Leg = dict[str, str]

View file

@ -351,146 +351,3 @@ class Holiday:
if self.local_name and self.local_name != self.name if self.local_name and self.local_name != self.name
else self.name else self.name
) )
emojis = {
"market": "🧺",
"us_presidential_election": "🗳️🇺🇸",
"bus_route_closure": "🚌❌",
"meetup": "👥",
"dinner": "🍷",
"party": "🍷",
"ba_voucher": "✈️",
"accommodation": "🏨", # alternative: 🧳
"flight": "✈️",
"conference": "🎤",
"rocket": "🚀",
"birthday": "🎈",
"waste_schedule": "🗑️",
"economist": "📰",
"running": "🏃",
"critical_mass": "🚴",
"trip": "🧳",
"hackathon": "💻",
}
@dataclass
class Event:
"""Event."""
name: str
date: DateOrDateTime
end_date: DateOrDateTime | None = None
title: str | None = None
url: str | None = None
going: bool | None = None
@property
def as_datetime(self) -> datetime.datetime:
"""Date/time of event."""
return utils.as_datetime(self.date)
@property
def has_time(self) -> bool:
"""Event has a time associated with it."""
return isinstance(self.date, datetime.datetime)
@property
def as_date(self) -> datetime.date:
"""Date of event."""
return (
self.date.date() if isinstance(self.date, datetime.datetime) else self.date
)
@property
def end_as_date(self) -> datetime.date:
"""Date of event."""
return (
(
self.end_date.date()
if isinstance(self.end_date, datetime.datetime)
else self.end_date
)
if self.end_date
else self.as_date
)
@property
def display_time(self) -> str | None:
"""Time for display on web page."""
return (
self.date.strftime("%H:%M")
if isinstance(self.date, datetime.datetime)
else None
)
@property
def display_timezone(self) -> str | None:
"""Timezone for display on web page."""
return (
self.date.strftime("%z")
if isinstance(self.date, datetime.datetime)
else None
)
def display_duration(self) -> str | None:
"""Duration for display."""
if self.end_as_date != self.as_date or not self.has_time:
return None
assert isinstance(self.date, datetime.datetime)
assert isinstance(self.end_date, datetime.datetime)
secs: int = int((self.end_date - self.date).total_seconds())
hours: int = secs // 3600
mins: int = (secs % 3600) // 60
if mins == 0:
return f"{hours:d}h"
if hours == 0:
return f"{mins:d} mins"
return f"{hours:d}h {mins:02d} mins"
def delta_days(self, today: datetime.date) -> str:
"""Return number of days from today as a string."""
delta = (self.as_date - today).days
match delta:
case 0:
return "today"
case 1:
return "1 day"
case _:
return f"{delta:,d} days"
@property
def display_date(self) -> str:
"""Date for display on web page."""
if isinstance(self.date, datetime.datetime):
return self.date.strftime("%a, %d, %b %Y %H:%M %z")
else:
return self.date.strftime("%a, %d, %b %Y")
@property
def display_title(self) -> str:
"""Name for display."""
return self.title or self.name
@property
def emoji(self) -> str | None:
"""Emoji."""
if self.title == "LHG Run Club":
return "🏃🍻"
return emojis.get(self.name)
@property
def title_with_emoji(self) -> str | None:
"""Title with optional emoji at the start."""
title = self.title or self.name
if title is None:
return None
emoji = self.emoji
return f"{emoji} {title}" if emoji else title