From 86fbc2d2fd437991eeaea57c2791788adabec4ae Mon Sep 17 00:00:00 2001 From: Aleksey Ropan Date: Sun, 11 Aug 2024 22:40:55 +0000 Subject: [PATCH] Update legacy to php 8 Added ac.nowcoder.com Problem rating predictor Added archive problems Codechef ratelimit fix --- legacy/Dockerfile | 17 +- legacy/cron | 1 - legacy/db.class.php | 8 + legacy/helper.php | 39 ++- legacy/libs/smarty | 2 +- legacy/module/ac.nowcoder.com/index.php | 81 ++++++ legacy/module/acmp.ru/index.php | 2 +- legacy/module/adventofcode.com/index.php | 2 +- legacy/module/beecrowd.com.br/index.php | 18 +- legacy/module/bubblecup.org/index.php | 4 +- legacy/module/challenges.reply.com/index.php | 2 +- legacy/module/codeforces.com-gym/index.php | 2 +- legacy/module/codeforces.com/index.php | 2 +- legacy/module/coderun.yandex.ru/index.php | 4 +- .../codingninjas.com_codestudio/index.php | 2 +- legacy/module/ctftime.org/index.php | 2 +- legacy/module/dphi.tech/index.php | 4 +- legacy/module/facebook.com/index.php | 2 +- legacy/module/geeksforgeeks.org/index.php | 2 +- legacy/module/highload.fun/index.php | 6 +- legacy/module/kaggle.com/index.php | 2 +- .../module/karelia.snarknews.info/index.php | 8 +- legacy/module/luogu.com.cn/index.php | 1 + legacy/module/nerc.itmo.ru_school/index.php | 2 +- legacy/module/nerc.itmo.ru_trains/index.php | 2 +- legacy/module/olympiads.ru/index.php | 3 + legacy/module/projecteuler.net/index.php | 2 +- legacy/module/robocontest.uz/index.php | 6 + legacy/module/supecoder.dev/index.php | 2 +- requirements.txt | 3 + src/clist/admin.py | 4 +- src/clist/api/v4.py | 4 +- .../management/commands/parse_new_problems.py | 113 ++++++++ .../management/commands/parse_problems.py | 14 +- .../commands/set_resources_fields.py | 13 +- .../train_problem_rating_predictor.py | 53 ++++ src/clist/migrations/0160_problem_kinds.py | 19 ++ .../migrations/0161_auto_20240728_1215.py | 37 +++ src/clist/migrations/0162_resource_edits.py | 89 ++++++ src/clist/models.py | 92 +++++- src/clist/templatetags/extras.py | 26 ++ src/clist/views.py | 45 +-- src/pyclist/settings.py | 7 +- .../commands/parse_accounts_infos.py | 2 +- .../management/commands/parse_statistic.py | 8 +- src/ranking/management/modules/ac_nowcoder.py | 229 +++++++++++++++ src/ranking/management/modules/beecrowd.py | 22 +- src/ranking/management/modules/codechef.py | 270 +++++++++--------- .../management/modules/common/__init__.py | 4 + src/ranking/management/modules/leetcode.py | 116 +++++++- src/ranking/models.py | 11 +- src/ranking/utils.py | 48 +++- src/ranking/views.py | 4 + src/static/css/base.css | 36 ++- src/static/css/profile.css | 10 +- src/static/css/standings.css | 8 - src/static/css/standings_list.css | 5 + src/static/img/resources/ac_nowcoder.png | Bin 0 -> 3696 bytes src/static/img/resources/usaco_guide.png | Bin 0 -> 2540 bytes src/static/js/base.js | 25 +- src/static/js/contest/calendar.js | 14 + src/static/js/standings.js | 4 + src/templates/calendar.html | 2 +- src/templates/navbar.html | 2 +- src/templates/problems_paging.html | 27 +- src/templates/profile.html | 14 +- src/templates/profile_contests_paging.html | 89 +++--- src/templates/standings.html | 3 + src/templates/standings_filters.html | 25 +- src/templates/standings_list.html | 3 +- src/templates/standings_list_filters.html | 7 + src/templates/standings_list_paging.html | 59 ++-- src/templates/standings_problem_progress.html | 10 +- src/true_coders/views.py | 11 +- src/utils/proxy_list.py | 44 ++- src/utils/requester/__init__.py | 4 +- 76 files changed, 1472 insertions(+), 393 deletions(-) create mode 100755 legacy/module/ac.nowcoder.com/index.php create mode 100644 src/clist/management/commands/parse_new_problems.py create mode 100644 src/clist/management/commands/train_problem_rating_predictor.py create mode 100644 src/clist/migrations/0160_problem_kinds.py create mode 100644 src/clist/migrations/0161_auto_20240728_1215.py create mode 100644 src/clist/migrations/0162_resource_edits.py create mode 100644 src/ranking/management/modules/ac_nowcoder.py create mode 100644 src/static/img/resources/ac_nowcoder.png create mode 100644 src/static/img/resources/usaco_guide.png diff --git a/legacy/Dockerfile b/legacy/Dockerfile index 50c737a2..c3db8b17 100644 --- a/legacy/Dockerfile +++ b/legacy/Dockerfile @@ -1,4 +1,4 @@ -FROM php:7-fpm +FROM php:8-fpm # Use the default production configuration RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" @@ -8,13 +8,26 @@ RUN docker-php-ext-install iconv RUN apt install -y libicu-dev && docker-php-ext-install intl RUN apt install -y libpq-dev && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql && docker-php-ext-install pgsql +# Curl +ENV CURL_VERSION=8.9.1 +RUN curl -L https://github.com/stunnel/static-curl/releases/download/${CURL_VERSION}/curl-linux-aarch64-${CURL_VERSION}.tar.xz --output /tmp/curl.tar.xz && \ + tar -xvf /tmp/curl.tar.xz -C /tmp && \ + sha256sum /tmp/curl | grep -q "eff254056270ded081d677f2f04847817a1be692283bd5b37fbc379bed8d5461" && \ + mv /tmp/curl /usr/local/bin/curl && \ + rm /tmp/curl.tar.xz + # Configure python COPY requirements.txt . -RUN apt install -y python3 python3-pip && pip install -r requirements.txt +RUN apt install -y python3 python3-pip python3-venv && \ + python3 -m venv /venv/legacy && \ + /venv/legacy/bin/pip install -U pip && \ + /venv/legacy/bin/pip install -r requirements.txt +ENV PATH="/venv/legacy/bin/:$PATH" # Configure cron RUN apt install -y cron COPY cron /etc/cron.d/clist +RUN echo "PATH=$PATH" | cat - /etc/cron.d/clist > temp && mv temp /etc/cron.d/clist RUN chmod 0644 /etc/cron.d/clist RUN crontab /etc/cron.d/clist diff --git a/legacy/cron b/legacy/cron index d523d174..8d33c976 100644 --- a/legacy/cron +++ b/legacy/cron @@ -1,3 +1,2 @@ -PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 7,25,42 * * * * /usr/src/legacy/update.bash >/usr/src/legacy/logs/cron.log 2>&1 diff --git a/legacy/db.class.php b/legacy/db.class.php index f8c6c938..cc486bf3 100755 --- a/legacy/db.class.php +++ b/legacy/db.class.php @@ -2,6 +2,14 @@ $is_debug = true; class db { + private string $host; + private string $dbname; + private int $port; + private string $username; + private string $password; + private $link; + private $result; + function __construct() { $db_conf = parse_ini_file("/run/secrets/db_conf"); diff --git a/legacy/helper.php b/legacy/helper.php index 31ebe5f8..53691a82 100755 --- a/legacy/helper.php +++ b/legacy/helper.php @@ -168,11 +168,11 @@ function curlexec(&$url, $postfields = NULL, $params = array()) echo "url = $url\n"; } - // echo "curl_setopt(CURLOPT_URL, $url)\n"; empty($url) && die("Empty URL on " . __FILE__ . ":" . __LINE__); curl_setopt($CID, CURLOPT_URL, $url); - $header = array('Accept-Language: en;q=0.8, ru;q=0.2'); + $header = array(); + $header[] = 'Accept-Language: en;q=0.8, ru;q=0.2'; if (isset($params["http_header"])) { $header = array_merge($header, $params["http_header"]); } @@ -193,13 +193,30 @@ function curlexec(&$url, $postfields = NULL, $params = array()) curl_setopt($CID, CURLOPT_POST, false); } + $with_curl = isset($params["with_curl"]) && $params["with_curl"]; + if (CACHE && $postfields === NULL && file_exists($cachefile)) { $page = file_get_contents($cachefile); } else { - $page = curl_exec($CID); + if ($with_curl) { + $command = "curl -i {$url} -L --silent"; + foreach ($header as $h) { + $command .= " -H " . escapeshellarg($h); + } + if ($postfields !== NULL) { + $postfields = http_build_query($postfields); + $command .= " --data " . escapeshellarg($postfields); + } + if (isset($params["cookie_file"])) { + $command .= " -b " . escapeshellarg($params["cookie_file"]) . " -c " . escapeshellarg($params["cookie_file"]); + } + $page = shell_exec($command); + } else { + $page = curl_exec($CID); + } if (preg_match('#charset=["\']?([-a-z0-9]+)#i', $page, $match)) { $charset = $match[1]; @@ -254,7 +271,16 @@ function curlexec(&$url, $postfields = NULL, $params = array()) $COOKIE[$k] = $v; } } - $url = curl_getinfo($CID, CURLINFO_EFFECTIVE_URL); + if ($with_curl) { + if (isset($header['location'])) { + $url = $header['location']; + if (is_array($url)) { + $url = end($url); + } + } + } else { + $url = curl_getinfo($CID, CURLINFO_EFFECTIVE_URL); + } return $page; } @@ -447,6 +473,11 @@ function unparse_url($parsed_url) return "$scheme$user$pass$host$port$path$query$fragment"; } + + function parse_schema_host($url) { + return parse_url($url, PHP_URL_SCHEME) . "://" . parse_url($url, PHP_URL_HOST); + } + function url_merge($original, $new, $merge_query = false) { if (is_string($original)) { diff --git a/legacy/libs/smarty b/legacy/libs/smarty index dd55b231..9fc96a13 160000 --- a/legacy/libs/smarty +++ b/legacy/libs/smarty @@ -1 +1 @@ -Subproject commit dd55b23121e55a3b4f1af90a707a6c4e5969530f +Subproject commit 9fc96a13dbaf546c3d7bcf95466726578cd4e0fa diff --git a/legacy/module/ac.nowcoder.com/index.php b/legacy/module/ac.nowcoder.com/index.php new file mode 100755 index 00000000..2ac5c8f2 --- /dev/null +++ b/legacy/module/ac.nowcoder.com/index.php @@ -0,0 +1,81 @@ +]*data-id="(?P[^"]*)"[^<]*data-json="(?P[^"]*)"[^>]*>#', $page, $matches, PREG_SET_ORDER); + $n_parsed = 0; + + foreach ($matches as $_ => $match) { + $data = html_entity_decode($match['data']); + $data = html_entity_decode($data); + $data = json_decode($data, true); + + $type = pop_item($data, 'type'); + if ($type == 0) { + $kind = 'ACM'; + $standings_kind = 'icpc'; + } elseif ($type == 3) { + $kind = 'IOI'; + $standings_kind = 'scoring'; + } elseif ($type == 2) { + $kind = 'OI'; + $standings_kind = 'scoring'; + } else { + $kind = null; + $standings_kind = null; + } + + $title = html_entity_decode(pop_item($data, 'contestName')); + if ($kind) { + $title .= " [$kind]"; + } + + $key = pop_item($data, 'contestId'); + + $contest = [ + 'title' => $title, + 'start_time' => pop_item($data, 'contestStartTime') / 1000, + 'end_time' => pop_item($data, 'contestEndTime') / 1000, + 'duration' => pop_item($data, 'contestDuration') / 1000 / 60, + 'url' => "https://ac.nowcoder.com/acm/contest/{$key}", + 'key' => $key, + 'rid' => $RID, + 'host' => $HOST, + 'timezone' => $TIMEZONE, + 'info' => ['parse' => $data], + ]; + + if ($standings_kind) { + $contest['standings_kind'] = $standings_kind; + } + + $contests[] = $contest; + + if (!isset($seen[$key])) { + $seen[$key] = true; + $n_parsed += 1; + } + } + return $n_parsed; + } + + process_url($URL); + + $page = 1; + $base_url = parse_schema_host($URL) . '/acm/contest/vip-end-index?orderType=DESC'; + + for ($page = 1; ; $page++) { + $url = $base_url . "&page=$page"; + $ok = process_url($url); + + if (!$ok || !isset($_GET['parse_full_list'])) { + break; + } + } +?> diff --git a/legacy/module/acmp.ru/index.php b/legacy/module/acmp.ru/index.php index a41e35e9..8716abe2 100644 --- a/legacy/module/acmp.ru/index.php +++ b/legacy/module/acmp.ru/index.php @@ -20,7 +20,7 @@ } if (DEBUG) { - echo "$year - ${match['title']}\n"; + echo "$year - {$match['title']}\n"; } preg_match_all('#]*href="?(?P[^ ">]*)"?>\[Описание\]#', $page, $matches, PREG_SET_ORDER); diff --git a/legacy/module/adventofcode.com/index.php b/legacy/module/adventofcode.com/index.php index 8ccd81b4..42a44fd2 100755 --- a/legacy/module/adventofcode.com/index.php +++ b/legacy/module/adventofcode.com/index.php @@ -51,7 +51,7 @@ preg_match_all('#]*aria-label="(?P