Move some functions into a utils module

This commit is contained in:
Edward Betts 2024-07-01 22:22:01 +03:00
parent 0e49d18721
commit 01b42845c3
2 changed files with 34 additions and 31 deletions

View file

@ -12,28 +12,12 @@ from pycountry.db import Country
import agenda import agenda
from agenda import format_list_with_ampersand from agenda import format_list_with_ampersand
from . import utils
StrDict = dict[str, typing.Any] StrDict = dict[str, typing.Any]
DateOrDateTime = datetime.datetime | datetime.date DateOrDateTime = datetime.datetime | datetime.date
def as_date(d: DateOrDateTime) -> datetime.date:
"""Convert datetime to date."""
if isinstance(d, datetime.datetime):
return d.date()
assert isinstance(d, datetime.date)
return d
def as_datetime(d: DateOrDateTime) -> datetime.datetime:
"""Date/time of event."""
t0 = datetime.datetime.min.time()
return (
d
if isinstance(d, datetime.datetime)
else datetime.datetime.combine(d, t0).replace(tzinfo=datetime.timezone.utc)
)
@dataclass @dataclass
class TripElement: class TripElement:
"""Trip element.""" """Trip element."""
@ -106,18 +90,20 @@ class Trip:
def end(self) -> datetime.date | None: def end(self) -> datetime.date | None:
"""End date for trip.""" """End date for trip."""
max_conference_end = ( max_conference_end = (
max(as_date(item["end"]) for item in self.conferences) max(utils.as_date(item["end"]) for item in self.conferences)
if self.conferences if self.conferences
else datetime.date.min else datetime.date.min
) )
assert isinstance(max_conference_end, datetime.date) assert isinstance(max_conference_end, datetime.date)
arrive = [as_date(item["arrive"]) for item in self.travel if "arrive" in item] arrive = [
utils.as_date(item["arrive"]) for item in self.travel if "arrive" in item
]
travel_end = max(arrive) if arrive else datetime.date.min travel_end = max(arrive) if arrive else datetime.date.min
assert isinstance(travel_end, datetime.date) assert isinstance(travel_end, datetime.date)
accommodation_end = ( accommodation_end = (
max(as_date(item["to"]) for item in self.accommodation) max(utils.as_date(item["to"]) for item in self.accommodation)
if self.accommodation if self.accommodation
else datetime.date.min else datetime.date.min
) )
@ -314,7 +300,7 @@ class Trip:
) )
) )
return sorted(elements, key=lambda e: as_datetime(e.start_time)) return sorted(elements, key=lambda e: utils.as_datetime(e.start_time))
def elements_grouped_by_day(self) -> list[tuple[datetime.date, list[TripElement]]]: def elements_grouped_by_day(self) -> list[tuple[datetime.date, list[TripElement]]]:
"""Group trip elements by day.""" """Group trip elements by day."""
@ -325,7 +311,7 @@ class Trip:
for element in self.elements(): for element in self.elements():
# Extract the date part of the 'when' attribute # Extract the date part of the 'when' attribute
day = as_date(element.start_time) day = utils.as_date(element.start_time)
grouped_elements[day].append(element) grouped_elements[day].append(element)
# Sort elements within each day # Sort elements within each day
@ -334,7 +320,7 @@ class Trip:
key=lambda e: ( key=lambda e: (
e.element_type == "check-in", # check-out elements last e.element_type == "check-in", # check-out elements last
e.element_type != "check-out", # check-in elements first e.element_type != "check-out", # check-in elements first
as_datetime(e.start_time), # then sort by time utils.as_datetime(e.start_time), # then sort by time
) )
) )
@ -403,13 +389,7 @@ class Event:
@property @property
def as_datetime(self) -> datetime.datetime: def as_datetime(self) -> datetime.datetime:
"""Date/time of event.""" """Date/time of event."""
d = self.date return utils.as_datetime(self.date)
t0 = datetime.datetime.min.time()
return (
d
if isinstance(d, datetime.datetime)
else datetime.datetime.combine(d, t0).replace(tzinfo=datetime.timezone.utc)
)
@property @property
def has_time(self) -> bool: def has_time(self) -> bool:

23
agenda/utils.py Normal file
View file

@ -0,0 +1,23 @@
"""Utility functions."""
import datetime
DateOrDateTime = datetime.datetime | datetime.date
def as_date(d: DateOrDateTime) -> datetime.date:
"""Convert datetime to date."""
if isinstance(d, datetime.datetime):
return d.date()
assert isinstance(d, datetime.date)
return d
def as_datetime(d: DateOrDateTime) -> datetime.datetime:
"""Date/time of event."""
t0 = datetime.datetime.min.time()
return (
d
if isinstance(d, datetime.datetime)
else datetime.datetime.combine(d, t0).replace(tzinfo=datetime.timezone.utc)
)