Improvements
This commit is contained in:
parent
7599f655ad
commit
b6f0c88320
7 changed files with 139 additions and 27 deletions
96
main.py
96
main.py
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue