Improve progressive results loading

This commit is contained in:
Edward Betts 2026-05-21 09:52:58 +01:00
parent 9691632f65
commit 378d2484d0
6 changed files with 369 additions and 60 deletions

128
app.py
View file

@ -113,6 +113,35 @@ def _parse_connection(raw, default, valid_set):
return val if val in valid_set else default
def _results_url(
station_crs,
slug,
travel_date,
journey_type="outbound",
return_date=None,
**params,
):
params = {k: v for k, v in params.items() if v is not None}
if journey_type == "return":
return url_for(
"return_results",
station_crs=station_crs,
slug=slug,
travel_date=travel_date,
return_date=return_date,
**params,
)
if journey_type == "inbound":
params["journey_type"] = "inbound"
return url_for(
"results",
station_crs=station_crs,
slug=slug,
travel_date=travel_date,
**params,
)
@app.route("/search")
def search():
slug = request.args.get("destination", "")
@ -150,12 +179,11 @@ def search():
return_date = ""
if slug in DESTINATIONS and travel_date and (journey_type != "return" or return_date):
return redirect(
url_for(
"results",
_results_url(
station_crs=station_crs,
slug=slug,
travel_date=travel_date,
journey_type=None if journey_type == "outbound" else journey_type,
journey_type=journey_type,
return_date=return_date if journey_type == "return" else None,
min_connection=None if min_conn == default_min else min_conn,
max_connection=None if max_conn == default_max else max_conn,
@ -168,6 +196,21 @@ def search():
@app.route("/results/<station_crs>/<slug>/<travel_date>")
def results(station_crs, slug, travel_date):
return _results(
station_crs,
slug,
travel_date,
request.args.get("journey_type", "outbound"),
request.args.get("return_date"),
)
@app.route("/results/<station_crs>/<slug>/<travel_date>/return/<return_date>")
def return_results(station_crs, slug, travel_date, return_date):
return _results(station_crs, slug, travel_date, "return", return_date)
def _results(station_crs, slug, travel_date, journey_type, return_date):
departure_station_name = STATION_BY_CRS.get(station_crs)
if departure_station_name is None:
abort(404)
@ -175,10 +218,8 @@ def results(station_crs, slug, travel_date):
if not destination or not travel_date:
return redirect(url_for("index"))
journey_type = request.args.get("journey_type", "outbound")
if journey_type not in VALID_JOURNEY_TYPES:
journey_type = "outbound"
return_date = request.args.get("return_date")
if journey_type == "return":
try:
if not return_date or date.fromisoformat(return_date) < date.fromisoformat(travel_date):
@ -205,6 +246,38 @@ def results(station_crs, slug, travel_date):
if es_class not in VALID_ES_CLASSES:
es_class = DEFAULT_ES_CLASS
if (
request.args.get("render") != "full"
and not (
app.config.get("TESTING")
and request.args.get("progressive") != "1"
)
):
dt = date.fromisoformat(travel_date)
travel_date_display = dt.strftime("%A %-d %B %Y")
full_args = dict(request.args)
full_args.pop("progressive", None)
full_args.pop("journey_type", None)
full_args.pop("return_date", None)
full_args["render"] = "full"
return render_template(
"results_loading.html",
destination=destination,
departure_station_name=departure_station_name,
journey_type=journey_type,
travel_date_display=travel_date_display,
return_date=return_date,
full_results_url=_results_url(
station_crs=station_crs,
slug=slug,
travel_date=travel_date,
journey_type=journey_type,
return_date=return_date,
**full_args,
),
index_url=url_for("index"),
)
user_agent = request.headers.get("User-Agent", rtt_scraper.DEFAULT_UA)
error_messages = []
from_cache_parts = []
@ -413,6 +486,46 @@ def results(station_crs, slug, travel_date):
url_max = None if max_connection == default_max else max_connection
url_nr = None if nr_class == DEFAULT_NR_CLASS else nr_class
url_es = None if es_class == DEFAULT_ES_CLASS else es_class
common_url_args = {
"journey_type": journey_type,
"return_date": return_date,
"min_connection": url_min,
"max_connection": url_max,
"nr_class": url_nr,
"es_class": url_es,
}
prev_results_url = _results_url(
station_crs,
slug,
prev_date,
**common_url_args,
)
next_results_url = _results_url(
station_crs,
slug,
next_date,
**common_url_args,
)
destination_links = [
(
destination_slug,
destination_name,
_results_url(
station_crs,
destination_slug,
travel_date,
**common_url_args,
),
)
for destination_slug, destination_name in DESTINATIONS.items()
]
results_base_url = _results_url(
station_crs,
slug,
travel_date,
journey_type=journey_type,
return_date=return_date,
)
trip_fares = {}
advance_fares = {}
@ -465,6 +578,10 @@ def results(station_crs, slug, travel_date):
departure_station_name=departure_station_name,
prev_date=prev_date,
next_date=next_date,
prev_results_url=prev_results_url,
next_results_url=next_results_url,
destination_links=destination_links,
results_base_url=results_base_url,
travel_date_display=travel_date_display,
gwr_count=sum(section["gwr_count"] for section in sections),
eurostar_count=sum(section["eurostar_count"] for section in sections),
@ -484,7 +601,6 @@ def results(station_crs, slug, travel_date):
es_class=es_class,
url_nr_class=url_nr,
url_es_class=url_es,
url_journey_type=None if journey_type == "outbound" else journey_type,
trip_fares_json=json.dumps(trip_fares),
advance_fares_json=json.dumps(advance_fares),
advance_api_urls_json=json.dumps(advance_api_urls),