Add car journeys to trips
This commit is contained in:
parent
bc7a2e89d0
commit
c6cb06b71e
9 changed files with 430 additions and 10 deletions
106
validate_yaml.py
106
validate_yaml.py
|
|
@ -38,7 +38,7 @@ def check_currency(item: agenda.types.StrDict) -> None:
|
|||
|
||||
|
||||
def check_country_code(
|
||||
item: agenda.types.StrDict, source: str, required: bool = True
|
||||
item: typing.Mapping[str, typing.Any], source: str, required: bool = True
|
||||
) -> None:
|
||||
"""Throw error if country code is missing or invalid."""
|
||||
country = item.get("country")
|
||||
|
|
@ -494,6 +494,109 @@ def check_buses() -> None:
|
|||
print(len(buses), "buses")
|
||||
|
||||
|
||||
def car_route_path(route: str) -> str:
|
||||
"""Return the absolute path for a car route filename."""
|
||||
route_filename = agenda.trip.route_filename_without_extension(route)
|
||||
if os.path.isabs(route_filename) or ".." in route_filename.split(os.path.sep):
|
||||
raise ValueError(f"invalid car route filename {route!r}")
|
||||
return os.path.join(data_dir, "car_routes", route_filename + ".geojson")
|
||||
|
||||
|
||||
def validate_car_journey_routes(cars: list[agenda.types.StrDict]) -> None:
|
||||
"""Check every car journey route references an existing GeoJSON file."""
|
||||
for car in cars:
|
||||
route = car.get("route")
|
||||
if not isinstance(route, str) or not route:
|
||||
pprint(car)
|
||||
print("car journey missing route")
|
||||
sys.exit(-1)
|
||||
try:
|
||||
route_path = car_route_path(route)
|
||||
except ValueError as exc:
|
||||
pprint(car)
|
||||
print(exc)
|
||||
sys.exit(-1)
|
||||
if not os.path.exists(route_path):
|
||||
pprint(car)
|
||||
print(f"car route does not exist: {route_path}")
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def validate_car_journey_dates(
|
||||
cars: list[agenda.types.StrDict], trip_list: list[agenda.types.Trip]
|
||||
) -> None:
|
||||
"""Check car journey dates fit the referenced trip."""
|
||||
trip_lookup = {trip.start: trip for trip in trip_list}
|
||||
prev_depart = None
|
||||
prev_car = None
|
||||
|
||||
for car in cars:
|
||||
for field in ("trip", "depart", "arrive"):
|
||||
if field not in car:
|
||||
pprint(car)
|
||||
print(f"car journey missing {field}")
|
||||
sys.exit(-1)
|
||||
|
||||
current_depart = normalize_datetime(car["depart"])
|
||||
arrive = normalize_datetime(car["arrive"])
|
||||
|
||||
if prev_depart and current_depart < prev_depart:
|
||||
assert prev_car is not None
|
||||
print("Out of order car journey found:")
|
||||
print(
|
||||
f" Previous: {prev_car.get('depart')} {prev_car.get('from', '')} -> {prev_car.get('to', '')}"
|
||||
)
|
||||
print(
|
||||
f" Current: {car.get('depart')} {car.get('from', '')} -> {car.get('to', '')}"
|
||||
)
|
||||
assert (
|
||||
False
|
||||
), "Car journeys are not in chronological order by departure time."
|
||||
prev_depart = current_depart
|
||||
prev_car = car
|
||||
|
||||
if arrive < current_depart:
|
||||
print("Invalid car journey found (arrive before depart):")
|
||||
print(f" {car.get('depart')} {car.get('from', '')} -> {car.get('to', '')}")
|
||||
print(f" arrive: {car.get('arrive')}")
|
||||
assert False, "Car journey arrival time is earlier than departure time."
|
||||
|
||||
trip_start = agenda.utils.as_date(car["trip"])
|
||||
trip = trip_lookup.get(trip_start)
|
||||
if trip is None:
|
||||
pprint(car)
|
||||
print(f"car journey references unknown trip {trip_start}")
|
||||
sys.exit(-1)
|
||||
|
||||
trip_end = trip.end or trip.start
|
||||
depart_date = agenda.utils.as_date(car["depart"])
|
||||
arrive_date = agenda.utils.as_date(car["arrive"])
|
||||
|
||||
if depart_date < trip.start or arrive_date > trip_end:
|
||||
pprint(car)
|
||||
print(
|
||||
"car journey dates outside trip range: "
|
||||
f"{depart_date} to {arrive_date}; trip {trip.start} to {trip_end}"
|
||||
)
|
||||
sys.exit(-1)
|
||||
|
||||
check_currency(car)
|
||||
|
||||
|
||||
def check_car_journeys() -> None:
|
||||
"""Check car journeys, route files and trip date consistency."""
|
||||
filepath = os.path.join(data_dir, "car_journeys.yaml")
|
||||
if not os.path.exists(filepath):
|
||||
print("0 car journeys")
|
||||
return
|
||||
|
||||
cars = agenda.travel.parse_yaml("car_journeys", data_dir)
|
||||
validate_car_journey_routes(cars)
|
||||
trip_list = agenda.trip.build_trip_list(data_dir)
|
||||
validate_car_journey_dates(cars, trip_list)
|
||||
print(len(cars), "car journeys")
|
||||
|
||||
|
||||
def check_airlines() -> list[agenda.types.StrDict]:
|
||||
"""Check airlines."""
|
||||
airlines: list[agenda.types.StrDict] = agenda.travel.parse_yaml(
|
||||
|
|
@ -521,6 +624,7 @@ def check_airlines() -> list[agenda.types.StrDict]:
|
|||
def check() -> None:
|
||||
"""Validate personal data YAML files."""
|
||||
airlines = check_airlines()
|
||||
check_car_journeys()
|
||||
check_trips()
|
||||
check_flights({airline["iata"] for airline in airlines})
|
||||
check_trains()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue