Bit of a facelift - getting to point of needing templating.

This commit is contained in:
2026-06-06 20:34:22 +01:00
parent a40ca8d806
commit 6d16194838
2 changed files with 74 additions and 44 deletions
+2 -29
View File
@@ -4,34 +4,15 @@ Standard functions to call for fares information.
# Imports
import requests
import pandas as pd
from os import environ
import json
# Init.
COLUMN_RENAMES = {
"origin_code": "Origin",
"destination_code": "Destination",
"route_code": "Route",
"status_code": "Status",
"usage_code": "Usage",
"direction": "Direction",
"end_date": "Ends",
"start_date": "Starts",
"toc": "TOC",
"cross_london_flag": "Cross London",
"settlement_flag": "Settlement",
"discount_flag": "Discount",
"flow_id": "ID",
"ticket_code": "Ticket Code",
"fare": "Fare",
"restriction_code": "Restriction",
}
# Functions
def fares_query(origin: str, destination: str) -> pd.DataFrame:
def fares_query(origin: str, destination: str) -> list[dict[str, dict[str, str]]]:
response = requests.get(
url=f"https://fares.ballast-data.co.uk/fares?origin={origin}&destination={destination}",
auth=(
@@ -39,12 +20,4 @@ def fares_query(origin: str, destination: str) -> pd.DataFrame:
environ.get("BD_FARES_PASS", ""),
),
)
dfs, data = [], json.loads(response.content.decode())
for flow_fares in data:
df = pd.json_normalize(flow_fares["fares"]).drop("flow_id", axis=1)
meta = pd.DataFrame.from_records(
[flow_fares["flow_id"] | {"Number": number} for number in df.index]
).rename(COLUMN_RENAMES, axis=1)
df.index = pd.MultiIndex.from_frame(meta)
dfs.append(df)
return pd.concat(dfs).rename(COLUMN_RENAMES, axis=1)
return json.loads(response.content.decode()) # pyright: ignore[reportAny]
+72 -15
View File
@@ -3,8 +3,11 @@ Web server core for the fares site.
"""
# Import
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
from logging import Logger, INFO
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from logging import INFO, Logger
import pandas as pd
from pandas.io.formats.style import Styler
from requests.exceptions import ConnectionError
from fares_site.api_calling import fares_query
@@ -13,6 +16,25 @@ from fares_site.api_calling import fares_query
DEFAULT_ADDRESS = "127.0.0.1"
DEFAULT_PORT = 12_000
COLUMN_RENAMES = {
"origin_code": "Origin",
"destination_code": "Destination",
"route_code": "Route",
"status_code": "Status",
"usage_code": "Usage",
"direction": "Direction",
"end_date": "Ends",
"start_date": "Starts",
"toc": "TOC",
"cross_london_flag": "Cross London",
"settlement_flag": "Settlement",
"discount_flag": "Discount",
"flow_id": "ID",
"ticket_code": "Ticket Code",
"fare": "Fare",
"restriction_code": "Restriction",
}
HTML_CONTENT_HEADER = """
<!DOCTYPE HTML>
<html>
@@ -23,13 +45,32 @@ HTML_CONTENT_HEADER = """
<link rel="stylesheet" href="https://cdn.ballast-data.co.uk/theme.css">
<link rel="icon" type="image/x-icon" href="https://cdn.ballast-data.co.uk/Icon.svg">
</head>
<body>
<body style="padding: 0px; margin: 0px;">
<div style="width: 100%; padding: 0px; margin: 0px; background-color: var(--dark-color);">
<div style="margin-left: auto; margin-right: auto; width: fit-content; background-color: var(--secondary-accent); margin-top: 0px; padding: 12px; border-radius: 0 0 9px 9px;">
Ballast-Data Product <br>
Contact: Non-Doxxing Email Lorum Ipsum <br>
Some Header Content
</div>
<br>
<div style="width: fit-content; margin-left: auto; margin-right: auto; border: 9px solid var(--light-color); border-radius: 3px; padding: 12px; background-color: white; border-radius: 9px;">
<div style="width: fit-content; margin-left: auto; margin-right: auto; border-bottom: 9px solid var(--secondary-accent);">
<br>
<img height=80px src="https://cdn.ballast-data.co.uk/Logo.svg">
<b style="font-size: 100px; line-height: 1; font-weight: 400;"> Fares </b> <br>
<b style="font-size: 60px; line-height: 1; font-weight: 400;"> RailFares </b> <br>
</div>
<br>
"""
HTML_CONTENT_FOOTER = """
</div>
<br>
<div style="margin-left: auto; margin-right: auto; width: fit-content; background-color: var(--primary-accent); margin-top: 0px; padding: 12px; border-radius: 9px 9px 0 0;">
Open Rail Data Disclaimer Etc. | No Guarantees or Whatever | We do freelance and dont want to be poor.
</div>
</div>
</body>
</html>
"""
@@ -51,20 +92,36 @@ class FaresHandler(BaseHTTPRequestHandler):
Generates the content of a GET request.
Responsible for receiving the requests' details and constructing the output.
"""
table = fares_query(
data = fares_query(
origin=(_d := self.parse_url_query()).get("origin", "NCL"),
destination=_d.get("destination", "NCL"),
).style
table = table.set_table_styles(
[
{"selector": "tr", "props": [("vertical-align", "text-top")]},
{
"selector": "tbody td",
"props": [("border-top", "1px solid var(--dark-color)")],
},
]
)
text = table.to_html()
text = "<table>"
text += (
'<tr style="font-size: 1.6em;"> <th> Flow </th> <th> Fares </th> </tr>\n'
)
for flow_fares in data:
flow_table = (
pd.json_normalize(flow_fares["flow_id"])
.rename(COLUMN_RENAMES, axis=1)
.T.style
)
_ = flow_table.hide(axis=1)
fares_table = (
pd.json_normalize(flow_fares["fares"])
.drop("flow_id", axis=1)
.rename(COLUMN_RENAMES, axis=1)
.style
)
_ = fares_table.hide(axis=0)
text += '<tr> \n <td style="border-top: 6px solid var(--primary-accent); vertical-align: top;">'
text += flow_table.to_html()
text += '</td> <td style="border-top: 6px solid var(--primary-accent); vertical-align: top;">'
text += fares_table.to_html()
text += "</td> \n </tr>"
text += "</table>"
return HTML_CONTENT_HEADER + text + HTML_CONTENT_FOOTER
def do_GET(self) -> None: