fix(usaco): add proactive cookie validation to login and submit

Problem: `login()` always ran a fresh web login even with valid
cached cookies. `submit()` only checked cookie existence, not
validity, relying solely on a reactive retry after auth failure.
Auth redirect detection used `page_r.url.path` which could miss
non-path login redirects.

Solution: `login()` and `submit()` now load cookies and call
`_check_usaco_login()` upfront; re-login only if the check fails.
Auth detection in `_do_submit()` uses `str(page_r.url)` for a more
robust redirect match.
This commit is contained in:
Barrett Ruth 2026-03-07 02:20:20 -05:00
parent a47decf81b
commit ffd40564bc
Signed by: barrett
GPG key ID: A6C96C9349D2FC81

View file

@ -429,7 +429,19 @@ class USACOScraper(BaseScraper):
async with httpx.AsyncClient(follow_redirects=True) as client:
await _load_usaco_cookies(client)
if not client.cookies:
if client.cookies:
print(json.dumps({"status": "checking_login"}), flush=True)
if not await _check_usaco_login(client, username):
client.cookies.clear()
print(json.dumps({"status": "logging_in"}), flush=True)
try:
ok = await _do_usaco_login(client, username, password)
except Exception as e:
return self._submit_error(f"Login failed: {e}")
if not ok:
return self._submit_error("Login failed (bad credentials?)")
await _save_usaco_cookies(client)
else:
print(json.dumps({"status": "logging_in"}), flush=True)
try:
ok = await _do_usaco_login(client, username, password)
@ -470,7 +482,8 @@ class USACOScraper(BaseScraper):
headers=HEADERS,
timeout=HTTP_TIMEOUT,
)
if "login" in page_r.url.path.lower() or "Login" in page_r.text[:2000]:
page_url = str(page_r.url)
if "/login" in page_url or "Login" in page_r.text[:2000]:
return self._submit_error("auth_failure")
form_url, hidden_fields, lang_val = _parse_submit_form(
page_r.text, language_id
@ -513,6 +526,16 @@ class USACOScraper(BaseScraper):
return self._login_error("Missing username or password")
async with httpx.AsyncClient(follow_redirects=True) as client:
await _load_usaco_cookies(client)
if client.cookies:
print(json.dumps({"status": "checking_login"}), flush=True)
if await _check_usaco_login(client, username):
return LoginResult(
success=True,
error="",
credentials={"username": username, "password": password},
)
print(json.dumps({"status": "logging_in"}), flush=True)
try:
ok = await _do_usaco_login(client, username, password)