- Eurostar scraper now fetches both Standard and Plus (PLUS class code)
prices/seats in a single API call; each service dict gains plus_price
and plus_seats fields
- GWR fares scraper gains fetch_advance() which makes two sets of
paginated calls (standard advance + first-class advance) and returns
cheapest per departure; shared _run_pages() generator reduces
duplication in fetch()
- New /api/advance_fares/<station_crs>/<travel_date> endpoint returns
advance fares as JSON, cached for 24 hours
- Results page gains NR ticket selector (Walk-on / Std Advance / 1st
Advance) and Eurostar selector (Standard / Plus); total column is
JS-computed from the selected combination with cheapest/priciest
highlighting
- Load advance prices button fetches the API lazily; if advance fares
are already cached they are embedded in the page and applied on load
so the button is hidden automatically
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes#5 — Goring & Streatley (GOR) was only showing Anytime Day Single
because ticket code CDS was not included in _WANTED_CODES.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Support any station with direct trains to Paddington; station CRS code
is now part of the URL (/results/<crs>/<slug>/<date>)
- Load station list from data/direct_to_paddington.tsv; show dropdown on
index page; 404 for unknown station codes
- Fetch live GWR walk-on fares via api.gwr.com for all stations (SSS/SVS/SDS
with restrictions already applied per train); cache 30 days
- Scrape Paddington arrival platform numbers from RTT
- Show unreachable morning Eurostars (before first reachable service only)
- Circle line: show actual KX St Pancras arrival times (not check-in estimate)
and add a second backup service in the transfer column
- Widen page max-width to 1100px for longer station names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>