Prefer ICAO flight number for some airlines
This commit is contained in:
parent
8cd2335630
commit
503d39e6b8
|
@ -60,11 +60,18 @@ def parse_yaml(travel_type: str, data_dir: str) -> TravelList:
|
||||||
def get_flights(data_dir: str) -> list[Event]:
|
def get_flights(data_dir: str) -> list[Event]:
|
||||||
"""Get travel events."""
|
"""Get travel events."""
|
||||||
bookings = parse_yaml("flights", data_dir)
|
bookings = parse_yaml("flights", data_dir)
|
||||||
|
airlines = parse_yaml("airlines", data_dir)
|
||||||
|
by_iata = {a["iata"]: a for a in airlines}
|
||||||
events = []
|
events = []
|
||||||
for booking in bookings:
|
for booking in bookings:
|
||||||
for item in booking["flights"]:
|
for item in booking["flights"]:
|
||||||
if not item["depart"].date():
|
if not item["depart"].date():
|
||||||
continue
|
continue
|
||||||
|
airline = by_iata[item["airline"]]
|
||||||
|
item["airline_code"] = airline[
|
||||||
|
"iata" if not airline.get("flight_number_prefer_icao") else "icao"
|
||||||
|
]
|
||||||
|
|
||||||
e = Event(
|
e = Event(
|
||||||
date=item["depart"],
|
date=item["depart"],
|
||||||
end_date=item.get("arrive"),
|
end_date=item.get("arrive"),
|
||||||
|
@ -95,7 +102,7 @@ def get_trains(data_dir: str) -> list[Event]:
|
||||||
|
|
||||||
def flight_number(flight: Leg) -> str:
|
def flight_number(flight: Leg) -> str:
|
||||||
"""Flight number."""
|
"""Flight number."""
|
||||||
airline_code = flight["airline"]
|
airline_code = flight["airline_code"]
|
||||||
# make sure this is the airline code, not the airline name
|
# make sure this is the airline code, not the airline name
|
||||||
assert " " not in airline_code and not any(c.islower() for c in airline_code)
|
assert " " not in airline_code and not any(c.islower() for c in airline_code)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,14 @@ from agenda import travel
|
||||||
from agenda.types import StrDict, Trip
|
from agenda.types import StrDict, Trip
|
||||||
|
|
||||||
|
|
||||||
|
class Airline(typing.TypedDict, total=False):
|
||||||
|
"""Airline."""
|
||||||
|
|
||||||
|
iata: str
|
||||||
|
icao: str
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
def load_travel(travel_type: str, plural: str, data_dir: str) -> list[StrDict]:
|
def load_travel(travel_type: str, plural: str, data_dir: str) -> list[StrDict]:
|
||||||
"""Read flight and train journeys."""
|
"""Read flight and train journeys."""
|
||||||
items = travel.parse_yaml(plural, data_dir)
|
items = travel.parse_yaml(plural, data_dir)
|
||||||
|
@ -85,7 +93,7 @@ def depart_datetime(item: StrDict) -> datetime:
|
||||||
|
|
||||||
|
|
||||||
def process_flight(
|
def process_flight(
|
||||||
flight: StrDict, iata: dict[str, str], airports: list[StrDict]
|
flight: StrDict, by_iata: dict[str, Airline], airports: list[StrDict]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add airport detail, airline name and distance to flight."""
|
"""Add airport detail, airline name and distance to flight."""
|
||||||
if flight["from"] in airports:
|
if flight["from"] in airports:
|
||||||
|
@ -93,7 +101,11 @@ def process_flight(
|
||||||
if flight["to"] in airports:
|
if flight["to"] in airports:
|
||||||
flight["to_airport"] = airports[flight["to"]]
|
flight["to_airport"] = airports[flight["to"]]
|
||||||
if "airline" in flight:
|
if "airline" in flight:
|
||||||
flight["airline_name"] = iata.get(flight["airline"], "[unknown]")
|
airline = by_iata[flight["airline"]]
|
||||||
|
flight["airline_detail"] = airline
|
||||||
|
flight["airline_code"] = airline[
|
||||||
|
"iata" if not airline.get("flight_number_prefer_icao") else "icao"
|
||||||
|
]
|
||||||
|
|
||||||
flight["distance"] = travel.flight_distance(flight)
|
flight["distance"] = travel.flight_distance(flight)
|
||||||
|
|
||||||
|
@ -102,11 +114,11 @@ def load_flight_bookings(data_dir: str) -> list[StrDict]:
|
||||||
"""Load flight bookings."""
|
"""Load flight bookings."""
|
||||||
bookings = load_travel("flight", "flights", data_dir)
|
bookings = load_travel("flight", "flights", 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")))
|
||||||
iata = {a["iata"]: a["name"] for a in airlines}
|
by_iata = {a["iata"]: a for a in airlines}
|
||||||
airports = travel.parse_yaml("airports", data_dir)
|
airports = travel.parse_yaml("airports", data_dir)
|
||||||
for booking in bookings:
|
for booking in bookings:
|
||||||
for flight in booking["flights"]:
|
for flight in booking["flights"]:
|
||||||
process_flight(flight, iata, airports)
|
process_flight(flight, by_iata, airports)
|
||||||
return bookings
|
return bookings
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for item in booking.flights %}
|
{% for item in booking.flights %}
|
||||||
{% set full_flight_number = item.airline + item.flight_number %}
|
{% set full_flight_number = item.airline_code + 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 %}
|
||||||
<div class="grid-item"></div>
|
<div class="grid-item"></div>
|
||||||
<div class="grid-item"></div>
|
<div class="grid-item"></div>
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro flight_row(item) %}
|
{% macro flight_row(item) %}
|
||||||
{% set full_flight_number = item.airline + item.flight_number %}
|
{% set full_flight_number = item.airline_code + 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 %}
|
||||||
<div class="grid-item text-end">{{ item.depart.strftime("%a, %d %b %Y") }}</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.from }} → {{ item.to }}</div>
|
||||||
|
@ -373,10 +373,10 @@
|
||||||
–
|
–
|
||||||
{{ e.end_loc }} {{ flag(trip, e.end_country.flag) }}
|
{{ e.end_loc }} {{ flag(trip, e.end_country.flag) }}
|
||||||
{% if e.element_type == "flight" %}
|
{% if e.element_type == "flight" %}
|
||||||
{% set full_flight_number = e.detail.airline + e.detail.flight_number %}
|
{% set full_flight_number = e.detail.airline_code + e.detail.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 %}
|
||||||
<span class="text-nowrap"><strong>airline:</strong> {{ e.detail.airline_name }}</span>
|
<span class="text-nowrap"><strong>airline:</strong> {{ e.detail.airline_name }}</span>
|
||||||
<span class="text-nowrap"><strong>flight number:</strong> {{ e.detail.airline }}{{ e.detail.flight_number }}</span>
|
<span class="text-nowrap"><strong>flight number:</strong> {{ full_flight_number }}</span>
|
||||||
{% if e.detail.duration %}
|
{% if e.detail.duration %}
|
||||||
<span class="text-nowrap"><strong>duration:</strong> {{ e.detail.duration }}</span>
|
<span class="text-nowrap"><strong>duration:</strong> {{ e.detail.duration }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -387,7 +387,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if e.element_type == "flight" %}
|
{% if e.element_type == "flight" %}
|
||||||
<a href="https://www.flightradar24.com/data/flights/{{ full_flight_number | lower }}">flightradar24</a>
|
<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="https://uk.flightaware.com/live/flight/{{ full_flight_number }}">FlightAware</a>
|
||||||
| <a href="{{ radarbox_url }}">radarbox</a>
|
| <a href="{{ radarbox_url }}">radarbox</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -162,9 +162,19 @@ def check_airlines() -> list[agenda.types.StrDict]:
|
||||||
airlines = agenda.travel.parse_yaml("airlines", data_dir)
|
airlines = agenda.travel.parse_yaml("airlines", data_dir)
|
||||||
print(len(airlines), "airlines")
|
print(len(airlines), "airlines")
|
||||||
for airline in airlines:
|
for airline in airlines:
|
||||||
assert airline.keys() == {"icao", "iata", "name"}
|
try:
|
||||||
assert len(airline["icao"]) == 3
|
keys = set(airline.keys())
|
||||||
assert len(airline["iata"]) == 2
|
keys.discard("flight_number_prefer_icao")
|
||||||
|
assert keys == {"icao", "iata", "name"}
|
||||||
|
iata, icao = airline["iata"], airline["icao"]
|
||||||
|
assert iata[0].isupper() and iata[1].isupper() or iata[1].isdigit()
|
||||||
|
assert icao.isupper()
|
||||||
|
assert len(iata) == 2 and len(icao) == 3
|
||||||
|
if "flight_number_prefer_icao" in airline:
|
||||||
|
assert isinstance(airline["flight_number_prefer_icao"], bool)
|
||||||
|
except AssertionError:
|
||||||
|
print(yaml.dump([airline]))
|
||||||
|
raise
|
||||||
|
|
||||||
return airlines
|
return airlines
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue