diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 2ec963ed..a7712d72 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -11,6 +11,9 @@ parser: '@typescript-eslint/parser' plugins: - '@typescript-eslint' - simple-import-sort +ignorePatterns: + - public/ + - '*.spec.ts' rules: '@typescript-eslint/dot-notation': 0 '@typescript-eslint/no-implied-eval': 0 @@ -24,7 +27,42 @@ rules: - error - always - exceptAfterSingleLine: true - '@typescript-eslint/naming-convention': 0 + '@typescript-eslint/naming-convention': + - warn + - selector: default + format: [camelCase] + leadingUnderscore: allowSingleOrDouble + - selector: default + filter: + regex: '^([A-Z]|_+id|__call__)$' + match: true + format: null + - selector: variable + modifiers: [destructured] + filter: + regex: '^_id$' + match: false + format: [camelCase, PascalCase, UPPER_CASE, snake_case] + - selector: variable + format: [camelCase, PascalCase, UPPER_CASE] + modifiers: [const] + leadingUnderscore: allowSingleOrDouble + - selector: property + format: [camelCase, PascalCase, UPPER_CASE, snake_case] + leadingUnderscore: allowSingleOrDouble + - selector: [function, parameter, parameterProperty, objectLiteralMethod] + filter: + regex: __call__ + match: false + format: [camelCase, PascalCase] + leadingUnderscore: allowSingleOrDouble + - selector: enum + format: [PascalCase] + - selector: [class, interface, typeAlias, enumMember] + format: [PascalCase, camelCase] + - selector: typeParameter + format: [camelCase, PascalCase, UPPER_CASE] + '@typescript-eslint/no-redeclare': 0 class-methods-use-this: 0 @@ -77,3 +115,7 @@ settings: import/resolver: typescript: alwaysTryTypes: true +# parserOptions: +# project: +# - './tsconfig.json' +# - './packages/**/tsconfig.json' \ No newline at end of file diff --git a/packages/hydrojudge/package.json b/packages/hydrojudge/package.json index 80615ebd..272c3a80 100644 --- a/packages/hydrojudge/package.json +++ b/packages/hydrojudge/package.json @@ -1,7 +1,7 @@ { "name": "@hydrooj/hydrojudge", "bin": "bin/hydrojudge.js", - "version": "2.12.15", + "version": "2.12.16", "main": "package.json", "author": "undefined ", "repository": "https://github.com/hydro-dev/Hydro.git", diff --git a/packages/hydrojudge/src/cases.ts b/packages/hydrojudge/src/cases.ts index 1f754071..8763e08f 100644 --- a/packages/hydrojudge/src/cases.ts +++ b/packages/hydrojudge/src/cases.ts @@ -189,8 +189,8 @@ function isValidConfig(config) { if (config.count > (getConfig('testcases_max') || 100)) { throw new FormatError('Too many testcases. Cancelled.'); } - const total_time = sum(config.subtasks.map((subtask) => subtask.time * subtask.cases.length)); - if (total_time > (getConfig('total_time_limit') || 60) * 1000) { + const time = sum(config.subtasks.map((subtask) => subtask.time * subtask.cases.length)); + if (time > (getConfig('total_time_limit') || 60) * 1000) { throw new FormatError('Total time limit longer than {0}s. Cancelled.', [+getConfig('total_time_limit') || 60]); } const memMax = max(config.subtasks.map((subtask) => subtask.memory)); diff --git a/packages/hydrojudge/src/config.ts b/packages/hydrojudge/src/config.ts index 589a6c05..51cdbab5 100644 --- a/packages/hydrojudge/src/config.ts +++ b/packages/hydrojudge/src/config.ts @@ -6,6 +6,7 @@ import fs from 'fs-extra'; import yaml from 'js-yaml'; const argv = cac().parse(); +// eslint-disable-next-line @typescript-eslint/naming-convention let CONFIG_FILE = path.resolve(os.homedir(), '.config', 'hydro', 'judge.yaml'); let config = { diff --git a/packages/hydrojudge/src/daemon.ts b/packages/hydrojudge/src/daemon.ts index d347ec87..97ffdf4e 100644 --- a/packages/hydrojudge/src/daemon.ts +++ b/packages/hydrojudge/src/daemon.ts @@ -30,7 +30,7 @@ declare global { } if (!global.onDestory) global.onDestory = []; if (!global.hosts) global.hosts = []; -let SI = false; +let exit = false; const terminate = async () => { log.info('正在保存数据'); @@ -38,11 +38,11 @@ const terminate = async () => { await Promise.all(global.onDestory.map((f) => f())); process.exit(1); } catch (e) { - if (SI) process.exit(1); + if (exit) process.exit(1); log.error(e.stack); log.error('发生了错误。'); log.error('再次按下 Ctrl-C 可强制退出。'); - SI = true; + exit = true; } }; process.on('SIGINT', terminate); @@ -60,7 +60,7 @@ async function worker(queue: Queue) { async function daemon() { const _hosts = getConfig('hosts'); - const retry_delay_sec = getConfig('retry_delay_sec'); + const delay = getConfig('retry_delay_sec'); const hosts = {}; const queue = new Queue(); for (const i in _hosts) { @@ -77,8 +77,8 @@ async function daemon() { break; } catch (e) { log.error(e, e.stack); - log.info(`在 ${retry_delay_sec} 秒后重试`); - await sleep(retry_delay_sec * 1000); + log.info(`在 ${delay} 秒后重试`); + await sleep(delay * 1000); } } } diff --git a/packages/hydrojudge/src/sandbox.ts b/packages/hydrojudge/src/sandbox.ts index 686a97d8..906cfdb6 100644 --- a/packages/hydrojudge/src/sandbox.ts +++ b/packages/hydrojudge/src/sandbox.ts @@ -27,7 +27,7 @@ function proc({ execute = '', time = 16000, memory = parseMemoryMB(getConfig('memoryMax')), - process_limit = getConfig('processLimit'), + processLimit = getConfig('processLimit'), stdin = '', copyIn = {}, copyOut = [], copyOutCached = [], } = {}) { if (!supportOptional) { @@ -48,7 +48,7 @@ function proc({ memoryLimit: Math.floor(memory * 1024 * 1024), strictMemoryLimit: getConfig('strict_memory'), // stackLimit: memory * 1024 * 1024, - procLimit: process_limit, + procLimit: processLimit, copyIn, copyOut, copyOutCached, diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index bdbc359b..9525863d 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.3.10", + "version": "3.3.11", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/import.ts b/packages/hydrooj/src/handler/import.ts index 22e8af6b..0b013659 100644 --- a/packages/hydrooj/src/handler/import.ts +++ b/packages/hydrooj/src/handler/import.ts @@ -49,13 +49,13 @@ async function syzojSync(info) { memory: `${judge.memoryLimit}m`, }; if (judge.extraSourceFiles) { - const user_extra_files = []; + const files = []; for (const key in judge.extraSourceFiles) { for (const file in judge.extraSourceFiles[key]) { - user_extra_files.push(file); + files.push(file); } } - config.user_extra_files = user_extra_files; + config.user_extra_files = files; } if (judge.checker?.type === 'custom') { config.checker_type = judge.checker.interface; diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 8f346528..9e77b77d 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -501,12 +501,12 @@ export class ProblemFilesHandler extends ProblemDetailHandler { this.response.body.additional_file = getAdditionalFile ? sortFiles(this.pdoc.additional_file || []) : []; if (pjax) { const { testdata, additional_file } = this.response.body; - const owner_udoc = await user.getById(domainId, this.pdoc.owner); + const owner = await user.getById(domainId, this.pdoc.owner); this.response.body = { fragments: (await Promise.all([ this.renderHTML('partials/problem_files-testdata.html', { testdata, pdoc: this.pdoc }), this.renderHTML('partials/problem_files-additional_file.html', { additional_file, pdoc: this.pdoc }), - this.renderHTML('partials/problem-sidebar-information.html', { pdoc: this.pdoc, owner_udoc }), + this.renderHTML('partials/problem-sidebar-information.html', { pdoc: this.pdoc, owner_udoc: owner }), ])).map((i) => ({ html: i })), }; this.response.template = ''; diff --git a/packages/hydrooj/src/lib/difficulty.ts b/packages/hydrooj/src/lib/difficulty.ts index 219ee3ca..d2f06652 100644 --- a/packages/hydrooj/src/lib/difficulty.ts +++ b/packages/hydrooj/src/lib/difficulty.ts @@ -1,44 +1,44 @@ const _CACHE_INFO = { - last_s: 0.0, - last_y: 0, + s: 0.0, + y: 0, values: [0.0], }; function _LOGP(x: number) { - const sqrt_2_pi = 2.506628274631000502415765284811; // Sqrt[Pi] - return (2 * Math.exp(-1.0 * (Math.log(x) ** 2) * 2)) / x / sqrt_2_pi; + const sqrtPi = 2.506628274631000502415765284811; // Sqrt[Pi] + return (2 * Math.exp(-1.0 * (Math.log(x) ** 2) * 2)) / x / sqrtPi; } -function _integrate_ensure_cache(y: number) { - let last_y = _CACHE_INFO.last_y; - if (y <= last_y) return _CACHE_INFO; - let s = _CACHE_INFO.last_s; +function _intergrateEnsureCache(y: number) { + let lastY = _CACHE_INFO.y; + if (y <= lastY) return _CACHE_INFO; + let s = _CACHE_INFO.s; const dx = 0.1; const dT = 2; - let x0 = (last_y / dT) * dx; - while (y > last_y) { + let x0 = (lastY / dT) * dx; + while (y > lastY) { x0 += dx; s += _LOGP(x0) * dx; for (let i = 1; i <= dT; i++) _CACHE_INFO.values.push(s); - last_y += dT; + lastY += dT; } - _CACHE_INFO.last_y = last_y; - _CACHE_INFO.last_s = s; + _CACHE_INFO.y = lastY; + _CACHE_INFO.s = s; return _CACHE_INFO; } -_integrate_ensure_cache(1000000); +_intergrateEnsureCache(1000000); function _integrate(y: number) { - _integrate_ensure_cache(y); + _intergrateEnsureCache(y); return _CACHE_INFO.values[y]; } function difficultyAlgorithm(nSubmit: number, nAccept: number) { if (!nSubmit) return null; const s = _integrate(nSubmit); - const ac_rate = nAccept / nSubmit; - const ans = Math.round(10.0 - 1.30 * s * 10.0 * ac_rate); + const acRate = nAccept / nSubmit; + const ans = Math.round(10.0 - 1.30 * s * 10.0 * acRate); return Math.max(ans, 1); } diff --git a/packages/hydrooj/src/lib/rating.ts b/packages/hydrooj/src/lib/rating.ts index d969f692..f4f0f792 100644 --- a/packages/hydrooj/src/lib/rating.ts +++ b/packages/hydrooj/src/lib/rating.ts @@ -103,16 +103,16 @@ interface RatingOutputUser { } function calculate(users: RatingInputUser[]): RatingOutputUser[] { - let last_idx = 0; - let last_rank = 1; + let lastIdx = 0; + let lastRank = 1; for (let i = 1; i < users.length; i++) { - if (users[i].rank > last_rank) { - for (let j = last_idx; j < i; j++) users[j].rank = i; - last_idx = i; - last_rank = users[i].rank; + if (users[i].rank > lastRank) { + for (let j = lastIdx; j < i; j++) users[j].rank = i; + lastIdx = i; + lastRank = users[i].rank; } } - for (let i = last_idx; i < users.length; i++) { + for (let i = lastIdx; i < users.length; i++) { users[i].rank = users.length; } const calculator = new RatingCalculator(users); diff --git a/packages/hydrooj/src/service/monitor.ts b/packages/hydrooj/src/service/monitor.ts index 77b0deac..15ed8b71 100644 --- a/packages/hydrooj/src/service/monitor.ts +++ b/packages/hydrooj/src/service/monitor.ts @@ -56,7 +56,8 @@ export async function feedback(): Promise<[string, StatusUpdate]> { superagent.post(`${system.get('server.center')}/report`) .send({ installId, payload }) .then((res) => { - if (res.body.updateUrl) system.set('server.center', res.body.updateUrl); + if (res.body.updateUrl?.startsWith('https://')) system.set('server.center', res.body.updateUrl); + if (res.body.notification) global.Hydro.model.message.sendNotification(res.body.notification); }) .catch(() => logger.debug('Cannot connect to hydro center.')); return [mid, $update]; diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index 15ce4685..1d7b9750 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable no-await-in-loop */ +/* eslint-disable @typescript-eslint/naming-convention */ import AdmZip from 'adm-zip'; import yaml from 'js-yaml'; import { pick } from 'lodash'; diff --git a/packages/import-qduoj/handler.ts b/packages/import-qduoj/handler.ts index cd7e8c2c..d34319ad 100644 --- a/packages/import-qduoj/handler.ts +++ b/packages/import-qduoj/handler.ts @@ -15,7 +15,7 @@ import { Handler, Route } from 'hydrooj/src/service/server'; fs.ensureDirSync('/tmp/hydro/import-qduoj'); class ImportQduojHandler extends Handler { - async ImportFromFile(domainId: string, zipfile: string) { + async fromFile(domainId: string, zipfile: string) { const zip = new AdmZip(zipfile); const tmp = path.resolve(os.tmpdir(), 'hydro', 'import-qduoj', String.random(32)); await new Promise((resolve, reject) => { @@ -121,7 +121,7 @@ class ImportQduojHandler extends Handler { if (!this.request.files.file) throw new ValidationError('file'); const stat = await fs.stat(this.request.files.file.path); if (stat.size > 128 * 1024 * 1024) throw new ValidationError('file', 'File too large'); - await this.ImportFromFile(domainId, this.request.files.file.path); + await this.fromFile(domainId, this.request.files.file.path); this.response.redirect = this.url('problem_main'); } } diff --git a/packages/import-qduoj/package.json b/packages/import-qduoj/package.json index f98f2c14..65218006 100644 --- a/packages/import-qduoj/package.json +++ b/packages/import-qduoj/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/import-qduoj", - "version": "1.3.2", + "version": "1.3.3", "description": "Import QDUOJ problem export", "main": "package.json", "repository": "https://github.com/hydro-dev/Hydro.git", diff --git a/packages/vjudge/package.json b/packages/vjudge/package.json index e2dec7c6..5b5df94c 100644 --- a/packages/vjudge/package.json +++ b/packages/vjudge/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/vjudge", - "version": "1.4.11", + "version": "1.4.12", "description": "Submit problems to remote oj", "main": "package.json", "repository": "https://github.com/hydro-dev/Hydro.git", diff --git a/packages/vjudge/src/providers/codeforces.ts b/packages/vjudge/src/providers/codeforces.ts index e1cab7b1..76730679 100644 --- a/packages/vjudge/src/providers/codeforces.ts +++ b/packages/vjudge/src/providers/codeforces.ts @@ -74,9 +74,8 @@ export default class CodeforcesProvider implements IBasicProvider { async ensureLogin() { if (await this.loggedIn) return true; logger.info('retry login'); - const csrf_token = await this.getCsrfToken('/enter'); const res = await this.post('/enter').send({ - csrf_token, + csrf_token: await this.getCsrfToken('/enter'), action: 'enter', ftaa: '', bfaa: '', @@ -197,10 +196,10 @@ export default class CodeforcesProvider implements IBasicProvider { const [, contestId, submittedProblemIndex] = id.startsWith('P921') ? ['', '921', id.split('P921')[1]] : /^P(\d+)([A-Z][0-9]*)$/.exec(id); - const csrf_token = await this.getCsrfToken('/problemset/submit'); + const csrf = await this.getCsrfToken('/problemset/submit'); // TODO check submit time to ensure submission - await this.post(`/problemset/submit?csrf_token=${csrf_token}`).send({ - csrf_token, + await this.post(`/problemset/submit?csrf_token=${csrf}`).send({ + csrf_token: csrf, contestId, action: 'submitSolutionFormSubmitted', programTypeId,