mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
109 lines
4.2 KiB
Python
109 lines
4.2 KiB
Python
"""Download the Input Summary + SAP Worksheets PDFs from Elmhurst (POC).
|
|
|
|
Closes the validate-cert loop's only manual export: pulls the two PDFs off the
|
|
Energy Report Summary page and saves them where `compare_epc_paths.py` reads:
|
|
* Input Summary -> elmhurst_summary.pdf (inputs; parse_site_notes_pdf -> EpcPropertyData)
|
|
* SAP Worksheets -> elmhurst_worksheet.pdf (the SAP calculation)
|
|
|
|
DISPLAY=:99 python scripts/hyde/elmhurst_download.py
|
|
|
|
SAFETY: this script clicks ONLY the two report buttons below. It NEVER clicks
|
|
Submit (`LinkButtonSubmitEPR`) — submitting lodges the assessment. The allow-list
|
|
is enforced in code.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from playwright.sync_api import (
|
|
Page,
|
|
TimeoutError as PlaywrightTimeoutError,
|
|
sync_playwright,
|
|
)
|
|
|
|
HERE = Path(__file__).parent
|
|
SESSION_DIR = HERE / ".elmhurst-session"
|
|
SAMPLE_DIR = (
|
|
HERE.parent.parent
|
|
/ "backend/epc_api/json_samples/real_life_examples"
|
|
/ "SAP-Schema-16.0/uprn_10070004512"
|
|
)
|
|
|
|
ASSESSMENT_GUID = "B44A0DB4-4C08-4241-B818-86F060172105"
|
|
ENTRY_URL = (
|
|
"https://rdsap10online.elmhurstenergy.co.uk/Processing/WebFormAddress.aspx"
|
|
f"?Guid={ASSESSMENT_GUID}"
|
|
)
|
|
|
|
# (button id, output filename). The ONLY buttons this script may click.
|
|
REPORTS: list[tuple[str, str]] = [
|
|
("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"),
|
|
("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf"),
|
|
]
|
|
# Buttons this script must NEVER touch (belt-and-braces).
|
|
_FORBIDDEN = {"ContentBody_ContentPlaceHolder1_LinkButtonSubmitEPR"}
|
|
|
|
|
|
def _download_one(page: Page, button_id: str, out: Path) -> bool:
|
|
assert button_id not in _FORBIDDEN, f"refusing to click forbidden {button_id}"
|
|
print(f" clicking {button_id} -> {out.name} ...", flush=True)
|
|
try:
|
|
with page.expect_download(timeout=60_000) as dl:
|
|
page.click(f"#{button_id}", timeout=20_000)
|
|
dl.value.save_as(str(out))
|
|
except PlaywrightTimeoutError:
|
|
# Some report buttons open the PDF in a popup rather than a download.
|
|
try:
|
|
with page.expect_popup(timeout=10_000) as pop:
|
|
page.click(f"#{button_id}", timeout=20_000)
|
|
popup = pop.value
|
|
with popup.expect_download(timeout=30_000) as dl2:
|
|
pass
|
|
dl2.value.save_as(str(out))
|
|
except PlaywrightTimeoutError:
|
|
print(f" !! no download/popup for {button_id}", flush=True)
|
|
return False
|
|
size = out.stat().st_size if out.exists() else 0
|
|
print(f" saved {out} ({size:,} bytes)", flush=True)
|
|
return out.exists() and size > 0
|
|
|
|
|
|
def download_reports() -> int:
|
|
SAMPLE_DIR.mkdir(parents=True, exist_ok=True)
|
|
ok = True
|
|
with sync_playwright() as p:
|
|
context = p.chromium.launch_persistent_context(
|
|
user_data_dir=str(SESSION_DIR),
|
|
headless=False,
|
|
accept_downloads=True,
|
|
viewport={"width": 1400, "height": 1000},
|
|
)
|
|
page = context.pages[0] if context.pages else context.new_page()
|
|
page.on("dialog", lambda d: d.accept())
|
|
|
|
print(f"entering assessment {ASSESSMENT_GUID} ...", flush=True)
|
|
page.goto(ENTRY_URL, wait_until="networkidle", timeout=60_000)
|
|
# The Summary nav only fires AFTER the Recommendations validation gate has
|
|
# been visited — clicking Summary straight from the Address page is a no-op.
|
|
print("navigating via Recommendations ...", flush=True)
|
|
with page.expect_navigation(wait_until="networkidle", timeout=60_000):
|
|
page.click("#ContentBody_buttonActionRecommendations_Link", timeout=15_000)
|
|
page.wait_for_timeout(600)
|
|
print("navigating to Energy Report Summary ...", flush=True)
|
|
with page.expect_navigation(wait_until="networkidle", timeout=60_000):
|
|
page.click("#ContentBody_buttonActionSummary_Link", timeout=15_000)
|
|
page.wait_for_timeout(600)
|
|
|
|
for button_id, fname in REPORTS:
|
|
ok = _download_one(page, button_id, SAMPLE_DIR / fname) and ok
|
|
page.wait_for_timeout(600)
|
|
|
|
context.close()
|
|
print("DONE." if ok else "DONE (with errors — see above).", flush=True)
|
|
return 0 if ok else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(download_reports())
|