Initial commit.
This commit is contained in:
commit
a8e0bd39e5
16 changed files with 981 additions and 0 deletions
96
app.py
Normal file
96
app.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import asyncio
|
||||
from flask import Flask, render_template, redirect, url_for, request
|
||||
from datetime import date, timedelta
|
||||
|
||||
from cache import get_cached, set_cached
|
||||
import scraper.eurostar as eurostar_scraper
|
||||
import scraper.realtime_trains as rtt_scraper
|
||||
from trip_planner import combine_trips
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
DESTINATIONS = {
|
||||
'paris': 'Paris Gare du Nord',
|
||||
'brussels': 'Brussels Midi',
|
||||
'lille': 'Lille Europe',
|
||||
'amsterdam': 'Amsterdam Centraal',
|
||||
}
|
||||
|
||||
|
||||
async def _fetch_both(destination: str, travel_date: str, user_agent: str):
|
||||
"""Fetch GWR trains and Eurostar times simultaneously."""
|
||||
gwr, es = await asyncio.gather(
|
||||
rtt_scraper.fetch(travel_date, user_agent),
|
||||
eurostar_scraper.fetch(destination, travel_date, user_agent),
|
||||
return_exceptions=True,
|
||||
)
|
||||
return gwr, es
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
today = date.today().isoformat()
|
||||
return render_template('index.html', destinations=DESTINATIONS, today=today)
|
||||
|
||||
|
||||
@app.route('/results/<slug>/<travel_date>')
|
||||
def results(slug, travel_date):
|
||||
destination = DESTINATIONS.get(slug)
|
||||
if not destination or not travel_date:
|
||||
return redirect(url_for('index'))
|
||||
|
||||
user_agent = request.headers.get('User-Agent', rtt_scraper.DEFAULT_UA)
|
||||
|
||||
cache_key = f"{travel_date}_{destination}"
|
||||
cached = get_cached(cache_key)
|
||||
|
||||
error = None
|
||||
if cached:
|
||||
gwr_trains = cached['gwr']
|
||||
eurostar_trains = cached['eurostar']
|
||||
from_cache = True
|
||||
else:
|
||||
from_cache = False
|
||||
gwr_result, es_result = asyncio.run(_fetch_both(destination, travel_date, user_agent))
|
||||
|
||||
if isinstance(gwr_result, Exception):
|
||||
gwr_trains = []
|
||||
error = f"Could not fetch GWR trains: {gwr_result}"
|
||||
else:
|
||||
gwr_trains = gwr_result
|
||||
|
||||
if isinstance(es_result, Exception):
|
||||
eurostar_trains = []
|
||||
msg = f"Could not fetch Eurostar times: {es_result}"
|
||||
error = f"{error}; {msg}" if error else msg
|
||||
else:
|
||||
eurostar_trains = es_result
|
||||
|
||||
if gwr_trains or eurostar_trains:
|
||||
set_cached(cache_key, {'gwr': gwr_trains, 'eurostar': eurostar_trains})
|
||||
|
||||
trips = combine_trips(gwr_trains, eurostar_trains, travel_date)
|
||||
|
||||
dt = date.fromisoformat(travel_date)
|
||||
prev_date = (dt - timedelta(days=1)).isoformat()
|
||||
next_date = (dt + timedelta(days=1)).isoformat()
|
||||
travel_date_display = dt.strftime('%A %-d %B %Y')
|
||||
|
||||
return render_template(
|
||||
'results.html',
|
||||
trips=trips,
|
||||
destination=destination,
|
||||
travel_date=travel_date,
|
||||
slug=slug,
|
||||
prev_date=prev_date,
|
||||
next_date=next_date,
|
||||
travel_date_display=travel_date_display,
|
||||
gwr_count=len(gwr_trains),
|
||||
eurostar_count=len(eurostar_trains),
|
||||
from_cache=from_cache,
|
||||
error=error,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
Loading…
Add table
Add a link
Reference in a new issue