mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-08 16:08:41 +00:00
feat(problem/remote): add uoj
This commit is contained in:
parent
9611ea35da
commit
6e945ef711
@ -35,6 +35,14 @@ $new_remote_problem_form->addInput('remote_problem_id', [
|
||||
|
||||
$vdata['remote_problem_id'] = $id;
|
||||
|
||||
return '';
|
||||
} elseif ($remote_oj === 'uoj') {
|
||||
if (!validateUInt($id)) {
|
||||
return '不合法的题目 ID';
|
||||
}
|
||||
|
||||
$vdata['remote_problem_id'] = $id;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -202,10 +202,10 @@ function getProblemCustomTestRequirement($problem) {
|
||||
|
||||
function sendSystemMsg($username, $title, $content) {
|
||||
DB::insert([
|
||||
"insert into user_system_msg",
|
||||
"(receiver, title, content, send_time)",
|
||||
"values", DB::tuple([$username, $title, $content, DB::now()])
|
||||
]);
|
||||
"insert into user_system_msg",
|
||||
"(receiver, title, content, send_time)",
|
||||
"values", DB::tuple([$username, $title, $content, DB::now()])
|
||||
]);
|
||||
}
|
||||
|
||||
function retry_loop(callable $f, $retry = 5, $ms = 10) {
|
||||
@ -218,3 +218,66 @@ function retry_loop(callable $f, $retry = 5, $ms = 10) {
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getAbsoluteUrl($relativeUrl, $baseUrl) {
|
||||
// if already absolute URL
|
||||
if (parse_url($relativeUrl, PHP_URL_SCHEME) !== null) {
|
||||
return $relativeUrl;
|
||||
}
|
||||
|
||||
// queries and anchors
|
||||
if ($relativeUrl[0] === '#' || $relativeUrl[0] === '?') {
|
||||
return $baseUrl . $relativeUrl;
|
||||
}
|
||||
|
||||
// parse base URL and convert to: $scheme, $host, $path, $query, $port, $user, $pass
|
||||
extract(parse_url($baseUrl));
|
||||
|
||||
// if base URL contains a path remove non-directory elements from $path
|
||||
if (isset($path) === true) {
|
||||
$path = preg_replace('#/[^/]*$#', '', $path);
|
||||
} else {
|
||||
$path = '';
|
||||
}
|
||||
|
||||
// if realtive URL starts with //
|
||||
if (substr($relativeUrl, 0, 2) === '//') {
|
||||
return $scheme . ':' . $relativeUrl;
|
||||
}
|
||||
|
||||
// if realtive URL starts with /
|
||||
if ($relativeUrl[0] === '/') {
|
||||
$path = null;
|
||||
}
|
||||
|
||||
$abs = null;
|
||||
|
||||
// if realtive URL contains a user
|
||||
if (isset($user) === true) {
|
||||
$abs .= $user;
|
||||
|
||||
// if realtive URL contains a password
|
||||
if (isset($pass) === true) {
|
||||
$abs .= ':' . $pass;
|
||||
}
|
||||
|
||||
$abs .= '@';
|
||||
}
|
||||
|
||||
$abs .= $host;
|
||||
|
||||
// if realtive URL contains a port
|
||||
if (isset($port) === true) {
|
||||
$abs .= ':' . $port;
|
||||
}
|
||||
|
||||
$abs .= $path . '/' . $relativeUrl . (isset($query) === true ? '?' . $query : null);
|
||||
|
||||
// replace // or /./ or /foo/../ with /
|
||||
$re = ['#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'];
|
||||
for ($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) {
|
||||
}
|
||||
|
||||
// return absolute URL
|
||||
return $scheme . '://' . $abs;
|
||||
}
|
||||
|
@ -23,6 +23,15 @@ class UOJRemoteProblem {
|
||||
],
|
||||
'languages' => ['C', 'C++', 'Java11', 'Python3', 'Pascal'],
|
||||
],
|
||||
'uoj' => [
|
||||
'name' => 'UniversalOJ',
|
||||
'short_name' => 'UOJ',
|
||||
'url' => 'https://uoj.ac',
|
||||
'not_exist_texts' => [
|
||||
'未找到该页面',
|
||||
],
|
||||
'languages' => ['C', 'C++03', 'C++11', 'C++14', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java8', 'Java11', 'Java17', 'Pascal'],
|
||||
],
|
||||
];
|
||||
|
||||
static function getCodeforcesProblemUrl($id) {
|
||||
@ -45,6 +54,10 @@ class UOJRemoteProblem {
|
||||
}, $id);
|
||||
}
|
||||
|
||||
static function getUojProblemUrl($id) {
|
||||
return static::$providers['uoj']['url'] . '/problem/' . $id;
|
||||
}
|
||||
|
||||
static function getCodeforcesProblemBasicInfoFromHtml($id, $html) {
|
||||
$remote_provider = static::$providers['codeforces'];
|
||||
|
||||
@ -273,11 +286,59 @@ class UOJRemoteProblem {
|
||||
];
|
||||
}
|
||||
|
||||
static function getUojProblemBasicInfo($id) {
|
||||
$remote_provider = static::$providers['uoj'];
|
||||
$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');
|
||||
|
||||
$res = retry_loop(function () use (&$curl, $id) {
|
||||
$curl->get(static::getUojProblemUrl($id));
|
||||
|
||||
if ($curl->error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $curl->response;
|
||||
});
|
||||
|
||||
if (!$res) return null;
|
||||
|
||||
$dom = new \IvoPetkov\HTML5DOMDocument();
|
||||
$dom->loadHTML($res);
|
||||
|
||||
$title_dom = $dom->querySelector('.page-header');
|
||||
$title_matches = [];
|
||||
preg_match('/^#[1-9][0-9]*\. (.*)$/', trim($title_dom->textContent), $title_matches);
|
||||
$title = "【{$remote_provider['short_name']}{$id}】{$title_matches[1]}";
|
||||
|
||||
$statement_dom = $dom->querySelector('.uoj-article');
|
||||
$statement = HTML::tag('h3', [], '题目描述');
|
||||
|
||||
foreach ($statement_dom->querySelectorAll('a') as &$elem) {
|
||||
$href = $elem->getAttribute('href');
|
||||
$href = getAbsoluteUrl($href, $remote_provider['url']);
|
||||
$elem->setAttribute('href', $href);
|
||||
}
|
||||
|
||||
$statement .= $statement_dom->innerHTML;
|
||||
|
||||
return [
|
||||
'type' => 'html',
|
||||
'title' => $title,
|
||||
'time_limit' => null,
|
||||
'memory_limit' => null,
|
||||
'difficulty' => -1,
|
||||
'statement' => $statement,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getProblemRemoteUrl($oj, $id) {
|
||||
if ($oj === 'codeforces') {
|
||||
return static::getCodeforcesProblemUrl($id);
|
||||
} else if ($oj === 'atcoder') {
|
||||
return static::getAtcoderProblemUrl($id);
|
||||
} else if ($oj === 'uoj') {
|
||||
return static::getUojProblemUrl($id);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -289,6 +350,8 @@ class UOJRemoteProblem {
|
||||
return static::getCodeforcesProblemBasicInfo($id);
|
||||
} else if ($oj === 'atcoder') {
|
||||
return static::getAtcoderProblemBasicInfo($id);
|
||||
} else if ($oj === 'uoj') {
|
||||
return static::getUojProblemBasicInfo($id);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
Loading…
Reference in New Issue
Block a user