diff --git a/app.py b/app.py index b29439c..9afcbc0 100644 --- a/app.py +++ b/app.py @@ -129,6 +129,13 @@ def _nr_weekday_cache_key(direction: str, station_crs: str, section_date: str) - ) +def _walkon_weekday_cache_key(direction: str, station_crs: str, section_date: str) -> str: + return ( + f"weekday_gwr_fares_{direction}_{station_crs}_" + f"{_nr_timetable_period_key(section_date)}_{_weekday_for(section_date)}" + ) + + def _eurostar_exact_cache_key(direction: str, section_date: str, destination: str) -> str: return f"eurostar_{direction}_{section_date}_{destination}" @@ -517,6 +524,9 @@ def _results(station_crs, slug, travel_date, journey_type, return_date): fare_direction = "to_paddington" if direction == "outbound" else "from_paddington" gwr_fares = {} cached_advance = get_cached(advance_cache_key, ttl=24 * 3600) + walkon_weekday_key = _walkon_weekday_cache_key(rtt_direction, station_crs, section_date) + exact_walkon = get_cached(gwr_cache_key, ttl=30 * 24 * 3600) + cached_walkon = exact_walkon if exact_walkon is not None else get_cached(walkon_weekday_key) if direction == "outbound": trips = combine_trips( @@ -603,6 +613,7 @@ def _results(station_crs, slug, travel_date, journey_type, return_date): "max_connection": section_max_connection, "provisional_timetable": nr_provisional or es_provisional, "advance_fares": cached_advance, + "cached_walkon_fares": cached_walkon, "walkon_api_url": url_for( "api_walkon_fares", station_crs=station_crs, @@ -755,11 +766,13 @@ def _results(station_crs, slug, travel_date, journey_type, return_date): trip_fares = {} advance_fares = {} + walkon_cached_fares = {} walkon_api_urls = {} advance_api_urls = {} advance_stream_urls = {} for section in sections: advance_fares[section["id"]] = section["advance_fares"] + walkon_cached_fares[section["id"]] = section.get("cached_walkon_fares") walkon_api_urls[section["id"]] = section["walkon_api_url"] advance_api_urls[section["id"]] = section["advance_api_url"] advance_stream_urls[section["id"]] = section["advance_stream_url"] @@ -860,6 +873,7 @@ def _results(station_crs, slug, travel_date, journey_type, return_date): section_directions_json=json.dumps(section_directions), trip_fares_json=json.dumps(trip_fares), advance_fares_json=json.dumps(advance_fares), + walkon_cached_fares_json=json.dumps(walkon_cached_fares), walkon_api_urls_json=json.dumps(walkon_api_urls), advance_api_urls_json=json.dumps(advance_api_urls), advance_stream_urls_json=json.dumps(advance_stream_urls), @@ -918,8 +932,11 @@ def api_walkon_fares(station_crs, travel_date): if direction not in {"to_paddington", "from_paddington"}: direction = "to_paddington" cache_key = f"gwr_fares_{direction}_{station_crs}_{travel_date}" + weekday_key = _walkon_weekday_cache_key(direction, station_crs, travel_date) cached = get_cached(cache_key, ttl=30 * 24 * 3600) if cached is not None: + if get_cached(weekday_key) is None: + set_cached(weekday_key, cached) return jsonify(cached) try: fares = ( @@ -928,6 +945,7 @@ def api_walkon_fares(station_crs, travel_date): else gwr_fares_scraper.fetch(station_crs, travel_date, direction=direction) ) set_cached(cache_key, fares) + set_cached(weekday_key, fares) return jsonify(fares) except Exception as e: return jsonify({"error": str(e)}), 500 diff --git a/templates/results.html b/templates/results.html index afe5d03..093104a 100644 --- a/templates/results.html +++ b/templates/results.html @@ -142,6 +142,7 @@ const DEFAULT_MIN_CONN_IN = {{ default_inbound_min_connection }}; let TRIP_FARES = {{ trip_fares_json | safe }}; let ADVANCE_FARES = {{ advance_fares_json | safe }}; + const WALKON_CACHED_FARES = {{ walkon_cached_fares_json | safe }}; let WALKON_API_URLS = {{ walkon_api_urls_json | safe }}; let ADVANCE_API_URLS = {{ advance_api_urls_json | safe }}; let ADVANCE_STREAM_URLS = {{ advance_stream_urls_json | safe }}; @@ -566,8 +567,17 @@ return c === 'advance_std' || c === 'advance_1st'; }); if (needsAdvance) loadMissingAdvanceFares(); + /* Pre-populate walk-on fares from weekday cache so prices show immediately */ + var hasPreloaded = false; + for (var sid in WALKON_CACHED_FARES) { + if (WALKON_CACHED_FARES[sid]) { mergeWalkonFares(sid, WALKON_CACHED_FARES[sid]); hasPreloaded = true; } + } updateDisplay(); updateRowHighlights(); + if (hasPreloaded) { + var loadingEl = document.getElementById('walkon-loading'); + if (loadingEl) loadingEl.innerHTML = 'Verifying fares'; + } loadWalkonFares(); startTimetableRefresh(); }