mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-26 09:48:41 +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;
|
$vdata['remote_problem_id'] = $id;
|
||||||
|
|
||||||
|
return '';
|
||||||
|
} else if ($remote_oj === 'loj') {
|
||||||
|
if (!validateUInt($id)) {
|
||||||
|
return '不合法的题目 ID';
|
||||||
|
}
|
||||||
|
|
||||||
|
$vdata['remote_problem_id'] = $id;
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +131,11 @@ $new_remote_problem_form->runAtServer();
|
|||||||
<li>
|
<li>
|
||||||
<p>目前支持导入以下题库的题目作为远端评测题:</p>
|
<p>目前支持导入以下题库的题目作为远端评测题:</p>
|
||||||
<ul class="mb-3">
|
<ul class="mb-3">
|
||||||
<li>Codeforces</li>
|
<li><a href="https://codeforces.com/problemset">Codeforces</a></li>
|
||||||
<li>Codeforces::Gym(题号前加 <code>GYM</code>)</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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>在导入题目前请先搜索题库中是否已经存在相应题目,避免重复添加。</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'],
|
'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) {
|
static function getCodeforcesProblemUrl($id) {
|
||||||
@ -58,6 +64,10 @@ class UOJRemoteProblem {
|
|||||||
return static::$providers['uoj']['url'] . '/problem/' . $id;
|
return static::$providers['uoj']['url'] . '/problem/' . $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function getLojProblemUrl($id) {
|
||||||
|
return static::$providers['loj']['url'] . '/p/' . $id;
|
||||||
|
}
|
||||||
|
|
||||||
static function getCodeforcesProblemBasicInfoFromHtml($id, $html) {
|
static function getCodeforcesProblemBasicInfoFromHtml($id, $html) {
|
||||||
$remote_provider = static::$providers['codeforces'];
|
$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) {
|
public static function getProblemRemoteUrl($oj, $id) {
|
||||||
if ($oj === 'codeforces') {
|
if ($oj === 'codeforces') {
|
||||||
return static::getCodeforcesProblemUrl($id);
|
return static::getCodeforcesProblemUrl($id);
|
||||||
@ -339,6 +415,8 @@ class UOJRemoteProblem {
|
|||||||
return static::getAtcoderProblemUrl($id);
|
return static::getAtcoderProblemUrl($id);
|
||||||
} else if ($oj === 'uoj') {
|
} else if ($oj === 'uoj') {
|
||||||
return static::getUojProblemUrl($id);
|
return static::getUojProblemUrl($id);
|
||||||
|
} else if ($oj === 'loj') {
|
||||||
|
return static::getLojProblemUrl($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -352,6 +430,8 @@ class UOJRemoteProblem {
|
|||||||
return static::getAtcoderProblemBasicInfo($id);
|
return static::getAtcoderProblemBasicInfo($id);
|
||||||
} else if ($oj === 'uoj') {
|
} else if ($oj === 'uoj') {
|
||||||
return static::getUojProblemBasicInfo($id);
|
return static::getUojProblemBasicInfo($id);
|
||||||
|
} else if ($oj === 'loj') {
|
||||||
|
return static::getLojProblemBasicInfo($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
Reference in New Issue
Block a user