From 47ceddea9e5fb9414e7caecab0787d7ea3b09b11 Mon Sep 17 00:00:00 2001 From: undefined Date: Sat, 19 Sep 2020 20:14:41 +0800 Subject: [PATCH] fix: problem_edit --- .gitmodules | 3 ++ build/start.ts | 2 +- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/problem.ts | 45 ++++++++++++------------ packages/hydrooj/src/handler/training.ts | 8 +++-- packages/hydrooj/src/service/bus.ts | 5 ++- 6 files changed, 38 insertions(+), 27 deletions(-) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..6346b3ec6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[customize] +path = packages/customize +url = https://github.com/hydro-dev/customize.git diff --git a/build/start.ts b/build/start.ts index 3733ff5e7..f506ccfc8 100644 --- a/build/start.ts +++ b/build/start.ts @@ -27,7 +27,7 @@ if (!cluster.isMaster) { try { const ui = argv.ui as string || '@hydrooj/ui-default'; require.resolve(ui); - addons.push(ui); + addons = [ui, ...addons]; } catch (e) { console.error('Please also install @hydrooj/ui-default'); } diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index bc66c1d70..e2d6b653d 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.13.13", + "version": "2.13.14", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 10dab4a96..a26b26075 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -25,10 +25,10 @@ import { Route, Connection, Handler, ConnectionHandler, Types, param, } from '../service/server'; -const parseCategory = (value: string) => flatten(value.split('+').map((e) => e.split(','))).map((e) => e.trim()); -const parsePid = (value: string) => (isSafeInteger(value) ? parseInt(value, 10) : value); +export const parseCategory = (value: string) => flatten(value.split('+').map((e) => e.split(','))).map((e) => e.trim()); +export const parsePid = (value: string) => (isSafeInteger(value) ? parseInt(value, 10) : value); -class ProblemHandler extends Handler { +export class ProblemHandler extends Handler { async __prepare() { this.checkPerm(PERM.PERM_VIEW_PROBLEM); } @@ -56,7 +56,7 @@ class ProblemHandler extends Handler { } } -class ProblemMainHandler extends ProblemHandler { +export class ProblemMainHandler extends ProblemHandler { @param('page', Types.PositiveInt, true) @param('q', Types.String, true) async get(domainId: string, page = 1, q = '') { @@ -101,7 +101,7 @@ class ProblemMainHandler extends ProblemHandler { } } -class ProblemCategoryHandler extends ProblemHandler { +export class ProblemCategoryHandler extends ProblemHandler { @param('page', Types.PositiveInt, true) @param('category', Types.String, null, parseCategory) async get(domainId: string, page = 1, category: string[]) { @@ -139,7 +139,7 @@ class ProblemCategoryHandler extends ProblemHandler { } } -class ProblemRandomHandler extends ProblemHandler { +export class ProblemRandomHandler extends ProblemHandler { @param('category', Types.String, true, null, parseCategory) async get(domainId: string, category: string[] = []) { const q: any = category.length ? { $and: [] } : {}; @@ -162,7 +162,7 @@ class ProblemRandomHandler extends ProblemHandler { } } -class ProblemDetailHandler extends ProblemHandler { +export class ProblemDetailHandler extends ProblemHandler { pdoc: Pdoc; udoc: User; @@ -233,7 +233,7 @@ class ProblemDetailHandler extends ProblemHandler { } } -class ProblemSubmitHandler extends ProblemDetailHandler { +export class ProblemSubmitHandler extends ProblemDetailHandler { @param('pid', Types.String, null, parsePid) async get(domainId: string, pid: string | number) { this.response.template = 'problem_submit.html'; @@ -270,7 +270,7 @@ class ProblemSubmitHandler extends ProblemDetailHandler { } } -class ProblemPretestHandler extends ProblemDetailHandler { +export class ProblemPretestHandler extends ProblemDetailHandler { @param('lang', Types.String) @param('code', Types.String) @param('input', Types.String, true) @@ -292,7 +292,7 @@ class ProblemPretestHandler extends ProblemDetailHandler { } } -class ProblemPretestConnectionHandler extends ConnectionHandler { +export class ProblemPretestConnectionHandler extends ConnectionHandler { pid: string; domainId: string; @@ -331,7 +331,7 @@ class ProblemPretestConnectionHandler extends ConnectionHandler { } } -class ProblemStatisticsHandler extends ProblemDetailHandler { +export class ProblemStatisticsHandler extends ProblemDetailHandler { async get(domainId: string) { const udoc = await user.getById(domainId, this.pdoc.owner); const path = [ @@ -344,14 +344,14 @@ class ProblemStatisticsHandler extends ProblemDetailHandler { } } -class ProblemManageHandler extends ProblemDetailHandler { +export class ProblemManageHandler extends ProblemDetailHandler { async prepare() { if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM.PERM_EDIT_PROBLEM); else this.checkPerm(PERM.PERM_EDIT_PROBLEM_SELF); } } -class ProblemSettingsHandler extends ProblemManageHandler { +export class ProblemSettingsHandler extends ProblemManageHandler { @param('pid', Types.String) async get(domainId: string, pid: string) { this.response.template = 'problem_settings.html'; @@ -403,7 +403,7 @@ class ProblemSettingsHandler extends ProblemManageHandler { } } -class ProblemEditHandler extends ProblemManageHandler { +export class ProblemEditHandler extends ProblemManageHandler { async get({ pid }) { this.response.template = 'problem_edit.html'; this.response.body.path = [ @@ -417,14 +417,15 @@ class ProblemEditHandler extends ProblemManageHandler { @param('title', Types.String, isTitle) @param('content', Types.String, isContent) async post(domainId: string, title: string, content: string) { - const pid = checkPid(this.request.body.pid); + const $update: Partial = { title, content }; + if (this.request.body.pid) $update.pid = checkPid(this.request.body.pid); const pdoc = await problem.get(domainId, this.request.params.pid); - await problem.edit(domainId, pdoc.docId, { title, content, pid }); + await problem.edit(domainId, pdoc.docId, $update); this.response.redirect = this.url('problem_detail', { pid: this.request.params.pid }); } } -class ProblemDataUploadHandler extends ProblemManageHandler { +export class ProblemDataUploadHandler extends ProblemManageHandler { async get() { if (this.pdoc.data instanceof ObjectID) { const f = await file.getMeta(this.pdoc.data); @@ -448,7 +449,7 @@ class ProblemDataUploadHandler extends ProblemManageHandler { } } -class ProblemDataDownloadHandler extends ProblemDetailHandler { +export class ProblemDataDownloadHandler extends ProblemDetailHandler { async get({ pid }) { if (!this.user.hasPriv(PRIV.PRIV_JUDGE)) { if (this.user._id !== this.pdoc.owner) { @@ -480,7 +481,7 @@ class ProblemDataDownloadHandler extends ProblemDetailHandler { } } -class ProblemSolutionHandler extends ProblemDetailHandler { +export class ProblemSolutionHandler extends ProblemDetailHandler { @param('page', Types.PositiveInt, true) async get(domainId: string, page = 1) { this.response.template = 'problem_solution.html'; @@ -586,7 +587,7 @@ class ProblemSolutionHandler extends ProblemDetailHandler { } } -class ProblemSolutionRawHandler extends ProblemDetailHandler { +export class ProblemSolutionRawHandler extends ProblemDetailHandler { @param('psid', Types.ObjectID) async get(domainId: string, psid: ObjectID) { this.checkPerm(PERM.PERM_VIEW_PROBLEM_SOLUTION); @@ -596,7 +597,7 @@ class ProblemSolutionRawHandler extends ProblemDetailHandler { } } -class ProblemSolutionReplyRawHandler extends ProblemDetailHandler { +export class ProblemSolutionReplyRawHandler extends ProblemDetailHandler { @param('psid', Types.ObjectID) @param('psrid', Types.ObjectID) async get(domainId: string, psid: ObjectID, psrid: ObjectID) { @@ -608,7 +609,7 @@ class ProblemSolutionReplyRawHandler extends ProblemDetailHandler { } } -class ProblemCreateHandler extends Handler { +export class ProblemCreateHandler extends Handler { async get() { this.response.template = 'problem_edit.html'; this.checkPerm(PERM.PERM_CREATE_PROBLEM); diff --git a/packages/hydrooj/src/handler/training.ts b/packages/hydrooj/src/handler/training.ts index 5cf626250..043eb5964 100644 --- a/packages/hydrooj/src/handler/training.ts +++ b/packages/hydrooj/src/handler/training.ts @@ -1,5 +1,6 @@ import assert from 'assert'; -import { ObjectID } from 'mongodb'; +import { FilterQuery, ObjectID } from 'mongodb'; +import { Tdoc, TrainingDoc } from '../interface'; import { ValidationError, ProblemNotFoundError } from '../error'; import { isTitle, isContent, isDescription } from '../lib/validator'; import paginate from '../lib/paginate'; @@ -8,10 +9,10 @@ import * as problem from '../model/problem'; import * as builtin from '../model/builtin'; import * as training from '../model/training'; import * as user from '../model/user'; +import * as bus from '../service/bus'; import { Route, Handler, Types, param, } from '../service/server'; -import { Tdoc } from '../interface'; async function _parseDagJson(domainId: string, _dag: string): Promise { const parsed = []; @@ -56,6 +57,8 @@ async function _parseDagJson(domainId: string, _dag: string): Promise = {}; + await bus.serial('training/list', query, this); const [tdocs, tpcount] = await paginate( training.getMulti(domainId), page, @@ -96,6 +99,7 @@ class TrainingDetailHandler extends Handler { @param('tid', Types.ObjectID) async get(domainId: string, tid: ObjectID) { const tdoc = await training.get(domainId, tid); + await bus.serial('training/get', tdoc, this); const pids = training.getPids(tdoc); const [owner, pdict] = await Promise.all([ user.getById(domainId, tdoc.owner), diff --git a/packages/hydrooj/src/service/bus.ts b/packages/hydrooj/src/service/bus.ts index 1fc54c309..c3f2748eb 100644 --- a/packages/hydrooj/src/service/bus.ts +++ b/packages/hydrooj/src/service/bus.ts @@ -3,7 +3,7 @@ import cluster from 'cluster'; import { Db, FilterQuery } from 'mongodb'; import { Logger } from '../logger'; import { - Mdoc, Pdoc, Rdoc, User, + Mdoc, Pdoc, Rdoc, TrainingDoc, User, } from '../interface'; type DocType = import('../model/document').DocType; @@ -46,6 +46,9 @@ export interface EventMap { 'problem/setting': (update: Partial, handler: any) => VoidReturn 'problem/get': (doc: Pdoc, handler: any) => VoidReturn + 'training/list': (query: FilterQuery, handler: any) => VoidReturn + 'training/get': (tdoc: TrainingDoc, handler: any) => VoidReturn + 'record/change': (rdoc: Rdoc, $set?: any, $push?: any) => void }