mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-26 05: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;
|
$vdata['remote_problem_id'] = $id;
|
||||||
|
|
||||||
|
return '';
|
||||||
|
} elseif ($remote_oj === 'uoj') {
|
||||||
|
if (!validateUInt($id)) {
|
||||||
|
return '不合法的题目 ID';
|
||||||
|
}
|
||||||
|
|
||||||
|
$vdata['remote_problem_id'] = $id;
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,3 +218,66 @@ function retry_loop(callable $f, $retry = 5, $ms = 10) {
|
|||||||
}
|
}
|
||||||
return $ret;
|
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'],
|
'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) {
|
static function getCodeforcesProblemUrl($id) {
|
||||||
@ -45,6 +54,10 @@ class UOJRemoteProblem {
|
|||||||
}, $id);
|
}, $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function getUojProblemUrl($id) {
|
||||||
|
return static::$providers['uoj']['url'] . '/problem/' . $id;
|
||||||
|
}
|
||||||
|
|
||||||
static function getCodeforcesProblemBasicInfoFromHtml($id, $html) {
|
static function getCodeforcesProblemBasicInfoFromHtml($id, $html) {
|
||||||
$remote_provider = static::$providers['codeforces'];
|
$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) {
|
public static function getProblemRemoteUrl($oj, $id) {
|
||||||
if ($oj === 'codeforces') {
|
if ($oj === 'codeforces') {
|
||||||
return static::getCodeforcesProblemUrl($id);
|
return static::getCodeforcesProblemUrl($id);
|
||||||
} else if ($oj === 'atcoder') {
|
} else if ($oj === 'atcoder') {
|
||||||
return static::getAtcoderProblemUrl($id);
|
return static::getAtcoderProblemUrl($id);
|
||||||
|
} else if ($oj === 'uoj') {
|
||||||
|
return static::getUojProblemUrl($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -289,6 +350,8 @@ class UOJRemoteProblem {
|
|||||||
return static::getCodeforcesProblemBasicInfo($id);
|
return static::getCodeforcesProblemBasicInfo($id);
|
||||||
} else if ($oj === 'atcoder') {
|
} else if ($oj === 'atcoder') {
|
||||||
return static::getAtcoderProblemBasicInfo($id);
|
return static::getAtcoderProblemBasicInfo($id);
|
||||||
|
} else if ($oj === 'uoj') {
|
||||||
|
return static::getUojProblemBasicInfo($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
Reference in New Issue
Block a user