diff --git a/packages/hydrooj/src/entry/common.ts b/packages/hydrooj/src/entry/common.ts index 10c27d29..46e6bd94 100644 --- a/packages/hydrooj/src/entry/common.ts +++ b/packages/hydrooj/src/entry/common.ts @@ -13,7 +13,7 @@ export const builtinLib = [ 'jwt', 'download', 'i18n', 'mail', 'useragent', 'crypto', 'misc', 'paginate', 'hash.hydro', 'rank', 'validator', 'ui', 'sysinfo', 'testdata.convert.ini', 'testdataConfig', - 'content', + 'content', 'difficulty', ]; export const builtinModel = [ diff --git a/packages/hydrooj/src/handler/judge.ts b/packages/hydrooj/src/handler/judge.ts index 7bfe7e61..15740eac 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -2,6 +2,7 @@ import { ObjectID } from 'mongodb'; import { JudgeResultBody, Rdoc, TestCase } from '../interface'; import { sleep } from '../utils'; import { Logger } from '../logger'; +import difficultyAlgorithm from '../lib/difficulty'; import * as record from '../model/record'; import * as problem from '../model/problem'; import * as builtin from '../model/builtin'; @@ -27,7 +28,11 @@ async function _postJudge(rdoc: Rdoc) { rdoc._id, rdoc.pid, accept, rdoc.score, rdoc.contest.type, ); } else if (updated) await domain.incUserInDomain(rdoc.domainId, rdoc.uid, 'nAccept', 1); - if (accept && updated) await problem.inc(rdoc.domainId, rdoc.pid, 'nAccept', 1); + const pdoc = (accept && updated) + ? await problem.inc(rdoc.domainId, rdoc.pid, 'nAccept', 1) + : await problem.get(rdoc.domainId, rdoc.pid); + const difficulty = difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept); + await problem.edit(pdoc.domainId, pdoc.docId, { difficulty }); } export async function next(body: JudgeResultBody) { diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index c3d39f8c..ea7e4906 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -10,6 +10,7 @@ import { } from '../interface'; import paginate from '../lib/paginate'; import { isTitle, isContent, isPid } from '../lib/validator'; +import difficultyAlgorithm from '../lib/difficulty'; import * as system from '../model/system'; import * as problem from '../model/problem'; import * as record from '../model/record'; @@ -333,10 +334,10 @@ export class ProblemEditHandler extends ProblemManageHandler { title, content, pid: newPid, hidden, tag: tag ?? [], }; let pdoc = await problem.get(domainId, pid); + $update.difficulty = difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept); await bus.serial('problem/before-edit', $update); pdoc = await problem.edit(domainId, pdoc.docId, $update); await bus.emit('problem/edit', pdoc); - await global.Hydro.script.difficulty.run({ domainId, pid }, console.log); this.response.redirect = this.url('problem_detail', { pid: newPid || pdoc.docId }); } } diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index a5249db9..7392356c 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -520,6 +520,7 @@ interface GeoIP { export interface Lib extends Record { download: typeof import('./lib/download'), + difficulty: typeof import('./lib/difficulty'), buildContent: typeof import('./lib/content').buildContent, 'hash.hydro': typeof import('./lib/hash.hydro'), i18n: typeof import('./lib/i18n'), diff --git a/packages/hydrooj/src/script/difficulty.ts b/packages/hydrooj/src/lib/difficulty.ts similarity index 68% rename from packages/hydrooj/src/script/difficulty.ts rename to packages/hydrooj/src/lib/difficulty.ts index b37615cb..219ee3ca 100644 --- a/packages/hydrooj/src/script/difficulty.ts +++ b/packages/hydrooj/src/lib/difficulty.ts @@ -1,7 +1,3 @@ -import * as problem from '../model/problem'; - -export const description = 'Caculate the difficulty of a problem'; - const _CACHE_INFO = { last_s: 0.0, last_y: 0, @@ -46,17 +42,5 @@ function difficultyAlgorithm(nSubmit: number, nAccept: number) { return Math.max(ans, 1); } -export async function run({ - domainId, pid, -}) { - const pdoc = await problem.get(domainId, pid); - const difficulty = difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept); - return await problem.edit(domainId, pdoc.docId, { difficulty }); -} - -export const validate = { - domainId: { $type: 'string' }, - pid: { $type: 'number' }, -}; - -global.Hydro.script.difficulty = { run, description, validate }; +export = difficultyAlgorithm; +global.Hydro.lib.difficulty = difficultyAlgorithm; diff --git a/packages/hydrooj/src/script/problemStat.ts b/packages/hydrooj/src/script/problemStat.ts index aeb958e1..02d01986 100644 --- a/packages/hydrooj/src/script/problemStat.ts +++ b/packages/hydrooj/src/script/problemStat.ts @@ -29,7 +29,7 @@ export async function udoc() { ]; let bulk = db.collection('domain.user').initializeUnorderedBulkOp(); const cursor = db.collection('record').aggregate(pipeline); - while (cursor.hasNext()) { + while (await cursor.hasNext()) { const adoc = await cursor.next() as any; bulk.find({ domainId: adoc._id.domainId, diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index 35f33e3a..55c31c62 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -15,6 +15,7 @@ import * as problem from './model/problem'; import * as domain from './model/domain'; import * as document from './model/document'; import * as system from './model/system'; +import difficultyAlgorithm from './lib/difficulty'; const logger = new Logger('upgrade'); type UpgradeScript = () => Promise; @@ -201,11 +202,20 @@ const scripts: UpgradeScript[] = [ return true; }, // Set null tag to [] - async function _9_10() { + async function _10_11() { const _FRESH_INSTALL_IGNORE = 1; await db.collection('document').updateMany({ docType: 10, tag: null }, { $set: { tag: [] } }); return true; }, + // Update problem difficulty + async function _11_12() { + const _FRESH_INSTALL_IGNORE = 1; + await iterateAllProblem(['nSubmit', 'nAccept'], async (pdoc) => { + const difficulty = difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept); + await problem.edit(pdoc.domainId, pdoc.docId, { difficulty }); + }); + return true; + }, ]; export = scripts;