Improvements

This commit is contained in:
Edward Betts 2023-09-11 07:00:20 +01:00
parent 7599f655ad
commit b6f0c88320
7 changed files with 139 additions and 27 deletions

96
main.py
View file

@ -8,6 +8,7 @@ import os.path
import re
import sys
import traceback
import collections
from datetime import date, datetime, timedelta
from typing import Any
@ -37,6 +38,7 @@ routes = {
("PORTSMOUTH", "ST MALO"),
("PORTSMOUTH", "LE HAVRE"),
("POOLE", "CHERBOURG"),
("PLYMOUTH", "ROSCOFF"),
],
"return": [
("CAEN", "PORTSMOUTH"),
@ -44,6 +46,7 @@ routes = {
("ST MALO", "PORTSMOUTH"),
("LE HAVRE", "PORTSMOUTH"),
("CHERBOURG", "POOLE"),
("ROSCOFF", "PLYMOUTH"),
],
}
@ -139,7 +142,13 @@ def start() -> Response | str:
return flask.render_template("index.html")
def cabins_url(dep: str, arr: str, crossing: dict[str, Any], ticket_tier: str) -> str:
def cabins_url(
dep: str,
arr: str,
crossing: dict[str, Any],
ticket_tier: str,
rear_mounted_bike_carrier: bool,
) -> str:
"""Generate a URL for the cabins on a given crossing."""
dt = datetime.fromisoformat(crossing["departureDateTime"]["iso"])
utc_dt = dt.astimezone(pytz.utc)
@ -155,6 +164,7 @@ def cabins_url(dep: str, arr: str, crossing: dict[str, Any], ticket_tier: str) -
ticket_tier=ticket_tier,
adults=adults_str,
small_dogs=small_dogs_str,
rear_mounted_bike_carrier=("true" if rear_mounted_bike_carrier else None),
)
@ -195,9 +205,12 @@ def get_prices_with_cache(
adults: int,
small_dogs: int,
refresh: bool = False,
rear_mounted_bike_carrier: bool = False,
) -> PriceData:
"""Get price data using cache."""
params = f"{direction}_{start}_{end}_{adults}_{small_dogs}"
params = (
f"{direction}_{start}_{end}_{adults}_{small_dogs}_{rear_mounted_bike_carrier}"
)
if not refresh:
data = check_cache_for_prices(params)
if data:
@ -217,6 +230,7 @@ def get_prices_with_cache(
vehicle,
adults,
small_dogs,
rear_mounted_bike_carrier,
)["crossings"],
)
for dep, arr in selection
@ -228,7 +242,10 @@ def get_prices_with_cache(
return all_data
def read_pax() -> dict[str, int]:
Pax = collections.namedtuple("Pax", ["adults", "small_dogs"])
def read_pax() -> Pax:
"""Get the number of adults and dogs that are travelling."""
config_adults = int(ferry_config.get("pax", "adults"))
config_dogs = int(ferry_config.get("pax", "dogs"))
@ -239,7 +256,14 @@ def read_pax() -> dict[str, int]:
small_dogs_str = flask.request.args.get("small_dogs")
small_dogs = int(small_dogs_str) if small_dogs_str else config_dogs
return {"adults": adults, "small_dogs": small_dogs}
return Pax(adults=adults, small_dogs=small_dogs)
pax_options = [
{"pax": Pax(adults=1, small_dogs=0), "label": "1 adult"},
{"pax": Pax(adults=2, small_dogs=0), "label": "2 adults"},
{"pax": Pax(adults=2, small_dogs=1), "label": "2 adults and a dog"},
]
def build_outbound(section: str) -> str:
@ -247,6 +271,9 @@ def build_outbound(section: str) -> str:
start = ferry_config.get(section, "from")
end = ferry_config.get(section, "to")
refresh = bool(flask.request.args.get("refresh"))
rear_mounted_bike_carrier = (
flask.request.args.get("rear_mounted_bike_carrier") == "true"
)
pax = read_pax()
@ -257,9 +284,10 @@ def build_outbound(section: str) -> str:
start,
end,
routes["outbound"],
pax["adults"],
pax["small_dogs"],
pax.adults,
pax.small_dogs,
refresh,
rear_mounted_bike_carrier,
)
return flask.render_template(
@ -274,6 +302,9 @@ def build_outbound(section: str) -> str:
get_duration=get_duration,
time_delta=-60,
format_pet_options=format_pet_options,
pax=pax,
pax_options=pax_options,
rear_mounted_bike_carrier=rear_mounted_bike_carrier,
)
@ -283,6 +314,9 @@ def build_return(section: str) -> str:
end = ferry_config.get(section, "to")
refresh = bool(flask.request.args.get("refresh"))
pax = read_pax()
rear_mounted_bike_carrier = (
flask.request.args.get("rear_mounted_bike_carrier") == "true"
)
direction = section[:-1] if section[-1].isdigit() else section
@ -291,9 +325,10 @@ def build_return(section: str) -> str:
start,
end,
routes["return"],
pax["adults"],
pax["small_dogs"],
pax.adults,
pax.small_dogs,
refresh,
rear_mounted_bike_carrier,
)
return flask.render_template(
@ -308,6 +343,9 @@ def build_return(section: str) -> str:
get_duration=get_duration,
time_delta=60,
format_pet_options=format_pet_options,
pax=pax,
pax_options=pax_options,
rear_mounted_bike_carrier=rear_mounted_bike_carrier,
)
@ -350,11 +388,16 @@ def format_pet_options(o: dict[str, bool]) -> list[str]:
def get_accommodations_with_cache(
dep: str, arr: str, d: str, ticket_tier: str, refresh: bool = False
dep: str,
arr: str,
d: str,
ticket_tier: str,
refresh: bool = False,
rear_mounted_bike_carrier: bool = False,
) -> dict[str, list[dict[str, Any]]]:
pax = read_pax()
params = f"{dep}_{arr}_{d}_{ticket_tier}_{pax['adults']}_{pax['small_dogs']}"
params = f"{dep}_{arr}_{d}_{ticket_tier}_{pax.adults}_{pax.small_dogs}_{rear_mounted_bike_carrier}"
existing_files = os.listdir(cache_location())
existing = [f for f in existing_files if f.endswith(params + ".json")]
if not refresh and existing:
@ -372,7 +415,14 @@ def get_accommodations_with_cache(
vehicle = vehicle_from_config(ferry_config)
filename = cache_filename(params)
data = get_accommodations(
dep, arr, d, ticket_tier, vehicle, pax["adults"], pax["small_dogs"]
dep,
arr,
d,
ticket_tier,
vehicle,
pax.adults,
pax.small_dogs,
rear_mounted_bike_carrier,
)
with open(filename, "w") as out:
@ -451,14 +501,29 @@ def cabins(
time_delta = -60
pax = read_pax()
rear_mounted_bike_carrier = (
flask.request.args.get("rear_mounted_bike_carrier") == "true"
)
prices = get_prices_with_cache(
direction, start, end, routes[direction], pax["adults"], pax["small_dogs"]
direction,
start,
end,
routes[direction],
pax.adults,
pax.small_dogs,
False,
rear_mounted_bike_carrier,
)
crossing = lookup_sailing_id(prices, sailing_id)
cabin_data = get_accommodations_with_cache(
departure_port, arrival_port, departure_date, ticket_tier
departure_port,
arrival_port,
departure_date,
ticket_tier,
False,
rear_mounted_bike_carrier,
)
accommodations = [
a
@ -467,6 +532,8 @@ def cabins(
# and "Inside" not in a["description"]
]
pax_labels = {i["pax"]: i["label"] for i in pax_options}
dep = dateutil.parser.isoparse(departure_date)
return flask.render_template(
@ -483,6 +550,9 @@ def cabins(
time_delta=time_delta,
format_pet_options=format_pet_options,
section=section,
pax=pax,
pax_label=pax_labels[pax],
rear_mounted_bike_carrier=rear_mounted_bike_carrier,
)