Add trips page
Creating a new entity called a trip. This will group together any travel accommodation and conferences that happen together on one trip. A trip is assumed to start when leaving home and finish when returning home. The start date of a trip in is the trip ID. The date is written in ISO format. This assumes there cannot be multiple trips one one day. This assumption might be wrong, for example a morning day trip by rail, then another trip starts in the afternoon. I can change my choice of using dates as trip IDs if that happens. Sometimes during the planning of a trip the start date is unknown. For now we make up a start date, we can always change it later. If we use the start date in URLs then the URLs will change. Might need to keep a file of redirects, or could think of a different style of identifier. Trip ID have been added to accommodation, conferences, trains and flights. Later there will be a trips.yaml with notes about each trip.
This commit is contained in:
parent
5786e3d575
commit
ce9faa654f
10 changed files with 234 additions and 120 deletions
67
web_view.py
67
web_view.py
|
|
@ -7,11 +7,9 @@ import operator
|
|||
import os.path
|
||||
import sys
|
||||
import traceback
|
||||
import typing
|
||||
from datetime import date, datetime
|
||||
|
||||
import flask
|
||||
import pycountry
|
||||
import werkzeug
|
||||
import werkzeug.debug.tbtools
|
||||
import yaml
|
||||
|
|
@ -19,7 +17,8 @@ import yaml
|
|||
import agenda.data
|
||||
import agenda.error_mail
|
||||
import agenda.thespacedevs
|
||||
import agenda.travel
|
||||
from agenda import format_list_with_ampersand, travel
|
||||
from agenda.types import StrDict, Trip
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
app.debug = False
|
||||
|
|
@ -87,8 +86,8 @@ async def gaps_page() -> str:
|
|||
def travel_list() -> str:
|
||||
"""Page showing a list of upcoming travel."""
|
||||
data_dir = app.config["PERSONAL_DATA"]
|
||||
flights = agenda.travel.parse_yaml("flights", data_dir)
|
||||
trains = agenda.travel.parse_yaml("trains", data_dir)
|
||||
flights = travel.parse_yaml("flights", data_dir)
|
||||
trains = travel.parse_yaml("trains", data_dir)
|
||||
|
||||
return flask.render_template("travel.html", flights=flights, trains=trains)
|
||||
|
||||
|
|
@ -98,13 +97,6 @@ def as_date(d: date | datetime) -> date:
|
|||
return d.date() if isinstance(d, datetime) else d
|
||||
|
||||
|
||||
def get_country(alpha_2: str) -> str | None:
|
||||
"""Lookup country by alpha-2 country code."""
|
||||
if not alpha_2:
|
||||
return None
|
||||
return typing.cast(str, pycountry.countries.get(alpha_2=alpha_2.upper()))
|
||||
|
||||
|
||||
@app.route("/conference")
|
||||
def conference_list() -> str:
|
||||
"""Page showing a list of conferences."""
|
||||
|
|
@ -133,7 +125,7 @@ def conference_list() -> str:
|
|||
past=past,
|
||||
future=future,
|
||||
today=today,
|
||||
get_country=get_country,
|
||||
get_country=agenda.get_country,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -141,7 +133,7 @@ def conference_list() -> str:
|
|||
def accommodation_list() -> str:
|
||||
"""Page showing a list of past, present and future accommodation."""
|
||||
data_dir = app.config["PERSONAL_DATA"]
|
||||
items = agenda.travel.parse_yaml("accommodation", data_dir)
|
||||
items = travel.parse_yaml("accommodation", data_dir)
|
||||
|
||||
stays_in_2024 = [item for item in items if item["from"].year == 2024]
|
||||
total_nights_2024 = sum(
|
||||
|
|
@ -159,7 +151,52 @@ def accommodation_list() -> str:
|
|||
items=items,
|
||||
total_nights_2024=total_nights_2024,
|
||||
nights_abroad_2024=nights_abroad_2024,
|
||||
get_country=get_country,
|
||||
get_country=agenda.get_country,
|
||||
)
|
||||
|
||||
|
||||
def load_travel(travel_type: str) -> list[StrDict]:
|
||||
"""Read flight and train journeys."""
|
||||
data_dir = app.config["PERSONAL_DATA"]
|
||||
items = travel.parse_yaml(travel_type + "s", data_dir)
|
||||
for item in items:
|
||||
item["type"] = travel_type
|
||||
return items
|
||||
|
||||
|
||||
@app.route("/trip")
|
||||
def trip_list() -> str:
|
||||
"""Page showing a list of trips."""
|
||||
trips: dict[date, Trip] = {}
|
||||
|
||||
data_dir = app.config["PERSONAL_DATA"]
|
||||
|
||||
travel_items = sorted(
|
||||
load_travel("flight") + load_travel("train"), key=operator.itemgetter("depart")
|
||||
)
|
||||
|
||||
data = {
|
||||
"travel": travel_items,
|
||||
"accommodation": travel.parse_yaml("accommodation", data_dir),
|
||||
"conferences": travel.parse_yaml("conferences", data_dir),
|
||||
}
|
||||
|
||||
for key, item_list in data.items():
|
||||
assert isinstance(item_list, list)
|
||||
for item in item_list:
|
||||
if not (trip_id := item.get("trip")):
|
||||
continue
|
||||
if trip_id not in trips:
|
||||
trips[trip_id] = Trip(date=trip_id)
|
||||
getattr(trips[trip_id], key).append(item)
|
||||
|
||||
trip_list = [trip for _, trip in sorted(trips.items(), reverse=True)]
|
||||
|
||||
return flask.render_template(
|
||||
"trips.html",
|
||||
trips=trip_list,
|
||||
get_country=agenda.get_country,
|
||||
format_list_with_ampersand=format_list_with_ampersand,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue