Compare commits
No commits in common. "6a601f5c145f9570a881b2f20c95898420901ddd" and "3747e83adeba3c99f69c6e14ef748d80a4cbccd6" have entirely different histories.
6a601f5c14
...
3747e83ade
5 changed files with 36 additions and 318 deletions
142
agenda/trip.py
142
agenda/trip.py
|
|
@ -130,8 +130,6 @@ def get_unbooked_flight_origin_iata(
|
||||||
UNBOOKED_RAIL_DESTINATIONS: dict[tuple[str, str], tuple[str, str]] = {
|
UNBOOKED_RAIL_DESTINATIONS: dict[tuple[str, str], tuple[str, str]] = {
|
||||||
("fr", "paris"): ("London St Pancras", "Paris Gare du Nord"),
|
("fr", "paris"): ("London St Pancras", "Paris Gare du Nord"),
|
||||||
}
|
}
|
||||||
EUROSTAR_LONDON_STATION = "London St Pancras"
|
|
||||||
EUROSTAR_HOME_FEEDER_ROUTE = ("Bristol Temple Meads", "London Paddington")
|
|
||||||
|
|
||||||
|
|
||||||
def load_station_lookup(data_dir: str) -> dict[str, StrDict]:
|
def load_station_lookup(data_dir: str) -> dict[str, StrDict]:
|
||||||
|
|
@ -170,71 +168,6 @@ def get_unbooked_rail_route(item: StrDict, data_dir: str) -> StrDict | None:
|
||||||
return route
|
return route
|
||||||
|
|
||||||
|
|
||||||
def build_train_route(
|
|
||||||
train_from: StrDict, train_to: StrDict, seen_geojson: set[str]
|
|
||||||
) -> StrDict | None:
|
|
||||||
"""Build a map route between two stations."""
|
|
||||||
geojson_filename = train_from.get("routes", {}).get(train_to["name"])
|
|
||||||
key = "_".join(["train"] + sorted([train_from["name"], train_to["name"]]))
|
|
||||||
if not geojson_filename:
|
|
||||||
return {
|
|
||||||
"type": "train",
|
|
||||||
"key": key,
|
|
||||||
"from": latlon_tuple(train_from),
|
|
||||||
"to": latlon_tuple(train_to),
|
|
||||||
}
|
|
||||||
|
|
||||||
if geojson_filename in seen_geojson:
|
|
||||||
return None
|
|
||||||
seen_geojson.add(geojson_filename)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"type": "train",
|
|
||||||
"key": key,
|
|
||||||
"geojson_filename": os.path.join("train_routes", geojson_filename),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def train_operator_is_eurostar(item: StrDict) -> bool:
|
|
||||||
"""Return True when a train item is operated by Eurostar."""
|
|
||||||
operator = item.get("operator")
|
|
||||||
return isinstance(operator, str) and operator.casefold() == "eurostar"
|
|
||||||
|
|
||||||
|
|
||||||
def is_eurostar_departure_from_london(train: StrDict) -> bool:
|
|
||||||
"""Return True when a train journey departs London St Pancras on Eurostar."""
|
|
||||||
if train.get("from") == EUROSTAR_LONDON_STATION and train_operator_is_eurostar(
|
|
||||||
train
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
|
|
||||||
for leg in train.get("legs", []):
|
|
||||||
if leg.get("from") == EUROSTAR_LONDON_STATION and train_operator_is_eurostar(
|
|
||||||
leg
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def get_eurostar_home_feeder_route(
|
|
||||||
trip: Trip, data_dir: str, seen_geojson: set[str]
|
|
||||||
) -> StrDict | None:
|
|
||||||
"""Return the assumed Bristol to Paddington route for London Eurostar trips."""
|
|
||||||
if not any(
|
|
||||||
t["type"] == "train" and is_eurostar_departure_from_london(t)
|
|
||||||
for t in trip.travel
|
|
||||||
):
|
|
||||||
return None
|
|
||||||
|
|
||||||
stations = load_station_lookup(data_dir)
|
|
||||||
from_station = stations.get(EUROSTAR_HOME_FEEDER_ROUTE[0])
|
|
||||||
to_station = stations.get(EUROSTAR_HOME_FEEDER_ROUTE[1])
|
|
||||||
if from_station is None or to_station is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return build_train_route(from_station, to_station, seen_geojson)
|
|
||||||
|
|
||||||
|
|
||||||
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: list[StrDict] = travel.parse_yaml(plural, data_dir)
|
items: list[StrDict] = travel.parse_yaml(plural, data_dir)
|
||||||
|
|
@ -755,37 +688,6 @@ def coordinate_dict(item: StrDict, coord_type: str) -> StrDict:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def coordinate_key(item: StrDict) -> tuple[str, str]:
|
|
||||||
"""Return the de-duplication key for a coordinate item."""
|
|
||||||
return (item["type"], item["name"])
|
|
||||||
|
|
||||||
|
|
||||||
def add_coordinate_if_missing(coordinates: list[StrDict], item: StrDict) -> None:
|
|
||||||
"""Append a coordinate item if the same type/name is not already present."""
|
|
||||||
key = coordinate_key(item)
|
|
||||||
if any(coordinate_key(existing) == key for existing in coordinates):
|
|
||||||
return
|
|
||||||
coordinates.append(item)
|
|
||||||
|
|
||||||
|
|
||||||
def add_coordinates_for_eurostar_home_feeder(
|
|
||||||
trip: Trip, coordinates: list[StrDict], data_dir: str
|
|
||||||
) -> None:
|
|
||||||
"""Add the assumed Bristol station pin for London Eurostar feeder travel."""
|
|
||||||
if not any(
|
|
||||||
t["type"] == "train" and is_eurostar_departure_from_london(t)
|
|
||||||
for t in trip.travel
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
stations = load_station_lookup(data_dir)
|
|
||||||
from_station = stations.get(EUROSTAR_HOME_FEEDER_ROUTE[0])
|
|
||||||
if from_station is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
add_coordinate_if_missing(coordinates, coordinate_dict(from_station, "station"))
|
|
||||||
|
|
||||||
|
|
||||||
def conference_free_days(trip: Trip) -> dict[str, tuple[int, int]]:
|
def conference_free_days(trip: Trip) -> dict[str, tuple[int, int]]:
|
||||||
"""Return (days_before, days_after) exploration days for each conference.
|
"""Return (days_before, days_after) exploration days for each conference.
|
||||||
|
|
||||||
|
|
@ -869,13 +771,7 @@ def read_geojson(data_dir: str, filename: str) -> str:
|
||||||
def get_trip_routes(trip: Trip, data_dir: str) -> list[StrDict]:
|
def get_trip_routes(trip: Trip, data_dir: str) -> list[StrDict]:
|
||||||
"""Get routes for given trip to show on map."""
|
"""Get routes for given trip to show on map."""
|
||||||
routes: list[StrDict] = []
|
routes: list[StrDict] = []
|
||||||
seen_geojson: set[str] = set()
|
seen_geojson = set()
|
||||||
eurostar_home_feeder_route = get_eurostar_home_feeder_route(
|
|
||||||
trip, data_dir, seen_geojson
|
|
||||||
)
|
|
||||||
if eurostar_home_feeder_route is not None:
|
|
||||||
routes.append(eurostar_home_feeder_route)
|
|
||||||
|
|
||||||
for t in trip.travel:
|
for t in trip.travel:
|
||||||
if t["type"] == "ferry":
|
if t["type"] == "ferry":
|
||||||
ferry_from, ferry_to = t["from_terminal"], t["to_terminal"]
|
ferry_from, ferry_to = t["from_terminal"], t["to_terminal"]
|
||||||
|
|
@ -948,9 +844,34 @@ def get_trip_routes(trip: Trip, data_dir: str) -> list[StrDict]:
|
||||||
if t["type"] == "train":
|
if t["type"] == "train":
|
||||||
for leg in t["legs"]:
|
for leg in t["legs"]:
|
||||||
train_from, train_to = leg["from_station"], leg["to_station"]
|
train_from, train_to = leg["from_station"], leg["to_station"]
|
||||||
route = build_train_route(train_from, train_to, seen_geojson)
|
geojson_filename = train_from.get("routes", {}).get(train_to["name"])
|
||||||
if route is not None:
|
key = "_".join(
|
||||||
routes.append(route)
|
["train"] + sorted([train_from["name"], train_to["name"]])
|
||||||
|
)
|
||||||
|
if not geojson_filename:
|
||||||
|
routes.append(
|
||||||
|
{
|
||||||
|
"type": "train",
|
||||||
|
"key": key,
|
||||||
|
"from": latlon_tuple(train_from),
|
||||||
|
"to": latlon_tuple(train_to),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if geojson_filename in seen_geojson:
|
||||||
|
continue
|
||||||
|
seen_geojson.add(geojson_filename)
|
||||||
|
|
||||||
|
routes.append(
|
||||||
|
{
|
||||||
|
"type": "train",
|
||||||
|
"key": key,
|
||||||
|
"geojson_filename": os.path.join(
|
||||||
|
"train_routes", geojson_filename
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if routes:
|
if routes:
|
||||||
return routes
|
return routes
|
||||||
|
|
@ -1003,15 +924,12 @@ def get_coordinates_and_routes(
|
||||||
seen_routes: set[str] = set()
|
seen_routes: set[str] = set()
|
||||||
for trip in trip_list:
|
for trip in trip_list:
|
||||||
for stop in collect_trip_coordinates(trip):
|
for stop in collect_trip_coordinates(trip):
|
||||||
key = coordinate_key(stop)
|
key = (stop["type"], stop["name"])
|
||||||
if key in seen_coordinates:
|
if key in seen_coordinates:
|
||||||
continue
|
continue
|
||||||
coordinates.append(stop)
|
coordinates.append(stop)
|
||||||
seen_coordinates.add(key)
|
seen_coordinates.add(key)
|
||||||
|
|
||||||
add_coordinates_for_eurostar_home_feeder(trip, coordinates, data_dir)
|
|
||||||
seen_coordinates = {coordinate_key(stop) for stop in coordinates}
|
|
||||||
|
|
||||||
for route in get_trip_routes(trip, data_dir):
|
for route in get_trip_routes(trip, data_dir):
|
||||||
if route["key"] in seen_routes:
|
if route["key"] in seen_routes:
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -59,46 +59,12 @@ function emojiIcon(emoji, zoom) {
|
||||||
|
|
||||||
function build_map(map_id, coordinates, routes) {
|
function build_map(map_id, coordinates, routes) {
|
||||||
var bounds = coordinates.map(function(station) { return [station.latitude, station.longitude]; });
|
var bounds = coordinates.map(function(station) { return [station.latitude, station.longitude]; });
|
||||||
|
if (bounds.length === 0) {
|
||||||
function addGeoJsonCoordinatesToBounds(geojsonCoordinates) {
|
|
||||||
if (!geojsonCoordinates) return;
|
|
||||||
if (typeof geojsonCoordinates[0] === "number" && typeof geojsonCoordinates[1] === "number") {
|
|
||||||
bounds.push([geojsonCoordinates[1], geojsonCoordinates[0]]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
geojsonCoordinates.forEach(addGeoJsonCoordinatesToBounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addGeoJsonGeometryToBounds(geometry) {
|
|
||||||
if (!geometry) return;
|
|
||||||
if (geometry.type === "GeometryCollection") {
|
|
||||||
geometry.geometries.forEach(addGeoJsonGeometryToBounds);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addGeoJsonCoordinatesToBounds(geometry.coordinates);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addGeoJsonToBounds(geojson) {
|
|
||||||
if (!geojson) return;
|
|
||||||
if (geojson.type === "FeatureCollection") {
|
|
||||||
geojson.features.forEach(function(feature) {
|
|
||||||
addGeoJsonGeometryToBounds(feature.geometry);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (geojson.type === "Feature") {
|
|
||||||
addGeoJsonGeometryToBounds(geojson.geometry);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addGeoJsonGeometryToBounds(geojson);
|
|
||||||
}
|
|
||||||
|
|
||||||
routes.forEach(function(r) {
|
routes.forEach(function(r) {
|
||||||
if (r.from) bounds.push(r.from);
|
if (r.from) bounds.push(r.from);
|
||||||
if (r.to) bounds.push(r.to);
|
if (r.to) bounds.push(r.to);
|
||||||
if (r.geojson) addGeoJsonToBounds(JSON.parse(r.geojson));
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
var map = bounds.length > 0
|
var map = bounds.length > 0
|
||||||
? L.map(map_id).fitBounds(bounds)
|
? L.map(map_id).fitBounds(bounds)
|
||||||
: L.map(map_id).setView([20, 0], 2);
|
: L.map(map_id).setView([20, 0], 2);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from datetime import date, datetime, timezone
|
||||||
|
|
||||||
import agenda.trip
|
import agenda.trip
|
||||||
import pytest
|
import pytest
|
||||||
from agenda.types import StrDict, Trip
|
from agenda.types import Trip
|
||||||
from web_view import app
|
from web_view import app
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -171,150 +171,6 @@ def test_get_trip_routes_assumes_unbooked_paris_trip_is_by_train(
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_get_trip_routes_adds_bristol_feeder_for_london_eurostar(
|
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
|
||||||
) -> None:
|
|
||||||
"""Booked London Eurostar trips should show the assumed Bristol rail feeder."""
|
|
||||||
london_st_pancras = {
|
|
||||||
"name": "London St Pancras",
|
|
||||||
"latitude": 51.531921,
|
|
||||||
"longitude": -0.126361,
|
|
||||||
"routes": {"Paris Gare du Nord": "London_St_Pancras_to_Paris_Gare_du_Nord"},
|
|
||||||
}
|
|
||||||
paris_gare_du_nord = {
|
|
||||||
"name": "Paris Gare du Nord",
|
|
||||||
"latitude": 48.88111111111111,
|
|
||||||
"longitude": 2.355277777777778,
|
|
||||||
"routes": {"London St Pancras": "London_St_Pancras_to_Paris_Gare_du_Nord"},
|
|
||||||
}
|
|
||||||
bristol_temple_meads = {
|
|
||||||
"name": "Bristol Temple Meads",
|
|
||||||
"latitude": 51.449,
|
|
||||||
"longitude": -2.581,
|
|
||||||
"routes": {"London Paddington": "gwml"},
|
|
||||||
}
|
|
||||||
london_paddington = {
|
|
||||||
"name": "London Paddington",
|
|
||||||
"latitude": 51.516,
|
|
||||||
"longitude": -0.176,
|
|
||||||
"routes": {"Bristol Temple Meads": "gwml"},
|
|
||||||
}
|
|
||||||
trip = Trip(
|
|
||||||
start=date(2026, 7, 20),
|
|
||||||
travel=[
|
|
||||||
{
|
|
||||||
"type": "train",
|
|
||||||
"from": "London St Pancras",
|
|
||||||
"to": "Paris Gare du Nord",
|
|
||||||
"operator": "Eurostar",
|
|
||||||
"from_station": london_st_pancras,
|
|
||||||
"to_station": paris_gare_du_nord,
|
|
||||||
"legs": [
|
|
||||||
{
|
|
||||||
"from": "London St Pancras",
|
|
||||||
"to": "Paris Gare du Nord",
|
|
||||||
"operator": "Eurostar",
|
|
||||||
"from_station": london_st_pancras,
|
|
||||||
"to_station": paris_gare_du_nord,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
)
|
|
||||||
stations = [
|
|
||||||
london_st_pancras,
|
|
||||||
paris_gare_du_nord,
|
|
||||||
bristol_temple_meads,
|
|
||||||
london_paddington,
|
|
||||||
]
|
|
||||||
|
|
||||||
def fake_parse_yaml(name: str, data_dir: str) -> object:
|
|
||||||
if name == "stations":
|
|
||||||
return stations
|
|
||||||
raise AssertionError(f"unexpected YAML load: {name}")
|
|
||||||
|
|
||||||
monkeypatch.setattr(agenda.trip.travel, "parse_yaml", fake_parse_yaml)
|
|
||||||
|
|
||||||
routes = agenda.trip.get_trip_routes(trip, "/tmp/personal-data")
|
|
||||||
|
|
||||||
assert routes == [
|
|
||||||
{
|
|
||||||
"type": "train",
|
|
||||||
"key": "train_Bristol Temple Meads_London Paddington",
|
|
||||||
"geojson_filename": "train_routes/gwml",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "train",
|
|
||||||
"key": "train_London St Pancras_Paris Gare du Nord",
|
|
||||||
"geojson_filename": "train_routes/London_St_Pancras_to_Paris_Gare_du_Nord",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_coordinates_for_eurostar_home_feeder_adds_bristol_station(
|
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
|
||||||
) -> None:
|
|
||||||
"""London Eurostar trips should get an assumed Bristol station pin."""
|
|
||||||
london_st_pancras = {
|
|
||||||
"name": "London St Pancras",
|
|
||||||
"latitude": 51.531921,
|
|
||||||
"longitude": -0.126361,
|
|
||||||
}
|
|
||||||
paris_gare_du_nord = {
|
|
||||||
"name": "Paris Gare du Nord",
|
|
||||||
"latitude": 48.88111111111111,
|
|
||||||
"longitude": 2.355277777777778,
|
|
||||||
}
|
|
||||||
bristol_temple_meads = {
|
|
||||||
"name": "Bristol Temple Meads",
|
|
||||||
"latitude": 51.449,
|
|
||||||
"longitude": -2.581,
|
|
||||||
}
|
|
||||||
trip = Trip(
|
|
||||||
start=date(2026, 7, 20),
|
|
||||||
travel=[
|
|
||||||
{
|
|
||||||
"type": "train",
|
|
||||||
"from": "London St Pancras",
|
|
||||||
"to": "Paris Gare du Nord",
|
|
||||||
"operator": "Eurostar",
|
|
||||||
"from_station": london_st_pancras,
|
|
||||||
"to_station": paris_gare_du_nord,
|
|
||||||
"legs": [
|
|
||||||
{
|
|
||||||
"from": "London St Pancras",
|
|
||||||
"to": "Paris Gare du Nord",
|
|
||||||
"operator": "Eurostar",
|
|
||||||
"from_station": london_st_pancras,
|
|
||||||
"to_station": paris_gare_du_nord,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
def fake_parse_yaml(name: str, data_dir: str) -> object:
|
|
||||||
if name == "stations":
|
|
||||||
return [london_st_pancras, paris_gare_du_nord, bristol_temple_meads]
|
|
||||||
raise AssertionError(f"unexpected YAML load: {name}")
|
|
||||||
|
|
||||||
monkeypatch.setattr(agenda.trip.travel, "parse_yaml", fake_parse_yaml)
|
|
||||||
|
|
||||||
coordinates: list[StrDict] = []
|
|
||||||
agenda.trip.add_coordinates_for_eurostar_home_feeder(
|
|
||||||
trip, coordinates, "/tmp/personal-data"
|
|
||||||
)
|
|
||||||
|
|
||||||
assert coordinates == [
|
|
||||||
{
|
|
||||||
"name": "Bristol Temple Meads",
|
|
||||||
"type": "station",
|
|
||||||
"latitude": 51.449,
|
|
||||||
"longitude": -2.581,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_load_cars_infers_route_labels_and_home_marker(
|
def test_load_cars_infers_route_labels_and_home_marker(
|
||||||
tmp_path: pathlib.Path,
|
tmp_path: pathlib.Path,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ data_dir = config.PERSONAL_DATA
|
||||||
currencies = set(config.CURRENCIES + ["GBP"])
|
currencies = set(config.CURRENCIES + ["GBP"])
|
||||||
|
|
||||||
LatLon = Tuple[float, float]
|
LatLon = Tuple[float, float]
|
||||||
MAX_TRIP_NIGHTS = 60
|
|
||||||
|
|
||||||
|
|
||||||
def check_currency(item: agenda.types.StrDict) -> None:
|
def check_currency(item: agenda.types.StrDict) -> None:
|
||||||
|
|
@ -103,22 +102,6 @@ def ranges_overlap(
|
||||||
return start_a < end_b and start_b < end_a
|
return start_a < end_b and start_b < end_a
|
||||||
|
|
||||||
|
|
||||||
def check_trip_duration(trip: agenda.types.Trip) -> None:
|
|
||||||
"""Check trip duration is within the expected maximum."""
|
|
||||||
if trip.end is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
nights = (trip.end - trip.start).days
|
|
||||||
if nights <= MAX_TRIP_NIGHTS:
|
|
||||||
return
|
|
||||||
|
|
||||||
url = f"https://edwardbetts.com/agenda/trip/{trip.start.isoformat()}"
|
|
||||||
print(f"Trip is too long: {url}")
|
|
||||||
print(f" {trip.title}")
|
|
||||||
print(f" {trip.start.isoformat()} to {trip.end.isoformat()}: {nights} nights")
|
|
||||||
assert False, f"Trip is {nights} nights; maximum is {MAX_TRIP_NIGHTS}"
|
|
||||||
|
|
||||||
|
|
||||||
def check_trips() -> None:
|
def check_trips() -> None:
|
||||||
"""Check trips and ensure they are in chronological order."""
|
"""Check trips and ensure they are in chronological order."""
|
||||||
filepath = os.path.join(data_dir, "trips.yaml")
|
filepath = os.path.join(data_dir, "trips.yaml")
|
||||||
|
|
@ -147,8 +130,6 @@ def check_trips() -> None:
|
||||||
print(len(trip_list), "trips")
|
print(len(trip_list), "trips")
|
||||||
|
|
||||||
for trip in trip_list:
|
for trip in trip_list:
|
||||||
check_trip_duration(trip)
|
|
||||||
|
|
||||||
if not trip.accommodation or not trip.conferences:
|
if not trip.accommodation or not trip.conferences:
|
||||||
continue
|
continue
|
||||||
accommodation_entries: list[
|
accommodation_entries: list[
|
||||||
|
|
|
||||||
|
|
@ -1365,9 +1365,6 @@ def trip_page(start: str) -> str:
|
||||||
agenda.trip.add_coordinates_for_unbooked_flights(
|
agenda.trip.add_coordinates_for_unbooked_flights(
|
||||||
routes, coordinates, app.config["PERSONAL_DATA"]
|
routes, coordinates, app.config["PERSONAL_DATA"]
|
||||||
)
|
)
|
||||||
agenda.trip.add_coordinates_for_eurostar_home_feeder(
|
|
||||||
trip, coordinates, app.config["PERSONAL_DATA"]
|
|
||||||
)
|
|
||||||
|
|
||||||
for route in routes:
|
for route in routes:
|
||||||
if "geojson_filename" in route:
|
if "geojson_filename" in route:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue