Adjust travel page to show flights grouped by booking with booking reference and price
Closes: #152
This commit is contained in:
parent
19732a3ef1
commit
6d6e416df3
|
@ -65,12 +65,11 @@ def depart_datetime(item: StrDict) -> datetime:
|
||||||
return datetime.combine(depart, time.min).replace(tzinfo=ZoneInfo("UTC"))
|
return datetime.combine(depart, time.min).replace(tzinfo=ZoneInfo("UTC"))
|
||||||
|
|
||||||
|
|
||||||
def load_flights(data_dir: str) -> list[StrDict]:
|
def load_flight_bookings(data_dir: str) -> list[StrDict]:
|
||||||
"""Load flights."""
|
"""Load flight bookings."""
|
||||||
bookings = load_travel("flight", data_dir)
|
bookings = load_travel("flight", data_dir)
|
||||||
airlines = yaml.safe_load(open(os.path.join(data_dir, "airlines.yaml")))
|
airlines = yaml.safe_load(open(os.path.join(data_dir, "airlines.yaml")))
|
||||||
airports = travel.parse_yaml("airports", data_dir)
|
airports = travel.parse_yaml("airports", data_dir)
|
||||||
flights = []
|
|
||||||
for booking in bookings:
|
for booking in bookings:
|
||||||
for flight in booking["flights"]:
|
for flight in booking["flights"]:
|
||||||
if flight["from"] in airports:
|
if flight["from"] in airports:
|
||||||
|
@ -81,10 +80,17 @@ def load_flights(data_dir: str) -> list[StrDict]:
|
||||||
flight["airline_name"] = airlines.get(flight["airline"], "[unknown]")
|
flight["airline_name"] = airlines.get(flight["airline"], "[unknown]")
|
||||||
|
|
||||||
flight["distance"] = travel.flight_distance(flight)
|
flight["distance"] = travel.flight_distance(flight)
|
||||||
flight["type"] = booking["type"]
|
return bookings
|
||||||
flight["trip"] = booking["trip"]
|
|
||||||
if "booking_reference" in booking:
|
|
||||||
flight["booking_reference"] = booking["booking_reference"]
|
def load_flights(data_dir: str) -> list[StrDict]:
|
||||||
|
"""Load flights."""
|
||||||
|
flights = []
|
||||||
|
for booking in load_flight_bookings(data_dir):
|
||||||
|
for flight in booking["flights"]:
|
||||||
|
for f in "type", "trip", "booking_reference":
|
||||||
|
if f in booking:
|
||||||
|
flight[f] = booking[f]
|
||||||
flights.append(flight)
|
flights.append(flight)
|
||||||
return flights
|
return flights
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,49 @@
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro flight_booking_row(booking) %}
|
||||||
|
<div class="grid-item">{{ booking.booking_reference or "reference missing" }}</div>
|
||||||
|
<div class="grid-item text-end">
|
||||||
|
{% if g.user.is_authenticated and booking.price and booking.currency %}
|
||||||
|
<span class="badge bg-info text-nowrap">{{ "{:,f}".format(booking.price) }} {{ booking.currency }}</span>
|
||||||
|
{% if booking.currency != "GBP" %}
|
||||||
|
<span class="badge bg-info text-nowrap">{{ "{:,.2f}".format(booking.price / fx_rate[booking.currency]) }} GBP</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% for i in range(8) %}
|
||||||
|
<div class="grid-item"></div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for item in booking.flights %}
|
||||||
|
{% set full_flight_number = item.airline + item.flight_number %}
|
||||||
|
{% set radarbox_url = "https://www.radarbox.com/data/flights/" + full_flight_number %}
|
||||||
|
<div class="grid-item"></div>
|
||||||
|
<div class="grid-item"></div>
|
||||||
|
<div class="grid-item text-end">{{ item.depart.strftime("%a, %d %b %Y") }}</div>
|
||||||
|
<div class="grid-item">{{ item.from }} → {{ item.to }}</div>
|
||||||
|
<div class="grid-item">{{ item.depart.strftime("%H:%M") }}</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
{% if item.arrive %}
|
||||||
|
{{ item.arrive.strftime("%H:%M") }}
|
||||||
|
{% if item.arrive.date() != item.depart.date() %}+1 day{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">{{ item.duration }}</div>
|
||||||
|
<div class="grid-item">{{ full_flight_number }}</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<a href="https://www.flightradar24.com/data/flights/{{ full_flight_number | lower }}">flightradar24</a>
|
||||||
|
| <a href="https://uk.flightaware.com/live/flight/{{ full_flight_number | replace("U2", "EZY") }}">FlightAware</a>
|
||||||
|
| <a href="{{ radarbox_url }}">radarbox</a>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item text-end">
|
||||||
|
{% if item.distance %}
|
||||||
|
{{ "{:,.0f} km / {:,.0f} miles".format(item.distance, item.distance / 1.60934) }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro flight_row(item) %}
|
{% macro flight_row(item) %}
|
||||||
{% set full_flight_number = item.airline + item.flight_number %}
|
{% set full_flight_number = item.airline + item.flight_number %}
|
||||||
{% set radarbox_url = "https://www.radarbox.com/data/flights/" + full_flight_number %}
|
{% set radarbox_url = "https://www.radarbox.com/data/flights/" + full_flight_number %}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% from "macros.html" import flight_row, train_row with context %}
|
{% from "macros.html" import flight_booking_row, train_row with context %}
|
||||||
|
|
||||||
{% block title %}Travel - Edward Betts{% endblock %}
|
{% block title %}Travel - Edward Betts{% endblock %}
|
||||||
|
|
||||||
|
{% set flight_column_count = 10 %}
|
||||||
{% set column_count = 10 %}
|
{% set column_count = 10 %}
|
||||||
|
|
||||||
{% block style %}
|
{% block style %}
|
||||||
<style>
|
<style>
|
||||||
.grid-container {
|
.grid-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat({{ column_count }}, auto);
|
grid-template-columns: repeat({{ flight_column_count }}, auto);
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
}
|
}
|
||||||
|
@ -36,19 +37,19 @@
|
||||||
<h3>flights</h3>
|
<h3>flights</h3>
|
||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
|
<div class="grid-item">reference</div>
|
||||||
|
<div class="grid-item">price</div>
|
||||||
<div class="grid-item text-end">date</div>
|
<div class="grid-item text-end">date</div>
|
||||||
<div class="grid-item">route</div>
|
<div class="grid-item">route</div>
|
||||||
<div class="grid-item">take-off</div>
|
<div class="grid-item">take-off</div>
|
||||||
<div class="grid-item">land</div>
|
<div class="grid-item">land</div>
|
||||||
<div class="grid-item">duration</div>
|
<div class="grid-item">duration</div>
|
||||||
<div class="grid-item">flight</div>
|
<div class="grid-item">flight</div>
|
||||||
<div class="grid-item">reference</div>
|
|
||||||
<div class="grid-item">tracking</div>
|
<div class="grid-item">tracking</div>
|
||||||
<div class="grid-item"></div>
|
<div class="grid-item">distance</div>
|
||||||
<div class="grid-item"></div>
|
|
||||||
|
|
||||||
{% for item in flights | sort(attribute="depart") %}
|
{% for item in flights %}
|
||||||
{{ flight_row(item) }}
|
{{ flight_booking_row(item) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ async def weekends() -> str:
|
||||||
def travel_list() -> str:
|
def travel_list() -> str:
|
||||||
"""Page showing a list of upcoming travel."""
|
"""Page showing a list of upcoming travel."""
|
||||||
data_dir = app.config["PERSONAL_DATA"]
|
data_dir = app.config["PERSONAL_DATA"]
|
||||||
flights = agenda.trip.load_flights(data_dir)
|
flights = agenda.trip.load_flight_bookings(data_dir)
|
||||||
trains = [
|
trains = [
|
||||||
item
|
item
|
||||||
for item in travel.parse_yaml("trains", data_dir)
|
for item in travel.parse_yaml("trains", data_dir)
|
||||||
|
|
Loading…
Reference in a new issue