Cache provisional weekday timetables

This commit is contained in:
Edward Betts 2026-05-21 11:31:17 +01:00
parent 378d2484d0
commit bc7cb9cffa
6 changed files with 686 additions and 58 deletions

View file

@ -23,7 +23,7 @@
<div class="date-nav">
<a href="{{ prev_results_url }}"
class="btn-nav">&larr; Prev</a>
<strong>{{ travel_date_display }}{% if return_date %} to {{ return_date }}{% endif %}</strong>
<strong>{{ travel_date_display }}{% if return_date_display %} to {{ return_date_display }}{% endif %}</strong>
<a href="{{ next_results_url }}"
class="btn-nav">Next &rarr;</a>
</div>
@ -87,8 +87,11 @@
const DEFAULT_MAX_CONN = {{ default_max_connection }};
let TRIP_FARES = {{ trip_fares_json | safe }};
let ADVANCE_FARES = {{ advance_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 }};
const TIMETABLE_REFRESH_URL = {{ timetable_refresh_url|tojson }};
const HAS_PROVISIONAL_TIMETABLE = {{ 'true' if provisional_timetable else 'false' }};
let cachedAdvanceFares = ADVANCE_FARES;
let currentNrClass = '{{ nr_class }}';
let currentEsClass = '{{ es_class }}';
@ -158,6 +161,26 @@
}
}
function mergeWalkonFares(sectionId, fares) {
for (var key in TRIP_FARES) {
var row = TRIP_FARES[key];
if (row.section !== sectionId || !row.advance_key || !fares[row.advance_key]) continue;
var fare = fares[row.advance_key];
row.walkon = {price: fare.price, ticket: fare.ticket || ''};
}
}
function mergeEurostarPrices(prices) {
for (var key in prices) {
for (var rowKey in TRIP_FARES) {
var row = TRIP_FARES[rowKey];
if (rowKey !== key && row.eurostar_key !== key) continue;
if (prices[key].es_standard) row.es_standard = prices[key].es_standard;
if (prices[key].es_plus) row.es_plus = prices[key].es_plus;
}
}
}
function sectionNeedsAdvance(sectionId) {
for (var key in TRIP_FARES) {
var row = TRIP_FARES[key];
@ -306,7 +329,8 @@
html += '</span>';
totalSpan.innerHTML = html;
} else {
totalSpan.innerHTML = '';
var missing = !nrFare ? 'No NR fare' : 'No Eurostar fare';
totalSpan.innerHTML = '<span class="text-xs text-muted">' + missing + '</span>';
}
}
});
@ -315,6 +339,30 @@
function initialiseResultsPage() {
if (currentNrClass === 'advance_std' || currentNrClass === 'advance_1st') loadMissingAdvanceFares();
updateDisplay();
startTimetableRefresh();
}
function startTimetableRefresh() {
if (!HAS_PROVISIONAL_TIMETABLE || !TIMETABLE_REFRESH_URL || !window.EventSource) return;
var source = new EventSource(TIMETABLE_REFRESH_URL);
source.onmessage = function(event) {
var msg = JSON.parse(event.data);
if (msg.type === 'reload') {
source.close();
window.location.reload();
} else if (msg.type === 'eurostar_prices') {
mergeEurostarPrices(msg.prices);
updateDisplay();
} else if (msg.type === 'walkon_fares') {
mergeWalkonFares(msg.section, msg.fares);
updateDisplay();
} else if (msg.type === 'done' || msg.type === 'error') {
source.close();
}
};
source.onerror = function() {
source.close();
};
}
if (document.readyState === 'loading') {
@ -330,6 +378,9 @@
{% if from_cache %}
&nbsp;&middot;&nbsp; <span class="text-muted text-sm">(cached)</span>
{% endif %}
{% if provisional_timetable %}
&nbsp;&middot;&nbsp; <span class="text-muted text-sm">checking exact timetable</span>
{% endif %}
</p>
{% if error %}
<div class="alert alert-error">