feat(config): open url option
This commit is contained in:
parent
2bc56195fd
commit
c0e175d84b
9 changed files with 45 additions and 18 deletions
|
|
@ -9,6 +9,7 @@
|
|||
---@field index_map table<string, number>
|
||||
---@field name string
|
||||
---@field display_name string
|
||||
---@field url string
|
||||
|
||||
---@class ContestSummary
|
||||
---@field display_name string
|
||||
|
|
@ -94,11 +95,13 @@ end
|
|||
---@param platform string
|
||||
---@param contest_id string
|
||||
---@param problems Problem[]
|
||||
function M.set_contest_data(platform, contest_id, problems)
|
||||
---@param url string
|
||||
function M.set_contest_data(platform, contest_id, problems, url)
|
||||
vim.validate({
|
||||
platform = { platform, 'string' },
|
||||
contest_id = { contest_id, 'string' },
|
||||
problems = { problems, 'table' },
|
||||
url = { url, 'string' },
|
||||
})
|
||||
|
||||
cache_data[platform] = cache_data[platform] or {}
|
||||
|
|
@ -109,6 +112,7 @@ function M.set_contest_data(platform, contest_id, problems)
|
|||
display_name = prev.display_name,
|
||||
problems = problems,
|
||||
index_map = {},
|
||||
url = url,
|
||||
}
|
||||
for i, p in ipairs(out.problems) do
|
||||
out.index_map[p.id] = i
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
---@field platforms table<string, CpPlatform>
|
||||
---@field hooks Hooks
|
||||
---@field debug boolean
|
||||
---@field open_url boolean
|
||||
---@field scrapers string[]
|
||||
---@field filename? fun(contest: string, contest_id: string, problem_id?: string, config: cp.Config, language?: string): string
|
||||
---@field ui CpUI
|
||||
|
|
@ -58,6 +59,7 @@ local utils = require('cp.utils')
|
|||
-- defaults per the new single schema
|
||||
---@type cp.Config
|
||||
M.defaults = {
|
||||
open_url = false,
|
||||
languages = {
|
||||
cpp = {
|
||||
extension = 'cc',
|
||||
|
|
@ -223,9 +225,7 @@ function M.setup(user_config)
|
|||
vim.validate({
|
||||
hooks = { cfg.hooks, { 'table' } },
|
||||
ui = { cfg.ui, { 'table' } },
|
||||
})
|
||||
|
||||
vim.validate({
|
||||
open_url = { cfg.open_url, { 'boolean', 'nil' }, true },
|
||||
before_run = { cfg.hooks.before_run, { 'function', 'nil' }, true },
|
||||
before_debug = { cfg.hooks.before_debug, { 'function', 'nil' }, true },
|
||||
setup_code = { cfg.hooks.setup_code, { 'function', 'nil' }, true },
|
||||
|
|
|
|||
|
|
@ -77,6 +77,11 @@ function M.setup_contest(platform, contest_id, problem_id, language)
|
|||
local pid = problem_id and problem_id or problems[1].id
|
||||
M.setup_problem(pid, language)
|
||||
start_tests(platform, contest_id, problems)
|
||||
|
||||
if contest_data.url and config_module.get_config().open_url then
|
||||
vim.print('opening')
|
||||
vim.ui.open(contest_data.url)
|
||||
end
|
||||
end
|
||||
|
||||
local contest_data = cache.get_contest_data(platform, contest_id)
|
||||
|
|
@ -134,7 +139,7 @@ function M.setup_contest(platform, contest_id, problem_id, language)
|
|||
contest_id,
|
||||
vim.schedule_wrap(function(result)
|
||||
local problems = result.problems or {}
|
||||
cache.set_contest_data(platform, contest_id, problems)
|
||||
cache.set_contest_data(platform, contest_id, problems, result.url)
|
||||
local prov = state.get_provisional()
|
||||
if not prov or prov.platform ~= platform or prov.contest_id ~= contest_id then
|
||||
return
|
||||
|
|
@ -150,8 +155,7 @@ function M.setup_contest(platform, contest_id, problem_id, language)
|
|||
if not pid then
|
||||
return
|
||||
end
|
||||
M.setup_problem(pid, prov.language)
|
||||
start_tests(platform, contest_id, cd.problems)
|
||||
proceed(cd)
|
||||
end)
|
||||
)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ local _timeout_path = nil
|
|||
local _timeout_reason = nil
|
||||
|
||||
local function is_windows()
|
||||
return uname and uname.sysname == 'Windows_NT'
|
||||
return uname.sysname == 'Windows_NT'
|
||||
end
|
||||
|
||||
local function check_time_is_gnu_time(bin)
|
||||
|
|
|
|||
|
|
@ -286,6 +286,7 @@ class AtcoderScraper(BaseScraper):
|
|||
error="",
|
||||
contest_id=cid,
|
||||
problems=problems,
|
||||
url=f"https://atcoder.jp/contests/{contest_id}/tasks",
|
||||
)
|
||||
|
||||
return await self._safe_execute("metadata", impl, contest_id)
|
||||
|
|
@ -335,6 +336,7 @@ async def main_async() -> int:
|
|||
result = MetadataResult(
|
||||
success=False,
|
||||
error="Usage: atcoder.py metadata <contest_id> OR atcoder.py tests <contest_id> OR atcoder.py contests",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
@ -345,7 +347,9 @@ async def main_async() -> int:
|
|||
if mode == "metadata":
|
||||
if len(sys.argv) != 3:
|
||||
result = MetadataResult(
|
||||
success=False, error="Usage: atcoder.py metadata <contest_id>"
|
||||
success=False,
|
||||
error="Usage: atcoder.py metadata <contest_id>",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
@ -360,7 +364,6 @@ async def main_async() -> int:
|
|||
success=False,
|
||||
error="Usage: atcoder.py tests <contest_id>",
|
||||
problem_id="",
|
||||
url="",
|
||||
tests=[],
|
||||
timeout_ms=0,
|
||||
memory_mb=0,
|
||||
|
|
@ -385,6 +388,7 @@ async def main_async() -> int:
|
|||
result = MetadataResult(
|
||||
success=False,
|
||||
error="Unknown mode. Use 'metadata <contest_id>', 'tests <contest_id>', or 'contests'",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class BaseScraper(ABC):
|
|||
error=f"{self.platform_name}: {error_msg}",
|
||||
contest_id=contest_id,
|
||||
problems=[],
|
||||
url="",
|
||||
)
|
||||
|
||||
def _create_tests_error(
|
||||
|
|
@ -37,7 +38,6 @@ class BaseScraper(ABC):
|
|||
success=False,
|
||||
error=f"{self.platform_name}: {error_msg}",
|
||||
problem_id=problem_id,
|
||||
url=url,
|
||||
tests=[],
|
||||
timeout_ms=0,
|
||||
memory_mb=0,
|
||||
|
|
|
|||
|
|
@ -198,7 +198,11 @@ class CodeforcesScraper(BaseScraper):
|
|||
f"No problems found for contest {cid}", cid
|
||||
)
|
||||
return MetadataResult(
|
||||
success=True, error="", contest_id=cid, problems=problems
|
||||
success=True,
|
||||
error="",
|
||||
contest_id=cid,
|
||||
problems=problems,
|
||||
url=f"https://codeforces.com/contest/{contest_id}",
|
||||
)
|
||||
|
||||
return await self._safe_execute("metadata", impl, contest_id)
|
||||
|
|
@ -259,6 +263,7 @@ async def main_async() -> int:
|
|||
result = MetadataResult(
|
||||
success=False,
|
||||
error="Usage: codeforces.py metadata <contest_id> OR codeforces.py tests <contest_id> OR codeforces.py contests",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
@ -269,7 +274,9 @@ async def main_async() -> int:
|
|||
if mode == "metadata":
|
||||
if len(sys.argv) != 3:
|
||||
result = MetadataResult(
|
||||
success=False, error="Usage: codeforces.py metadata <contest_id>"
|
||||
success=False,
|
||||
error="Usage: codeforces.py metadata <contest_id>",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
@ -284,7 +291,6 @@ async def main_async() -> int:
|
|||
success=False,
|
||||
error="Usage: codeforces.py tests <contest_id>",
|
||||
problem_id="",
|
||||
url="",
|
||||
tests=[],
|
||||
timeout_ms=0,
|
||||
memory_mb=0,
|
||||
|
|
@ -309,6 +315,7 @@ async def main_async() -> int:
|
|||
result = MetadataResult(
|
||||
success=False,
|
||||
error="Unknown mode. Use 'metadata <contest_id>', 'tests <contest_id>', or 'contests'",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
|
|||
|
|
@ -193,9 +193,14 @@ class CSESScraper(BaseScraper):
|
|||
return MetadataResult(
|
||||
success=False,
|
||||
error=f"{self.platform_name}: No problems found for category: {contest_id}",
|
||||
url="",
|
||||
)
|
||||
return MetadataResult(
|
||||
success=True, error="", contest_id=contest_id, problems=problems
|
||||
success=True,
|
||||
error="",
|
||||
contest_id=contest_id,
|
||||
problems=problems,
|
||||
url="https://cses.fi/problemset",
|
||||
)
|
||||
|
||||
async def scrape_contest_list(self) -> ContestListResult:
|
||||
|
|
@ -249,6 +254,7 @@ async def main_async() -> int:
|
|||
result = MetadataResult(
|
||||
success=False,
|
||||
error="Usage: cses.py metadata <category_id> OR cses.py tests <category> OR cses.py contests",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
@ -259,7 +265,9 @@ async def main_async() -> int:
|
|||
if mode == "metadata":
|
||||
if len(sys.argv) != 3:
|
||||
result = MetadataResult(
|
||||
success=False, error="Usage: cses.py metadata <category_id>"
|
||||
success=False,
|
||||
error="Usage: cses.py metadata <category_id>",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
@ -274,7 +282,6 @@ async def main_async() -> int:
|
|||
success=False,
|
||||
error="Usage: cses.py tests <category>",
|
||||
problem_id="",
|
||||
url="",
|
||||
tests=[],
|
||||
timeout_ms=0,
|
||||
memory_mb=0,
|
||||
|
|
@ -299,6 +306,7 @@ async def main_async() -> int:
|
|||
result = MetadataResult(
|
||||
success=False,
|
||||
error=f"Unknown mode: {mode}. Use 'metadata <category>', 'tests <category>', or 'contests'",
|
||||
url="",
|
||||
)
|
||||
print(result.model_dump_json())
|
||||
return 1
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class ScrapingResult(BaseModel):
|
|||
class MetadataResult(ScrapingResult):
|
||||
contest_id: str = ""
|
||||
problems: list[ProblemSummary] = Field(default_factory=list)
|
||||
url: str
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
|
|
@ -45,7 +46,6 @@ class ContestListResult(ScrapingResult):
|
|||
|
||||
class TestsResult(ScrapingResult):
|
||||
problem_id: str
|
||||
url: str
|
||||
tests: list[TestCase] = Field(default_factory=list)
|
||||
timeout_ms: int
|
||||
memory_mb: float
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue