fix(submit): harden atcoder and codeforces submit flow

Problem: AtCoder file upload always used a `.cpp` temp file regardless
of language. CF submit used `solve_cloudflare=True` causing a spurious
"No Cloudflare challenge found" error, and `_wait_for_gate_reload` in
`login_action` was dead code. Stale or expired cookies caused silent
auth failures with no recovery. The `uv.spawn` ndjson path for submit
had no overall timeout, so a hung browser process would live forever.

Solution: Replace AtCoder's temp file with `page.set_input_files` using
an in-memory buffer and correct extension via `_LANGUAGE_ID_EXTENSION`.
Replace CF's temp-file/fallback dance with a direct
`textarea[name="source"]` fill and set `solve_cloudflare=False` on the
submit fetch. Add a fast-path that skips the homepage login check when
cookies exist, with automatic stale-cookie recovery via `_retried` flag
on redirect-to-login detection. Remove `_wait_for_gate_reload`. Fix
`_ensure_browser` to propagate install errors instead of swallowing
them. Add a 120s kill timer to the ndjson `uv.spawn` submit path.
This commit is contained in:
Barrett Ruth 2026-03-05 11:09:43 -05:00
parent 6fcb5d1bbc
commit 6923301562
3 changed files with 105 additions and 99 deletions

View file

@ -92,6 +92,10 @@ local function run_scraper(platform, subcommand, args, opts)
env = spawn_env_list(env),
cwd = plugin_path,
}, function(code, signal)
if timer and not timer:is_closing() then
timer:stop()
timer:close()
end
if buf ~= '' and opts.on_event then
local ok_tail, ev_tail = pcall(vim.json.decode, buf)
if ok_tail then
@ -124,6 +128,31 @@ local function run_scraper(platform, subcommand, args, opts)
return { success = false, error = 'spawn failed' }
end
local timer = nil
if subcommand == 'submit' then
timer = uv.new_timer()
timer:start(120000, 0, function()
timer:stop()
timer:close()
if stdin_pipe and not stdin_pipe:is_closing() then
stdin_pipe:close()
end
if not stdout:is_closing() then
stdout:close()
end
if not stderr:is_closing() then
stderr:close()
end
if handle and not handle:is_closing() then
handle:kill(15)
handle:close()
end
if opts.on_exit then
opts.on_exit({ success = false, error = 'submit timed out' })
end
end)
end
if stdin_pipe then
uv.write(stdin_pipe, opts.stdin, function()
uv.shutdown(stdin_pipe, function()