fix(submit): use file path over stdin; fix CF CodeMirror textarea (#305)
## Problem After the initial submit hardening, two issues remained: source code was read in Lua and piped as stdin to the scraper (unnecessary roundtrip since the file exists on disk), and CF's `page.fill()` timed out on the hidden `textarea[name="source"]` because CodeMirror owns the editor state. ## Solution Pass the source file path as a CLI arg instead — AtCoder calls `page.set_input_files(file_path)` directly, CF reads it with `Path(file_path).read_text()`. Fix CF source injection via `page.evaluate()` into the CodeMirror instance. Extract `BROWSER_SUBMIT_NAV_TIMEOUT` as a per-platform `defaultdict` (CF defaults to 2× nav timeout). Save the buffer with `vim.cmd.update()` before submitting.
This commit is contained in:
parent
127089c57f
commit
a202725cc5
28 changed files with 269 additions and 168 deletions
|
|
@ -21,6 +21,7 @@ from .models import (
|
|||
from .timeouts import (
|
||||
BROWSER_NAV_TIMEOUT,
|
||||
BROWSER_SESSION_TIMEOUT,
|
||||
BROWSER_SUBMIT_NAV_TIMEOUT,
|
||||
HTTP_TIMEOUT,
|
||||
)
|
||||
|
||||
|
|
@ -289,7 +290,7 @@ class CodeforcesScraper(BaseScraper):
|
|||
self,
|
||||
contest_id: str,
|
||||
problem_id: str,
|
||||
source_code: str,
|
||||
file_path: str,
|
||||
language_id: str,
|
||||
credentials: dict[str, str],
|
||||
) -> SubmitResult:
|
||||
|
|
@ -297,7 +298,7 @@ class CodeforcesScraper(BaseScraper):
|
|||
_submit_headless,
|
||||
contest_id,
|
||||
problem_id,
|
||||
source_code,
|
||||
file_path,
|
||||
language_id,
|
||||
credentials,
|
||||
)
|
||||
|
|
@ -306,13 +307,15 @@ class CodeforcesScraper(BaseScraper):
|
|||
def _submit_headless(
|
||||
contest_id: str,
|
||||
problem_id: str,
|
||||
source_code: str,
|
||||
file_path: str,
|
||||
language_id: str,
|
||||
credentials: dict[str, str],
|
||||
_retried: bool = False,
|
||||
) -> SubmitResult:
|
||||
from pathlib import Path
|
||||
|
||||
source_code = Path(file_path).read_text()
|
||||
|
||||
try:
|
||||
from scrapling.fetchers import StealthySession # type: ignore[import-untyped,unresolved-import]
|
||||
except ImportError:
|
||||
|
|
@ -379,12 +382,22 @@ def _submit_headless(
|
|||
problem_id.upper(),
|
||||
)
|
||||
page.select_option('select[name="programTypeId"]', language_id)
|
||||
page.fill('textarea[name="source"]', source_code)
|
||||
page.evaluate(
|
||||
"""(code) => {
|
||||
const cm = document.querySelector('.CodeMirror');
|
||||
if (cm && cm.CodeMirror) {
|
||||
cm.CodeMirror.setValue(code);
|
||||
}
|
||||
const ta = document.querySelector('textarea[name="source"]');
|
||||
if (ta) ta.value = code;
|
||||
}""",
|
||||
source_code,
|
||||
)
|
||||
page.locator("form.submit-form input.submit").click(no_wait_after=True)
|
||||
try:
|
||||
page.wait_for_url(
|
||||
lambda url: "/my" in url or "/status" in url,
|
||||
timeout=BROWSER_NAV_TIMEOUT * 2,
|
||||
timeout=BROWSER_SUBMIT_NAV_TIMEOUT["codeforces"],
|
||||
)
|
||||
except Exception:
|
||||
err_el = page.query_selector("span.error")
|
||||
|
|
@ -441,7 +454,7 @@ def _submit_headless(
|
|||
return _submit_headless(
|
||||
contest_id,
|
||||
problem_id,
|
||||
source_code,
|
||||
file_path,
|
||||
language_id,
|
||||
credentials,
|
||||
_retried=True,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue