Add time to some events

This commit is contained in:
Edward Betts 2023-10-21 22:58:44 +01:00
parent 7c5c73d649
commit 6b6e038b67
4 changed files with 53 additions and 25 deletions

View file

@ -269,6 +269,10 @@ def get_us_holidays(input_date: date) -> list[Event]:
] ]
def as_date(d: date | datetime) -> date:
return d.date() if isinstance(d, datetime) else d
def get_conferences(input_date: date, filepath: str) -> List[Event]: def get_conferences(input_date: date, filepath: str) -> List[Event]:
"""Read conferences from a YAML file and return a list of Event objects.""" """Read conferences from a YAML file and return a list of Event objects."""
with open(filepath, "r") as f: with open(filepath, "r") as f:
@ -279,7 +283,7 @@ def get_conferences(input_date: date, filepath: str) -> List[Event]:
event_date = conf["start"] event_date = conf["start"]
# Skip the conference if it is before the input date. # Skip the conference if it is before the input date.
if event_date < input_date: if as_date(event_date) < input_date:
continue continue
event = Event( event = Event(
name="conference", name="conference",
@ -337,7 +341,7 @@ def get_accommodation(from_date: date, filepath: str) -> list[Event]:
) )
from_date = item["from"] from_date = item["from"]
to_date = item["to"] to_date = item["to"]
nights = (to_date - from_date).days nights = (to_date.date() - from_date.date()).days
night_str = f"{nights} nights" if nights != 1 else "1 night" night_str = f"{nights} nights" if nights != 1 else "1 night"
checkin = Event( checkin = Event(
date=from_date, date=from_date,
@ -359,7 +363,7 @@ def get_travel(from_date: date, method: str, filepath: str) -> list[Event]:
"""Get travel events.""" """Get travel events."""
return [ return [
Event( Event(
date=item["depart"].date(), date=item["depart"],
name="transport", name="transport",
title=f'{method} from {item["from"]} to {item["to"]}', title=f'{method} from {item["from"]} to {item["to"]}',
url=item.get("url"), url=item.get("url"),
@ -441,7 +445,7 @@ def get_data(now: datetime) -> dict[str, str | object]:
) )
events.append(next_up_series) events.append(next_up_series)
events.sort(key=operator.attrgetter("date")) events.sort(key=operator.attrgetter("as_datetime"))
reply["events"] = events reply["events"] = events

View file

@ -1,7 +1,8 @@
"""Types.""" """Types."""
import dataclasses import dataclasses
from datetime import date import datetime
from datetime import date, timezone
@dataclasses.dataclass @dataclasses.dataclass
@ -9,6 +10,44 @@ class Event:
"""Event.""" """Event."""
name: str name: str
date: date date: date | datetime.datetime
title: str | None = None title: str | None = None
url: str | None = None url: str | None = None
@property
def as_datetime(self) -> datetime.datetime:
"""Date/time of event."""
d = self.date
t0 = datetime.datetime.min.time()
return (
d
if isinstance(d, datetime.datetime)
else datetime.datetime.combine(d, t0).replace(tzinfo=timezone.utc)
)
@property
def as_date(self) -> datetime.date:
"""Date of event."""
return (
self.date.date() if isinstance(self.date, datetime.datetime) else self.date
)
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")

View file

@ -52,7 +52,7 @@
{% for event in events %} {% for event in events %}
<tr> <tr>
<td class="text-end"> <td class="text-end">
{{event.date.strftime("%a, %d, %b %Y")}} {{event.display_date}}
</td> </td>
<td class="text-start {% if event.name in class_map %} {{ class_map[event.name]}}{% endif %}"> <td class="text-start {% if event.name in class_map %} {{ class_map[event.name]}}{% endif %}">
{% if event.url %}<a href="{{ event.url }}">{% endif %} {% if event.url %}<a href="{{ event.url }}">{% endif %}
@ -61,7 +61,7 @@
{% if event.url %}</a>{% endif %} {% if event.url %}</a>{% endif %}
</td> </td>
<td class="text-end"> <td class="text-end">
{{ days(event.date) }} {{ event.delta_days(today) }}
</td> </td>
{% endfor %} {% endfor %}
</table> </table>

View file

@ -2,11 +2,10 @@
"""Web page to show upcoming events.""" """Web page to show upcoming events."""
import functools
import inspect import inspect
import sys import sys
import traceback import traceback
from datetime import date, datetime from datetime import datetime
import flask import flask
import werkzeug import werkzeug
@ -45,27 +44,13 @@ def exception_handler(e: werkzeug.exceptions.InternalServerError) -> tuple[str,
) )
def delta_days(today: date, when: date) -> str:
"""Return number of days from today as a string."""
delta = (when - today).days
match delta:
case 0:
return "today"
case 1:
return "1 day"
case _:
return f"{delta:,d} days"
@app.route("/") @app.route("/")
def index() -> str: def index() -> str:
"""Index page.""" """Index page."""
now = datetime.now() now = datetime.now()
data = get_data(now) data = get_data(now)
days = functools.partial(delta_days, now.date())
return flask.render_template("index.html", days=days, **data) return flask.render_template("index.html", today=now.date(), **data)
if __name__ == "__main__": if __name__ == "__main__":