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
from .types import Event
from .event import Event
def get_events(filepath: str) -> list[Event]:

View file

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

View file

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

View file

@ -7,7 +7,8 @@ from datetime import date, datetime, timedelta
import flask
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:

View file

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

View file

@ -4,7 +4,7 @@ from datetime import date, timedelta
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]:

View file

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

View file

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

View file

@ -4,7 +4,7 @@ import csv
import os
from datetime import datetime
from .types import Event
from .event import Event
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 . import uk_time
from .types import Event
from .event import 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
from . import uk_tz
from .types import Event
from .event import Event
def midnight(d: date) -> datetime:

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -351,146 +351,3 @@ class Holiday:
if self.local_name and self.local_name != 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