feat(problem/remote): prepare for luogu

This commit is contained in:
Baoshuo Ren 2023-02-02 20:07:35 +08:00
parent 16cd5bb162
commit 7cdb39267a
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
9 changed files with 201 additions and 36 deletions

View File

@ -73,14 +73,7 @@ $new_remote_problem_form->handle = function (&$vdata) {
UOJResponse::page500('题目抓取失败,可能是题目不存在或者没有题面!如果题目没有问题,请稍后再试。<a href="">返回</a>'); UOJResponse::page500('题目抓取失败,可能是题目不存在或者没有题面!如果题目没有问题,请稍后再试。<a href="">返回</a>');
} }
$submission_requirement = [ $submission_requirement = UOJRemoteProblem::getSubmissionRequirements($remote_online_judge);
[
"name" => "answer",
"type" => "source code",
"file_name" => "answer.code",
"languages" => $remote_provider['languages'],
]
];
$enc_submission_requirement = json_encode($submission_requirement); $enc_submission_requirement = json_encode($submission_requirement);
$extra_config = [ $extra_config = [

View File

@ -118,7 +118,7 @@ if (UOJProblem::info('type') == 'remote') {
</ul> </ul>
EOD); EOD);
$re_crawl_form->config['submit_button']['text'] = '重新爬取'; $re_crawl_form->config['submit_button']['text'] = '重新爬取';
$re_crawl_form->handle = function () use ($remote_online_judge, $remote_problem_id, $remote_provider) { $re_crawl_form->handle = function () use ($remote_online_judge, $remote_problem_id) {
try { try {
$data = UOJRemoteProblem::getProblemBasicInfo($remote_online_judge, $remote_problem_id); $data = UOJRemoteProblem::getProblemBasicInfo($remote_online_judge, $remote_problem_id);
} catch (Exception $e) { } catch (Exception $e) {
@ -134,16 +134,9 @@ if (UOJProblem::info('type') == 'remote') {
$data['difficulty'] = UOJProblem::info('difficulty'); $data['difficulty'] = UOJProblem::info('difficulty');
} }
$submission_requirement = [ $submission_requirement = UOJRemoteProblem::getSubmissionRequirements($remote_online_judge);
[
"name" => "answer",
"type" => "source code",
"file_name" => "answer.code",
"languages" => $remote_provider['languages'],
]
];
$enc_submission_requirement = json_encode($submission_requirement); $enc_submission_requirement = json_encode($submission_requirement);
$extra_config = [ $extra_config = [
'remote_online_judge' => $remote_online_judge, 'remote_online_judge' => $remote_online_judge,
'remote_problem_id' => $remote_problem_id, 'remote_problem_id' => $remote_problem_id,

View File

@ -46,6 +46,7 @@ function newAddDelCmdForm($form_name, $validate, $handle, $final = null) {
function newSubmissionForm($form_name, $requirement, $zip_file_name_gen, $handle) { function newSubmissionForm($form_name, $requirement, $zip_file_name_gen, $handle) {
$form = new UOJForm($form_name); $form = new UOJForm($form_name);
foreach ($requirement as $req) { foreach ($requirement as $req) {
if ($req['type'] == "source code") { if ($req['type'] == "source code") {
$languages = UOJLang::getAvailableLanguages(isset($req['languages']) ? $req['languages'] : null); $languages = UOJLang::getAvailableLanguages(isset($req['languages']) ? $req['languages'] : null);
@ -57,6 +58,101 @@ function newSubmissionForm($form_name, $requirement, $zip_file_name_gen, $handle
$form->addTextFileInput("{$form_name}_{$req['name']}", [ $form->addTextFileInput("{$form_name}_{$req['name']}", [
'filename' => $req['file_name'], 'filename' => $req['file_name'],
]); ]);
} else if ($req['type'] == "remote submission") {
if ($req['name'] == 'luogu') {
$form->appendHTML(HTML::tag_begin('div', ['class' => 'row']));
$form->appendHTML(HTML::tag(
'div',
[
'class' => 'col-sm-2',
],
HTML::tag('label', [
'class' => 'form-col-label',
], '_uid')
));
$form->addInput("{$form_name}_{$req['name']}_uid", [
'div_class' => 'col-sm-4',
'validator_php' => function ($x) {
if (!validateUInt($x)) {
return 'ID 不合法';
}
return '';
},
]);
$form->appendHTML(HTML::tag(
'div',
[
'class' => 'col-sm-6',
],
HTML::tag('div', [
'class' => 'form-text',
], '请在 Cookie 中找到 <code>_uid</code>,然后填入框中。')
));
$form->appendHTML(HTML::tag_end('div'));
$form->appendHTML(HTML::tag_begin('div', ['class' => 'row mt-3']));
$form->appendHTML(HTML::tag(
'div',
[
'class' => 'col-sm-2',
],
HTML::tag('label', [
'class' => 'form-col-label',
], '__clientid')
));
$form->addInput("{$form_name}_{$req['name']}_clientid", [
'div_class' => 'col-sm-4',
'validator_php' => function ($x) {
if (!validateString($x)) {
return 'ID 不合法';
}
return '';
},
]);
$form->appendHTML(HTML::tag(
'div',
[
'class' => 'col-sm-6',
],
HTML::tag('div', [
'class' => 'form-text',
], '请在 Cookie 中找到 <code>__clientid</code>,然后填入框中。')
));
$form->appendHTML(HTML::tag_end('div'));
$form->appendHTML(HTML::tag_begin('div', ['class' => 'row mt-3']));
$form->appendHTML(HTML::tag(
'div',
[
'class' => 'col-sm-2',
],
HTML::tag('label', [
'class' => 'form-col-label',
], '提交记录 ID')
));
$form->addInput("{$form_name}_{$req['name']}_submission_id", [
'div_class' => 'col-sm-4',
'validator_php' => function ($x) {
if (!validateUInt($x)) {
return 'ID 不合法';
}
return '';
},
]);
$form->appendHTML(HTML::tag(
'div',
[
'class' => 'col-sm-6',
],
HTML::tag('div', [
'class' => 'form-text',
], '请填入提交记录 ID不带开头的字母 <code>R</code>)。')
));
$form->appendHTML(HTML::tag_end('div'));
}
} }
} }
@ -74,35 +170,48 @@ function newSubmissionForm($form_name, $requirement, $zip_file_name_gen, $handle
$content = []; $content = [];
$content['file_name'] = $zip_file_name; $content['file_name'] = $zip_file_name;
$content['config'] = []; $content['config'] = [];
foreach ($requirement as $req) { foreach ($requirement as $req) {
if ($req['type'] == "source code") { if ($req['type'] == "source code") {
$content['config'][] = ["{$req['name']}_language", $_POST["{$form_name}_{$req['name']}_language"]]; $content['config'][] = ["{$req['name']}_language", $_POST["{$form_name}_{$req['name']}_language"]];
} else if ($req['type'] == "remote submission") {
$content['no_rejudge'] = true;
if ($req['name'] == "luogu") {
$content['config'][] = ["{$req['name']}_uid", $_POST["{$form_name}_{$req['name']}_uid"]];
$content['config'][] = ["{$req['name']}_clientid", $_POST["{$form_name}_{$req['name']}_clientid"]];
$content['config'][] = ["{$req['name']}_submission_id", $_POST["{$form_name}_{$req['name']}_submission_id"]];
}
} }
} }
foreach ($requirement as $req) { foreach ($requirement as $req) {
if ($_POST["{$form_name}_{$req['name']}_upload_type"] == 'editor') { if ($req['type'] == "remote submission") {
$zip_file->addFromString($req['file_name'], $_POST["{$form_name}_{$req['name']}_editor"]); $zip_file->addFromString($req['name'], '');
} else { } else {
$tmp_name = UOJForm::uploadedFileTmpName("{$form_name}_{$req['name']}_file"); if ($_POST["{$form_name}_{$req['name']}_upload_type"] == 'editor') {
if ($tmp_name == null) { $zip_file->addFromString($req['file_name'], $_POST["{$form_name}_{$req['name']}_editor"]);
$zip_file->addFromString($req['file_name'], '');
} else { } else {
$zip_file->addFile($tmp_name, $req['file_name']); $tmp_name = UOJForm::uploadedFileTmpName("{$form_name}_{$req['name']}_file");
if ($tmp_name == null) {
$zip_file->addFromString($req['file_name'], '');
} else {
$zip_file->addFile($tmp_name, $req['file_name']);
}
} }
} $stat = $zip_file->statName($req['file_name']);
$stat = $zip_file->statName($req['file_name']);
if ($req['type'] == 'source code') { if ($req['type'] == 'source code') {
$max_size = isset($req['size']) ? (int)$req['size'] : 100; $max_size = isset($req['size']) ? (int)$req['size'] : 100;
if ($stat['size'] > $max_size * 1024) { if ($stat['size'] > $max_size * 1024) {
$zip_file->close(); $zip_file->close();
unlink(UOJContext::storagePath() . $zip_file_name); unlink(UOJContext::storagePath() . $zip_file_name);
UOJResponse::message("源代码长度不能超过 {$max_size} kB。"); UOJResponse::message("源代码长度不能超过 {$max_size} kB。");
}
} }
}
$tot_size += $stat['size']; $tot_size += $stat['size'];
}
} }
$zip_file->close(); $zip_file->close();

View File

@ -403,7 +403,7 @@ function echoSubmissionContent($submission, $requirement) {
echo '</div>'; echo '</div>';
echo '<div class="card-footer">' . $footer_text . '</div>'; echo '<div class="card-footer">' . $footer_text . '</div>';
echo '</div>'; echo '</div>';
} elseif ($req['type'] == "text") { } else if ($req['type'] == "text") {
$file_content = $zip_file->getFromName("{$req['file_name']}", 504); $file_content = $zip_file->getFromName("{$req['file_name']}", 504);
$file_content = strOmit($file_content, 500); $file_content = strOmit($file_content, 500);
$file_content = uojTextEncode($file_content, array('allow_CR' => true, 'html_escape' => true)); $file_content = uojTextEncode($file_content, array('allow_CR' => true, 'html_escape' => true));
@ -417,6 +417,22 @@ function echoSubmissionContent($submission, $requirement) {
echo '</div>'; echo '</div>';
echo '<div class="card-footer">' . $footer_text . '</div>'; echo '<div class="card-footer">' . $footer_text . '</div>';
echo '</div>'; echo '</div>';
} else if ($req['type'] == "remote submission") {
$remote_provider = UOJRemoteProblem::$providers[$req['name']];
$content = '';
if ($req['name'] == 'luogu') {
$content .= '<p>远端评测 ID' .
HTML::tag(
'a',
[
'href' => $remote_provider['url'] . '/record/' . $config['luogu_submission_id']
],
'R' . $config['luogu_submission_id']
) . '</p>';
}
HTML::echoPanel('', '远端评测记录', $content);
} }
} }

View File

@ -665,6 +665,7 @@ class UOJForm {
EOD; EOD;
} else { } else {
echo <<<EOD echo <<<EOD
$("#button-submit-{$this->form_name}").addClass('disabled');
return ok; return ok;
EOD; EOD;
} }

View File

@ -562,6 +562,8 @@ class UOJProblem {
foreach ($submission_requirement as $req) { foreach ($submission_requirement as $req) {
if ($req['type'] == 'source code') { if ($req['type'] == 'source code') {
return false; return false;
} else if ($req['type'] == 'remote submission') {
return false;
} }
} }

View File

@ -40,6 +40,12 @@ class UOJRemoteProblem {
'url' => 'https://loj.ac', 'url' => 'https://loj.ac',
'languages' => ['C', 'C++03', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java17', 'Pascal'], 'languages' => ['C', 'C++03', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java17', 'Pascal'],
], ],
'luogu' => [
'name' => '洛谷',
'short_name' => '洛谷',
'url' => 'https://www.luogu.com.cn',
'languages' => [],
],
]; ];
static function curl_get($url) { static function curl_get($url) {
@ -394,6 +400,28 @@ class UOJRemoteProblem {
]; ];
} }
public static function getSubmissionRequirements($oj) {
$remote_provider = UOJRemoteProblem::$providers[$oj];
if ($oj == 'luogu') {
return [
[
"name" => "luogu",
"type" => "remote submission",
]
];
}
return [
[
"name" => "answer",
"type" => "source code",
"file_name" => "answer.code",
"languages" => $remote_provider['languages'],
]
];
}
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);

View File

@ -89,7 +89,8 @@ class UOJSubmission {
$content['config'][] = ['problem_id', UOJProblem::info('id')]; $content['config'][] = ['problem_id', UOJProblem::info('id')];
if (UOJProblem::info('type') == 'remote') { if (UOJProblem::info('type') == 'remote') {
$content['config'][] = ['remote_online_judge', UOJProblem::cur()->getExtraConfig('remote_online_judge')]; $remote_online_judge = UOJProblem::cur()->getExtraConfig('remote_online_judge');
$content['config'][] = ['remote_online_judge', $remote_online_judge];
$content['config'][] = ['remote_problem_id', UOJProblem::cur()->getExtraConfig('remote_problem_id')]; $content['config'][] = ['remote_problem_id', UOJProblem::cur()->getExtraConfig('remote_problem_id')];
} }
@ -418,6 +419,10 @@ class UOJSubmission {
} }
public function userCanRejudge(array $user = null) { public function userCanRejudge(array $user = null) {
if ($this->getContent('no_rejudge')) {
return false;
}
if (isSuperUser($user)) { if (isSuperUser($user)) {
return true; return true;
} }

View File

@ -210,6 +210,24 @@ trait UOJSubmissionLikeTrait {
<div class="card-footer">$footer_text</div> <div class="card-footer">$footer_text</div>
</div> </div>
EOD; EOD;
} else if ($req['type'] == "remote submission") {
$remote_provider = UOJRemoteProblem::$providers[$req['name']];
$content = '';
if ($req['name'] == 'luogu') {
$content .= HTML::tag('div', [], [
'远端评测 ID',
HTML::tag(
'a',
[
'href' => "{$remote_provider['url']}/record/{$config['luogu_submission_id']}"
],
'R' . $config['luogu_submission_id']
),
]);
}
HTML::echoPanel('mb-3', '远端评测记录', $content);
} }
} }
$zip_file->close(); $zip_file->close();