1
0
mirror of https://github.com/renbaoshuo/UOJ-Luogu-RemoteJudge.git synced 2024-11-23 22:58:43 +00:00

feat: import luogu problem from local json db using cli

This commit is contained in:
Baoshuo Ren 2023-03-20 18:32:20 +08:00
parent da9c4ced39
commit 52b98ac6ef
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
3 changed files with 93 additions and 23 deletions

View File

@ -8,6 +8,15 @@ requirePHPLib('luogu');
requirePHPLib('data'); requirePHPLib('data');
// TODO: more beautiful argv parser // TODO: more beautiful argv parser
$my_args = array();
for ($i = 1; $i < count($argv); $i++) {
if (preg_match('/^--([^=]+)[=](.*)/', $argv[$i], $match)) {
$my_args[$match[1]] = $match[2];
} else if (preg_match('/^--(.*)/', $argv[$i], $match)) {
$my_args[$match[1]] = $argv[++$i];
}
}
$handlers = [ $handlers = [
'upgrade:up' => function ($name) { 'upgrade:up' => function ($name) {
@ -64,18 +73,32 @@ $handlers = [
}); });
die("finished!\n"); die("finished!\n");
}, },
'luogu:add-problem' => function () use ($argv) { 'luogu:add-problem' => function () use ($argv, $my_args) {
$rest_index = null; DB::init();
$opts = getopt('', ['file::'], $rest_index);
if (!isset($opts['file'])) { $db = array();
if (!isset($my_args['file'])) {
echo "No database file specified, fetching online instead.\n\n"; echo "No database file specified, fetching online instead.\n\n";
} else {
echo "Reading local database: {$my_args['file']}\n\n";
$file = file_get_contents($my_args['file']);
foreach (explode("\n", $file) as $line) {
if (strlen($line) == 0) continue;
$line_data = json_decode($line, true);
$db[$line_data['pid']] = $line_data;
}
$db_count = count($db);
echo "Loaded {$db_count} items.\n\n";
} }
// TODO: read database from local file // TODO: read database from local file
$problems = array_slice($argv, $rest_index); $problems = array_filter($argv, function ($id) {
$problems = array_filter($problems, function ($id) {
if (!validateLuoguProblemId($id)) return false; if (!validateLuoguProblemId($id)) return false;
return true; return true;
@ -93,7 +116,16 @@ $handlers = [
foreach ($problems as $pid) { foreach ($problems as $pid) {
try { try {
$id = newLuoguRemoteProblem($pid); if (!isset($db[$pid])) {
if (!empty($db)) {
echo "[WARN] $pid: fallback to fetch data online\n";
}
$id = newLuoguRemoteProblem($pid);
} else {
$parsed = parseLuoguProblemData($db[$pid]);
$id = newLuoguRemoteProblemFromData($parsed);
}
echo "$pid: $id\n"; echo "$pid: $id\n";
} catch (Exception $e) { } catch (Exception $e) {

View File

@ -1,6 +1,6 @@
--- UOJ-System/web/app/cli.php 2022-12-30 09:54:05.452022649 +0800 --- UOJ-System/web/app/cli.php 2022-12-30 09:54:05.452022649 +0800
+++ UOJ-Luogu-RemoteJudge/web/app/cli.php 2023-03-20 16:47:12.734169684 +0800 +++ UOJ-Luogu-RemoteJudge/web/app/cli.php 2023-03-20 18:30:46.336676319 +0800
@@ -4,6 +4,9 @@ @@ -4,7 +4,19 @@
require $_SERVER['DOCUMENT_ROOT'] . '/app/libs/uoj-lib.php'; require $_SERVER['DOCUMENT_ROOT'] . '/app/libs/uoj-lib.php';
@ -8,25 +8,49 @@
+requirePHPLib('data'); +requirePHPLib('data');
+ +
// TODO: more beautiful argv parser // TODO: more beautiful argv parser
+$my_args = array();
+
+for ($i = 1; $i < count($argv); $i++) {
+ if (preg_match('/^--([^=]+)[=](.*)/', $argv[$i], $match)) {
+ $my_args[$match[1]] = $match[2];
+ } else if (preg_match('/^--(.*)/', $argv[$i], $match)) {
+ $my_args[$match[1]] = $argv[++$i];
+ }
+}
$handlers = [ $handlers = [
@@ -61,7 +64,44 @@ 'upgrade:up' => function ($name) {
@@ -61,7 +73,67 @@
}); });
die("finished!\n"); die("finished!\n");
}, },
- 'help' => 'showHelp' - 'help' => 'showHelp'
+ 'luogu:add-problem' => function () use ($argv) { + 'luogu:add-problem' => function () use ($argv, $my_args) {
+ $rest_index = null; + DB::init();
+ $opts = getopt('', ['file::'], $rest_index);
+ +
+ if (!isset($opts['file'])) { + $db = array();
+
+ if (!isset($my_args['file'])) {
+ echo "No database file specified, fetching online instead.\n\n"; + echo "No database file specified, fetching online instead.\n\n";
+ } else {
+ echo "Reading local database: {$my_args['file']}\n\n";
+
+ $file = file_get_contents($my_args['file']);
+
+ foreach (explode("\n", $file) as $line) {
+ if (strlen($line) == 0) continue;
+
+ $line_data = json_decode($line, true);
+ $db[$line_data['pid']] = $line_data;
+ }
+
+ $db_count = count($db);
+ echo "Loaded {$db_count} items.\n\n";
+ } + }
+ +
+ // TODO: read database from local file + // TODO: read database from local file
+ +
+ $problems = array_slice($argv, $rest_index); + $problems = array_filter($argv, function ($id) {
+ $problems = array_filter($problems, function ($id) {
+ if (!validateLuoguProblemId($id)) return false; + if (!validateLuoguProblemId($id)) return false;
+ +
+ return true; + return true;
@ -44,7 +68,16 @@
+ +
+ foreach ($problems as $pid) { + foreach ($problems as $pid) {
+ try { + try {
+ $id = newLuoguRemoteProblem($pid); + if (!isset($db[$pid])) {
+ if (!empty($db)) {
+ echo "[WARN] $pid: fallback to fetch data online\n";
+ }
+
+ $id = newLuoguRemoteProblem($pid);
+ } else {
+ $parsed = parseLuoguProblemData($db[$pid]);
+ $id = newLuoguRemoteProblemFromData($parsed);
+ }
+ +
+ echo "$pid: $id\n"; + echo "$pid: $id\n";
+ } catch (Exception $e) { + } catch (Exception $e) {

View File

@ -77,11 +77,7 @@ function fetchLuoguProblemBasicInfo($pid) {
return parseLuoguProblemData($data['currentData']['problem']); return parseLuoguProblemData($data['currentData']['problem']);
} }
function newLuoguRemoteProblem($pid) { function newLuoguRemoteProblemFromData($problem) {
// ensure validateLuoguProblemId($pid) is true
$problem = fetchLuoguProblemBasicInfo($pid);
$esc_submission_requirements = json_encode(array( $esc_submission_requirements = json_encode(array(
array( array(
"name" => "answer", "name" => "answer",
@ -98,7 +94,7 @@ function newLuoguRemoteProblem($pid) {
"view_details_type" => "ALL", "view_details_type" => "ALL",
)); ));
DB::insert("insert into problems (title, is_hidden, submission_requirement, extra_config, hackable, type) values ('" . DB::escape($problem['title']) . "', 1, '" . DB::escape($esc_submission_requirements) . "', '" . DB::escape($esc_extra_config) . "', 0, 'luogu')"); DB::insert("insert into problems (title, is_hidden, submission_requirement, extra_config, hackable, type) values ('" . DB::escape($problem['title']) . "', 1, '" . DB::escape($esc_submission_requirements) . "', '" . DB::escape($esc_extra_config) . "', 0, 'luogu')") or die(mysqli_error($GLOBALS['uojMySQL']) . "\n");
$id = DB::insert_id(); $id = DB::insert_id();
@ -109,6 +105,15 @@ function newLuoguRemoteProblem($pid) {
return $id; return $id;
} }
function newLuoguRemoteProblem($pid) {
// ensure validateLuoguProblemId($pid) is true
$problem = fetchLuoguProblemBasicInfo($pid);
$id = newLuoguRemoteProblemFromData($problem);
return $id;
}
function refetchLuoguProblemInfo($id) { function refetchLuoguProblemInfo($id) {
$problem = queryProblemBrief($id); $problem = queryProblemBrief($id);
$problem_extra_config = getProblemExtraConfig($problem); $problem_extra_config = getProblemExtraConfig($problem);