From 073eaffbd3825d06c7ec09e6975953f08212a6af Mon Sep 17 00:00:00 2001 From: undefined Date: Sat, 11 Dec 2021 20:09:23 +0800 Subject: [PATCH] core: allow custom problem difficulty --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/problem.ts | 10 ++++++---- packages/hydrooj/src/model/problem.ts | 1 + packages/hydrooj/src/script/rating.ts | 6 ++++-- packages/hydrooj/src/upgrade.ts | 5 +++++ packages/ui-default/backendlib/template.js | 1 + packages/ui-default/locales/zh.yaml | 1 - packages/ui-default/package.json | 2 +- packages/ui-default/pages/record_main.page.styl | 6 +++--- .../partials/problem-sidebar-information.html | 2 +- .../ui-default/templates/partials/problem_list.html | 2 +- packages/ui-default/templates/problem_detail.html | 2 +- packages/ui-default/templates/problem_edit.html | 13 ++++++++++++- packages/ui-default/templates/training_detail.html | 2 +- 14 files changed, 38 insertions(+), 17 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 2995a24e0..95f99695b 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.2.15", + "version": "3.2.16", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index b17bd5380..96a4038c5 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -457,16 +457,16 @@ export class ProblemEditHandler extends ProblemManageHandler { @post('pid', Types.Name, isPid, convertPid, true) @post('hidden', Types.Boolean) @post('tag', Types.Content, true, null, parseCategory) + @post('difficulty', Types.PositiveInt, (i) => +i <= 10, true) async post( domainId: string, pid: string | number, title: string, content: string, - newPid: string = '', hidden = false, tag: string[] = [], + newPid: string = '', hidden = false, tag: string[] = [], difficulty = 0, ) { if (newPid !== this.pdoc.pid && await problem.get(domainId, newPid)) throw new BadRequestError('new pid exists'); const $update: Partial = { - title, content, pid: newPid, hidden, tag: tag ?? [], + title, content, pid: newPid, hidden, tag: tag ?? [], difficulty, }; let pdoc = await problem.get(domainId, pid); - $update.difficulty = difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept); pdoc = await problem.edit(domainId, pdoc.docId, $update); this.response.redirect = this.url('problem_detail', { pid: newPid || pdoc.docId }); } @@ -780,10 +780,12 @@ export class ProblemCreateHandler extends Handler { @post('content', Types.Content) @post('pid', Types.Name, true, isPid, convertPid) @post('hidden', Types.Boolean) + @post('difficulty', Types.PositiveInt, (i) => +i <= 10, true) @post('tag', Types.Content, true, null, parseCategory) - async post(domainId: string, title: string, content: string, pid: string, hidden = false, tag: string[] = []) { + async post(domainId: string, title: string, content: string, pid: string, hidden = false, difficulty = 0, tag: string[] = []) { if (pid && await problem.get(domainId, pid)) throw new BadRequestError('invalid pid'); const docId = await problem.add(domainId, pid, title, content, this.user._id, tag ?? [], hidden); + if (difficulty) await problem.edit(domainId, docId, { difficulty }); this.response.body = { pid: pid || docId }; this.response.redirect = this.url('problem_files', { pid: pid || docId }); } diff --git a/packages/hydrooj/src/model/problem.ts b/packages/hydrooj/src/model/problem.ts index 9ccd03a2e..112ac0e35 100644 --- a/packages/hydrooj/src/model/problem.ts +++ b/packages/hydrooj/src/model/problem.ts @@ -8,6 +8,7 @@ import { ProblemNotFoundError, ValidationError } from '../error'; import type { Document, ProblemDict, ProblemStatusDoc, } from '../interface'; +import difficultyAlgorithm from '../lib/difficulty'; import { parseConfig } from '../lib/testdataConfig'; import * as bus from '../service/bus'; import { diff --git a/packages/hydrooj/src/script/rating.ts b/packages/hydrooj/src/script/rating.ts index 890992cc2..06c0f90b8 100644 --- a/packages/hydrooj/src/script/rating.ts +++ b/packages/hydrooj/src/script/rating.ts @@ -2,6 +2,7 @@ import { NumericDictionary, unionWith } from 'lodash'; import { FilterQuery, ObjectID } from 'mongodb'; import { ProblemDoc, Tdoc, Udoc } from '../interface'; +import difficultyAlgorithm from '../lib/difficulty'; import rating from '../lib/rating'; import { PRIV, STATUS } from '../model/builtin'; import * as contest from '../model/contest'; @@ -32,7 +33,8 @@ async function runProblem(...arg: any[]) { }, ).count() + 99) / 100, ); - const p = (pdoc.difficulty || 5) / (Math.sqrt(Math.sqrt(pdoc.nAccept)) + 1) / 10; + pdoc.difficulty = pdoc.difficulty || difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept) || 5; + const p = pdoc.difficulty / (Math.sqrt(Math.sqrt(pdoc.nAccept)) + 1) / 10; for (let page = 1; page <= nPages; page++) { const psdocs = await problem.getMultiStatus( pdoc.domainId, { docId: pdoc.docId, rid: { $ne: null } }, @@ -45,7 +47,7 @@ async function runProblem(...arg: any[]) { } } } - udict[pdoc.owner] = (udict[pdoc.owner] || 1500) + (pdoc.difficulty || 5); + udict[pdoc.owner] = (udict[pdoc.owner] || 1500) + pdoc.difficulty; } async function runContest(tdoc: Tdoc<30 | 60>, udict: ND, report: Function): Promise; diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index edb4d5f00..47f660d32 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -660,6 +660,11 @@ const scripts: UpgradeScript[] = [ if (bulk.length) await bulk.execute(); return true; }, + async function _55_56() { + const _FRESH_INSTALL_IGNORE = 1; + await db.collection('document').updateMany({ docType: document.TYPE_PROBLEM }, { $unset: { difficulty: '' } }); + return true; + }, ]; export default scripts; diff --git a/packages/ui-default/backendlib/template.js b/packages/ui-default/backendlib/template.js index 5e92962de..ee0bd8d11 100644 --- a/packages/ui-default/backendlib/template.js +++ b/packages/ui-default/backendlib/template.js @@ -129,6 +129,7 @@ env.addGlobal('size', misc.size); env.addGlobal('utils', { status }); env.addGlobal('avatarUrl', avatar); env.addGlobal('formatSeconds', misc.formatSeconds); +env.addGlobal('lib', global.Hydro.lib); env.addGlobal('model', global.Hydro.model); env.addGlobal('ui', global.Hydro.ui); env.addGlobal('isIE', (str) => (str ? (str.includes('MSIE') || str.includes('rv:11.0')) : false)); diff --git a/packages/ui-default/locales/zh.yaml b/packages/ui-default/locales/zh.yaml index 2db00bc65..43056a1bc 100644 --- a/packages/ui-default/locales/zh.yaml +++ b/packages/ui-default/locales/zh.yaml @@ -295,7 +295,6 @@ Enabled: 开启 End at: 结束于 End Date: 结束日期 End Time: 结束时间 -English: 英文 Enroll Training: 参加训练 Enrolled: 已参加 Enrollees: 参加人数 diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index b7a149f42..1829aff04 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.27.4", + "version": "4.27.5", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/pages/record_main.page.styl b/packages/ui-default/pages/record_main.page.styl index 7b0f95a13..4ecb3124a 100644 --- a/packages/ui-default/pages/record_main.page.styl +++ b/packages/ui-default/pages/record_main.page.styl @@ -4,18 +4,18 @@ position: relative .col--submit-at - width: rem(120px) + width: rem(115px) text-align: center &.nojs .col--submit-at width: rem(160px) .col--submit-by - width: rem(120px) + width: rem(140px) text-align: right .col--time, .col--memory, .col--lang - width: rem(100px) + width: rem(95px) text-align: center .col--status, .col--submit-by, .col--lang diff --git a/packages/ui-default/templates/partials/problem-sidebar-information.html b/packages/ui-default/templates/partials/problem-sidebar-information.html index e9dfa6a9a..7700ade61 100644 --- a/packages/ui-default/templates/partials/problem-sidebar-information.html +++ b/packages/ui-default/templates/partials/problem-sidebar-information.html @@ -10,7 +10,7 @@
{{ _('Memory') }}
{{ pdoc.config.memoryMax if pdoc.config.memoryMax == pdoc.config.memoryMin else pdoc.config.memoryMin+'~'+pdoc.config.memoryMax }}MiB
{{ _('Difficulty') }}
-
{{ pdoc['difficulty'] or _('(None)') }}
+
{{ pdoc['difficulty'] or lib.difficulty(pdoc.nSubmit, pdoc.nAccept) or _('(None)') }}
{{ _('Category') }}
{% if pdoc['category'] %} diff --git a/packages/ui-default/templates/partials/problem_list.html b/packages/ui-default/templates/partials/problem_list.html index ccc0b1ce4..b96e702d8 100644 --- a/packages/ui-default/templates/partials/problem_list.html +++ b/packages/ui-default/templates/partials/problem_list.html @@ -68,7 +68,7 @@ {{ pdoc.nSubmit }} {{ pdoc.nAccept }} - {{ pdoc['difficulty'] or _('(None)') }} + {{ pdoc['difficulty'] or lib.difficulty(pdoc.nSubmit, pdoc.nAccept) or _('(None)') }} {%- endfor -%} diff --git a/packages/ui-default/templates/problem_detail.html b/packages/ui-default/templates/problem_detail.html index faa5d43b7..ee31ad76a 100644 --- a/packages/ui-default/templates/problem_detail.html +++ b/packages/ui-default/templates/problem_detail.html @@ -58,7 +58,7 @@ {% if not tdoc %} {{ _('Tried') }}: {{ pdoc.nSubmit }} {{ _('Accepted') }}: {{ pdoc.nAccept if ((not tdoc) or showAccept) else '?' }} - {{ _('Difficulty') }}: {{ pdoc['difficulty'] or _('(None)') }} + {{ _('Difficulty') }}: {{ pdoc['difficulty'] or lib.difficulty(pdoc.nSubmit, pdoc.nAccept) or _('(None)') }} {% endif %} {{ _('Uploaded By') }}: {{ user.render_inline(udoc, badge=false) }} {% if pdoc.tag.length %} diff --git a/packages/ui-default/templates/problem_edit.html b/packages/ui-default/templates/problem_edit.html index 41b9e718a..fa3984198 100644 --- a/packages/ui-default/templates/problem_edit.html +++ b/packages/ui-default/templates/problem_edit.html @@ -30,13 +30,24 @@ +
{{ form.form_text({ - columns:12, + row:false, + columns:8, label:'Tags', help_text:'Split by \', \'.', name:'tag', value:pdoc['tag']|default([])|join(', ') }) }} + {{ form.form_text({ + row:false, + columns:4, + label:'Difficulty', + help_text:'From 1-10', + name:'difficulty', + value:pdoc['difficulty'] + }) }} +
    diff --git a/packages/ui-default/templates/training_detail.html b/packages/ui-default/templates/training_detail.html index ddacc2ac6..814406f05 100644 --- a/packages/ui-default/templates/training_detail.html +++ b/packages/ui-default/templates/training_detail.html @@ -133,7 +133,7 @@ {{ pdoc.nSubmit }} {{ pdoc.nAccept }} - {{ pdoc['difficulty'] or _('(None)') }} + {{ pdoc['difficulty'] or lib.difficulty(pdoc.nSubmit, pdoc.nAccept) or _('(None)') }} {% else %} {% set pdoc = {'_id': pid, 'hidden': true, 'title': '*'} %}