diff --git a/schedule.py b/schedule.py index 220ba8e..378622f 100755 --- a/schedule.py +++ b/schedule.py @@ -12,7 +12,6 @@ from datetime import date, datetime, timezone import ics # type: ignore import jinja2 import requests -from playwright.sync_api import Playwright, sync_playwright # type: ignore base_dir = os.path.dirname(__file__) @@ -41,28 +40,43 @@ 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() +def perform_login() -> None: + """Login to the Wheelie Fresh Bin website using OAuth2 token endpoint.""" + session = requests.Session() - page = context.new_page() + # OAuth2 password grant format + token_data = { + "grant_type": "password", + "username": username, + "password": password, + } - page.goto(login_url) - page.locator('input[name="UserName"]').fill(username) - page.locator('input[name="Password"]').fill(password) - page.locator('input[name="RememberMe"]').check() + # POST to the token endpoint + token_url = "https://portal.wheeliefreshbins.com/Token" + response = session.post(token_url, data=token_data) - with page.expect_navigation(url=summary_url): - page.locator('input:has-text("Log in")').click() + if response.status_code != 200: + raise Exception(f"Login failed with status {response.status_code}: {response.text}") - page.locator('a:has-text("Schedule")').click() + # The token endpoint should set the authentication cookie + cookie_value = session.cookies.get(".AspNet.Cookies") + if not cookie_value: + raise Exception("Authentication cookie not found after login") - page.close() + # Save cookie in the same format as Playwright did + auth_data = { + "cookies": [ + { + "name": ".AspNet.Cookies", + "value": cookie_value, + "domain": "portal.wheeliefreshbins.com", + "path": "/", + } + ] + } - context.storage_state(path=auth_json_path) - context.close() - browser.close() + with open(auth_json_path, "w") as f: + json.dump(auth_data, f, indent=2) def get_cookie_value() -> str: @@ -92,8 +106,7 @@ def read_html_from_json(r: requests.models.Response) -> str: def login() -> None: """Login to Wheelie Fresh Bins.""" - with sync_playwright() as playwright: - run(playwright) + perform_login() def get_schedule_html() -> str | typing.NoReturn: