#!/usr/bin/python3 """Retrieve Wheelie Fresh Bins cleaning schedule and save HTML to file.""" import configparser import json import os import re import sys from datetime import date, datetime, timedelta from typing import NoReturn import ics import jinja2 import requests from playwright.sync_api import Playwright, sync_playwright base_dir = os.path.dirname(__file__) templates_dir = os.path.join(base_dir, "templates") env = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_dir)) template = env.get_template("schedule.html") config_location = os.path.join(base_dir, "config") auth_json_path = os.path.join(base_dir, "auth.json") config = configparser.ConfigParser() config.read(config_location) username = config["login"]["username"] password = config["login"]["password"] data_dir = config["locations"]["data"] no_permission = "You do not have permission to view this directory or page." booking_id = config["booking"]["booking_id"] login_url = "https://portal.wheeliefreshbins.com/Account/Login" summary_url = "https://portal.wheeliefreshbins.com/Home/Summary" dest = config["location"]["dest"] ics_file = config["location"]["ics_file"] def run(playwright: Playwright) -> None: """Login to the Wheelie Fresh Bin website.""" browser = playwright.chromium.launch(headless=True) context = browser.new_context() page = context.new_page() page.goto(login_url) page.locator('input[name="UserName"]').fill(username) page.locator('input[name="Password"]').fill(password) page.locator('input[name="RememberMe"]').check() with page.expect_navigation(url=summary_url): page.locator('input:has-text("Log in")').click() page.locator('a:has-text("Schedule")').click() page.close() context.storage_state(path=auth_json_path) context.close() browser.close() def get_cookie_value() -> str: """Get the value of the cookie we need from auth.json.""" auth = json.load(open(auth_json_path)) v: str = next( cookie["value"] for cookie in auth["cookies"] if cookie["name"] == ".AspNet.Cookies" ) return v def retrieve_schedule() -> requests.models.Response: """Retrieve the bin cleaning schedule from the user dashboard.""" return requests.post( "https://portal.wheeliefreshbins.com/home/schedule", json={"bookingId": booking_id}, cookies={".AspNet.Cookies": get_cookie_value()}, ) def read_html_from_json(r: requests.models.Response) -> str: """Return HTML from the JSON response.""" html: str = r.json()["html"] return html def login() -> None: """Login to Wheelie Fresh Bins.""" with sync_playwright() as playwright: run(playwright) def get_schedule_html() -> str | NoReturn: """Grab the schedule and return the HTML part of the response.""" if not os.path.exists(auth_json_path): login() r = retrieve_schedule() if r.text != no_permission: return read_html_from_json(r) login() r = retrieve_schedule() if r.text != no_permission: return read_html_from_json(r) print("login failed") sys.exit(1) re_div = re.compile(r"