Compare commits
No commits in common. "4f307e323d0b4efea1edc7c6c3b43393a00bab8d" and "6e9829a1155d0b3f0876999d2ed432724b66e723" have entirely different histories.
4f307e323d
...
6e9829a115
7 changed files with 50 additions and 90 deletions
|
|
@ -605,10 +605,10 @@ end
|
||||||
---@param problem_id? string
|
---@param problem_id? string
|
||||||
---@return string
|
---@return string
|
||||||
local function default_filename(contest_id, problem_id)
|
local function default_filename(contest_id, problem_id)
|
||||||
if problem_id and problem_id ~= contest_id then
|
if problem_id then
|
||||||
return (contest_id .. problem_id):lower()
|
return (contest_id .. problem_id):lower()
|
||||||
end
|
end
|
||||||
return (problem_id or contest_id):lower()
|
return contest_id:lower()
|
||||||
end
|
end
|
||||||
M.default_filename = default_filename
|
M.default_filename = default_filename
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,19 @@ local STATUS_MESSAGES = {
|
||||||
installing_browser = 'Installing browser...',
|
installing_browser = 'Installing browser...',
|
||||||
}
|
}
|
||||||
|
|
||||||
---@param platform string
|
---@param platform string?
|
||||||
---@param display string
|
function M.login(platform)
|
||||||
local function prompt_and_login(platform, display)
|
platform = platform or state.get_platform()
|
||||||
|
if not platform then
|
||||||
|
logger.log(
|
||||||
|
'No platform specified. Usage: :CP <platform> login',
|
||||||
|
{ level = vim.log.levels.ERROR }
|
||||||
|
)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local display = constants.PLATFORM_DISPLAY_NAMES[platform] or platform
|
||||||
|
|
||||||
vim.ui.input({ prompt = display .. ' username: ' }, function(username)
|
vim.ui.input({ prompt = display .. ' username: ' }, function(username)
|
||||||
if not username or username == '' then
|
if not username or username == '' then
|
||||||
logger.log('Cancelled', { level = vim.log.levels.WARN })
|
logger.log('Cancelled', { level = vim.log.levels.WARN })
|
||||||
|
|
@ -27,7 +37,15 @@ local function prompt_and_login(platform, display)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local credentials = { username = username, password = password }
|
cache.load()
|
||||||
|
local existing = cache.get_credentials(platform) or {}
|
||||||
|
local credentials = {
|
||||||
|
username = username,
|
||||||
|
password = password,
|
||||||
|
}
|
||||||
|
if existing.token then
|
||||||
|
credentials.token = existing.token
|
||||||
|
end
|
||||||
|
|
||||||
local scraper = require('cp.scraper')
|
local scraper = require('cp.scraper')
|
||||||
scraper.login(platform, credentials, function(ev)
|
scraper.login(platform, credentials, function(ev)
|
||||||
|
|
@ -51,47 +69,6 @@ local function prompt_and_login(platform, display)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param platform string?
|
|
||||||
function M.login(platform)
|
|
||||||
platform = platform or state.get_platform()
|
|
||||||
if not platform then
|
|
||||||
logger.log(
|
|
||||||
'No platform specified. Usage: :CP <platform> login',
|
|
||||||
{ level = vim.log.levels.ERROR }
|
|
||||||
)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local display = constants.PLATFORM_DISPLAY_NAMES[platform] or platform
|
|
||||||
|
|
||||||
cache.load()
|
|
||||||
local existing = cache.get_credentials(platform) or {}
|
|
||||||
|
|
||||||
if existing.username and existing.password then
|
|
||||||
local scraper = require('cp.scraper')
|
|
||||||
scraper.login(platform, existing, function(ev)
|
|
||||||
vim.schedule(function()
|
|
||||||
local msg = STATUS_MESSAGES[ev.status] or ev.status
|
|
||||||
logger.log(display .. ': ' .. msg, { level = vim.log.levels.INFO, override = true })
|
|
||||||
end)
|
|
||||||
end, function(result)
|
|
||||||
vim.schedule(function()
|
|
||||||
if result.success then
|
|
||||||
logger.log(
|
|
||||||
display .. ' login successful',
|
|
||||||
{ level = vim.log.levels.INFO, override = true }
|
|
||||||
)
|
|
||||||
else
|
|
||||||
prompt_and_login(platform, display)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
prompt_and_login(platform, display)
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param platform string?
|
---@param platform string?
|
||||||
function M.logout(platform)
|
function M.logout(platform)
|
||||||
platform = platform or state.get_platform()
|
platform = platform or state.get_platform()
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ function M.submit(opts)
|
||||||
|
|
||||||
prompt_credentials(platform, function(creds)
|
prompt_credentials(platform, function(creds)
|
||||||
vim.cmd.update()
|
vim.cmd.update()
|
||||||
|
logger.log('Submitting...', { level = vim.log.levels.INFO, override = true })
|
||||||
|
|
||||||
require('cp.scraper').submit(
|
require('cp.scraper').submit(
|
||||||
platform,
|
platform,
|
||||||
|
|
|
||||||
|
|
@ -248,21 +248,7 @@ class CSESScraper(BaseScraper):
|
||||||
if not username or not password:
|
if not username or not password:
|
||||||
return self._login_error("Missing username or password")
|
return self._login_error("Missing username or password")
|
||||||
|
|
||||||
token = credentials.get("token")
|
|
||||||
async with httpx.AsyncClient(follow_redirects=True) as client:
|
async with httpx.AsyncClient(follow_redirects=True) as client:
|
||||||
if token:
|
|
||||||
print(json.dumps({"status": "checking_login"}), flush=True)
|
|
||||||
if await self._check_token(client, token):
|
|
||||||
return LoginResult(
|
|
||||||
success=True,
|
|
||||||
error="",
|
|
||||||
credentials={
|
|
||||||
"username": username,
|
|
||||||
"password": password,
|
|
||||||
"token": token,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
print(json.dumps({"status": "logging_in"}), flush=True)
|
print(json.dumps({"status": "logging_in"}), flush=True)
|
||||||
token = await self._web_login(client, username, password)
|
token = await self._web_login(client, username, password)
|
||||||
if not token:
|
if not token:
|
||||||
|
|
@ -474,8 +460,7 @@ class CSESScraper(BaseScraper):
|
||||||
|
|
||||||
if r.status_code not in range(200, 300):
|
if r.status_code not in range(200, 300):
|
||||||
try:
|
try:
|
||||||
body = r.json()
|
err = r.json().get("message", r.text)
|
||||||
err = body.get("error") or body.get("message") or r.text
|
|
||||||
except Exception:
|
except Exception:
|
||||||
err = r.text
|
err = r.text
|
||||||
return self._submit_error(f"Submit request failed: {err}")
|
return self._submit_error(f"Submit request failed: {err}")
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,6 @@ class KattisScraper(BaseScraper):
|
||||||
return self._submit_error("Missing credentials. Use :CP kattis login")
|
return self._submit_error("Missing credentials. Use :CP kattis login")
|
||||||
|
|
||||||
async with httpx.AsyncClient(follow_redirects=True) as client:
|
async with httpx.AsyncClient(follow_redirects=True) as client:
|
||||||
print(json.dumps({"status": "checking_login"}), flush=True)
|
|
||||||
await _load_kattis_cookies(client)
|
await _load_kattis_cookies(client)
|
||||||
if not client.cookies:
|
if not client.cookies:
|
||||||
print(json.dumps({"status": "logging_in"}), flush=True)
|
print(json.dumps({"status": "logging_in"}), flush=True)
|
||||||
|
|
@ -367,7 +366,7 @@ class KattisScraper(BaseScraper):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return self._submit_error(f"Submit request failed: {e}")
|
return self._submit_error(f"Submit request failed: {e}")
|
||||||
|
|
||||||
if r.status_code in (400, 403) or r.text == "Request validation failed":
|
if r.text == "Request validation failed":
|
||||||
_COOKIE_PATH.unlink(missing_ok=True)
|
_COOKIE_PATH.unlink(missing_ok=True)
|
||||||
print(json.dumps({"status": "logging_in"}), flush=True)
|
print(json.dumps({"status": "logging_in"}), flush=True)
|
||||||
ok = await _do_kattis_login(client, username, password)
|
ok = await _do_kattis_login(client, username, password)
|
||||||
|
|
|
||||||
|
|
@ -429,19 +429,7 @@ class USACOScraper(BaseScraper):
|
||||||
|
|
||||||
async with httpx.AsyncClient(follow_redirects=True) as client:
|
async with httpx.AsyncClient(follow_redirects=True) as client:
|
||||||
await _load_usaco_cookies(client)
|
await _load_usaco_cookies(client)
|
||||||
if client.cookies:
|
if not 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)
|
print(json.dumps({"status": "logging_in"}), flush=True)
|
||||||
try:
|
try:
|
||||||
ok = await _do_usaco_login(client, username, password)
|
ok = await _do_usaco_login(client, username, password)
|
||||||
|
|
@ -482,8 +470,7 @@ class USACOScraper(BaseScraper):
|
||||||
headers=HEADERS,
|
headers=HEADERS,
|
||||||
timeout=HTTP_TIMEOUT,
|
timeout=HTTP_TIMEOUT,
|
||||||
)
|
)
|
||||||
page_url = str(page_r.url)
|
if "login" in page_r.url.path.lower() or "Login" in page_r.text[:2000]:
|
||||||
if "/login" in page_url or "Login" in page_r.text[:2000]:
|
|
||||||
return self._submit_error("auth_failure")
|
return self._submit_error("auth_failure")
|
||||||
form_url, hidden_fields, lang_val = _parse_submit_form(
|
form_url, hidden_fields, lang_val = _parse_submit_form(
|
||||||
page_r.text, language_id
|
page_r.text, language_id
|
||||||
|
|
@ -526,16 +513,6 @@ class USACOScraper(BaseScraper):
|
||||||
return self._login_error("Missing username or password")
|
return self._login_error("Missing username or password")
|
||||||
|
|
||||||
async with httpx.AsyncClient(follow_redirects=True) as client:
|
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)
|
print(json.dumps({"status": "logging_in"}), flush=True)
|
||||||
try:
|
try:
|
||||||
ok = await _do_usaco_login(client, username, password)
|
ok = await _do_usaco_login(client, username, password)
|
||||||
|
|
|
||||||
21
t/minimal_init.lua
Normal file
21
t/minimal_init.lua
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
vim.opt.runtimepath:prepend(vim.fn.expand('~/dev/cp.nvim'))
|
||||||
|
vim.opt.runtimepath:prepend(vim.fn.expand('~/dev/fzf-lua'))
|
||||||
|
|
||||||
|
vim.g.cp = {
|
||||||
|
languages = {
|
||||||
|
cpp = {
|
||||||
|
extension = 'cc',
|
||||||
|
commands = {
|
||||||
|
build = { 'g++', '-std=c++23', '-O2', '{source}', '-o', '{binary}' },
|
||||||
|
run = { '{binary}' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
platforms = {
|
||||||
|
codechef = {
|
||||||
|
enabled_languages = { 'cpp' },
|
||||||
|
default_language = 'cpp',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ui = { picker = 'fzf-lua' },
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue