mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-26 03:48:42 +00:00
feat(problem/remote): add loj
This commit is contained in:
parent
dc32574585
commit
af80a6831b
@ -43,6 +43,14 @@ $new_remote_problem_form->addInput('remote_problem_id', [
|
||||
|
||||
$vdata['remote_problem_id'] = $id;
|
||||
|
||||
return '';
|
||||
} else if ($remote_oj === 'loj') {
|
||||
if (!validateUInt($id)) {
|
||||
return '不合法的题目 ID';
|
||||
}
|
||||
|
||||
$vdata['remote_problem_id'] = $id;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
@ -123,8 +131,11 @@ $new_remote_problem_form->runAtServer();
|
||||
<li>
|
||||
<p>目前支持导入以下题库的题目作为远端评测题:</p>
|
||||
<ul class="mb-3">
|
||||
<li>Codeforces</li>
|
||||
<li>Codeforces::Gym(题号前加 <code>GYM</code>)</li>
|
||||
<li><a href="https://codeforces.com/problemset">Codeforces</a></li>
|
||||
<li><a href="https://codeforces.com/gyms">Codeforces::Gym</a>(题号前加 <code>GYM</code>)</li>
|
||||
<li><a href="https://atcoder.jp/contests/archive">AtCoder</a></li>
|
||||
<li><a href="https://uoj.ac/problems">UniversalOJ</a></li>
|
||||
<li><a href="https://loj.ac/p">LibreOJ</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>在导入题目前请先搜索题库中是否已经存在相应题目,避免重复添加。</li>
|
||||
|
@ -32,6 +32,12 @@ class UOJRemoteProblem {
|
||||
],
|
||||
'languages' => ['C', 'C++03', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java8', 'Java11', 'Java17', 'Pascal'],
|
||||
],
|
||||
'loj' => [
|
||||
'name' => 'LibreOJ',
|
||||
'short_name' => 'LOJ',
|
||||
'url' => 'https://loj.ac',
|
||||
'languages' => ['C', 'C++03', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java8', 'Java11', 'Java17', 'Pascal'],
|
||||
],
|
||||
];
|
||||
|
||||
static function getCodeforcesProblemUrl($id) {
|
||||
@ -58,6 +64,10 @@ class UOJRemoteProblem {
|
||||
return static::$providers['uoj']['url'] . '/problem/' . $id;
|
||||
}
|
||||
|
||||
static function getLojProblemUrl($id) {
|
||||
return static::$providers['loj']['url'] . '/p/' . $id;
|
||||
}
|
||||
|
||||
static function getCodeforcesProblemBasicInfoFromHtml($id, $html) {
|
||||
$remote_provider = static::$providers['codeforces'];
|
||||
|
||||
@ -332,6 +342,72 @@ class UOJRemoteProblem {
|
||||
];
|
||||
}
|
||||
|
||||
static function getLojProblemBasicInfo($id) {
|
||||
$remote_provider = static::$providers['loj'];
|
||||
$curl = new Curl();
|
||||
$curl->setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36 S2OJ/3.1.0');
|
||||
$curl->setHeader('Content-Type', 'application/json');
|
||||
|
||||
$res = retry_loop(function () use (&$curl, $id) {
|
||||
$curl->post('https://api.loj.ac.cn/api/problem/getProblem', json_encode([
|
||||
'displayId' => (int)$id,
|
||||
'localizedContentsOfLocale' => 'zh_CN',
|
||||
'samples' => true,
|
||||
'judgeInfo' => true,
|
||||
]));
|
||||
|
||||
if ($curl->error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $curl->response;
|
||||
});
|
||||
|
||||
if (!$res) return null;
|
||||
|
||||
// Convert stdClass to array
|
||||
$res = json_decode(json_encode($res), true);
|
||||
|
||||
if (isset($res['error'])) return null;
|
||||
|
||||
$localized_contents = $res['localizedContentsOfLocale'];
|
||||
$statement = '';
|
||||
|
||||
foreach ($localized_contents['contentSections'] as $section) {
|
||||
$statement .= "\n###" . $section['sectionTitle'] . "\n\n";
|
||||
|
||||
if ($section['type'] === 'Text') {
|
||||
$statement .= $section['text'] . "\n";
|
||||
} else if ($section['type'] === 'Sample') {
|
||||
// assert($res['samples'][$section['sampleId']]);
|
||||
$display_sample_id = $section['sampleId'] + 1;
|
||||
$sample = $res['samples'][$section['sampleId']];
|
||||
|
||||
$statement .= "\n#### 样例输入 #{$display_sample_id}\n\n";
|
||||
$statement .= "\n```text\n{$sample['inputData']}\n```\n\n";
|
||||
|
||||
$statement .= "\n#### 样例输出 #{$display_sample_id}\n\n";
|
||||
$statement .= "\n```text\n{$sample['outputData']}\n```\n\n";
|
||||
|
||||
if (trim($section['text'])) {
|
||||
$statement .= "\n#### 样例解释 #{$display_sample_id}\n\n";
|
||||
$statement .= $section['text'] . "\n";
|
||||
}
|
||||
} else {
|
||||
// do nothing...
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => 'html',
|
||||
'title' => "【{$remote_provider['short_name']}{$id}】{$localized_contents['title']}",
|
||||
'time_limit' => (float)$res['judgeInfo']['timeLimit'] / 1000.0,
|
||||
'memory_limit' => $res['judgeInfo']['memoryLimit'],
|
||||
'difficulty' => -1,
|
||||
'statement' => HTML::purifier()->purify(HTML::parsedown()->text($statement)),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getProblemRemoteUrl($oj, $id) {
|
||||
if ($oj === 'codeforces') {
|
||||
return static::getCodeforcesProblemUrl($id);
|
||||
@ -339,6 +415,8 @@ class UOJRemoteProblem {
|
||||
return static::getAtcoderProblemUrl($id);
|
||||
} else if ($oj === 'uoj') {
|
||||
return static::getUojProblemUrl($id);
|
||||
} else if ($oj === 'loj') {
|
||||
return static::getLojProblemUrl($id);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -352,6 +430,8 @@ class UOJRemoteProblem {
|
||||
return static::getAtcoderProblemBasicInfo($id);
|
||||
} else if ($oj === 'uoj') {
|
||||
return static::getUojProblemBasicInfo($id);
|
||||
} else if ($oj === 'loj') {
|
||||
return static::getLojProblemBasicInfo($id);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
Loading…
Reference in New Issue
Block a user