mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 01:38:19 +08:00
core: use Content/Name/Title to replace String
This commit is contained in:
1 parent
05968798fe
commit
2814bb51b9
15 files changed
+126
-117
No files matched your search
@@ -115,7 +115,7 @@ class ContestBoardcastHandler extends ContestHandler {
|
||||
}
|
||||
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async post(domainId: string, tid: ObjectID, content: string) {
|
||||
const tdoc = await contest.get(domainId, tid);
|
||||
if (tdoc.owner !== this.user._id) throw new PermissionError('Boardcast Message');
|
||||
@@ -202,10 +202,10 @@ class ContestEditHandler extends ContestHandler {
|
||||
@param('beginAtDate', Types.Date)
|
||||
@param('beginAtTime', Types.Time)
|
||||
@param('duration', Types.Float)
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('rule', Types.Range(contest.RULES))
|
||||
@param('pids', Types.String)
|
||||
@param('pids', Types.Content)
|
||||
@param('rated', Types.Boolean)
|
||||
async post(
|
||||
domainId: string, beginAtDate: string, beginAtTime: string, duration: number,
|
||||
@@ -284,7 +284,7 @@ class ContestProblemHandler extends ContestHandler {
|
||||
|
||||
export class ContestProblemFileDownloadHandler extends ContestProblemHandler {
|
||||
@query('type', Types.Range(['additional_file', 'testdata']), true)
|
||||
@param('filename', Types.String)
|
||||
@param('filename', Types.Name)
|
||||
@param('noDisposition', Types.Boolean)
|
||||
async get(domainId: string, type = 'additional_file', filename: string, noDisposition = false) {
|
||||
if (type === 'testdata' && this.user._id !== this.pdoc.owner) this.checkPerm(PERM.PERM_READ_PROBLEM_DATA);
|
||||
@@ -327,8 +327,8 @@ class ContestDetailProblemSubmitHandler extends ContestProblemHandler {
|
||||
}
|
||||
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('lang', Types.String)
|
||||
@param('code', Types.String)
|
||||
@param('lang', Types.Name)
|
||||
@param('code', Types.Content)
|
||||
async post(domainId: string, tid: ObjectID, lang: string, code: string) {
|
||||
await this.limitRate('add_record', 60, 10);
|
||||
const rid = await record.add(domainId, this.pdoc.docId, this.user._id, lang, code, true, {
|
||||
@@ -406,10 +406,10 @@ class ContestCreateHandler extends ContestHandler {
|
||||
@param('beginAtDate', Types.Date)
|
||||
@param('beginAtTime', Types.Time)
|
||||
@param('duration', Types.Float)
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('rule', Types.String)
|
||||
@param('pids', Types.String)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('rule', Types.Name)
|
||||
@param('pids', Types.Content)
|
||||
@param('rated', Types.Boolean)
|
||||
async post(
|
||||
domainId: string, beginAtDate: string, beginAtTime: string, duration: number,
|
||||
|
||||
@@ -32,8 +32,8 @@ class DiscussionHandler extends Handler {
|
||||
drrdoc?: Drrdoc;
|
||||
vnode?: any;
|
||||
|
||||
@param('type', Types.String, true)
|
||||
@param('name', Types.String, true)
|
||||
@param('type', Types.Name, true)
|
||||
@param('name', Types.Name, true)
|
||||
@param('did', Types.ObjectID, true)
|
||||
@param('drid', Types.ObjectID, true)
|
||||
@param('drrid', Types.ObjectID, true)
|
||||
@@ -97,8 +97,8 @@ class DiscussionMainHandler extends Handler {
|
||||
}
|
||||
|
||||
class DiscussionNodeHandler extends DiscussionHandler {
|
||||
@param('type', Types.String)
|
||||
@param('name', Types.String)
|
||||
@param('type', Types.Name)
|
||||
@param('name', Types.Name)
|
||||
@param('page', Types.PositiveInt, true)
|
||||
async get(domainId: string, type: string, _name: string, page = 1) {
|
||||
let name: ObjectID | string | number;
|
||||
@@ -149,10 +149,10 @@ class DiscussionCreateHandler extends DiscussionHandler {
|
||||
this.response.body = { path, vnode: this.vnode };
|
||||
}
|
||||
|
||||
@param('type', Types.String)
|
||||
@param('name', Types.String)
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('type', Types.Name)
|
||||
@param('name', Types.Name)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('highlight', Types.Boolean)
|
||||
@param('pin', Types.Boolean)
|
||||
async post(
|
||||
@@ -166,11 +166,6 @@ class DiscussionCreateHandler extends DiscussionHandler {
|
||||
else name = _name;
|
||||
if (highlight) this.checkPerm(PERM.PERM_HIGHLIGHT_DISCUSSION);
|
||||
if (pin) this.checkPerm(PERM.PERM_PIN_DISCUSSION);
|
||||
await bus.serial(
|
||||
'discussion/before-add',
|
||||
domainId, typeMapper[type], name, this.user._id,
|
||||
title, content, this.request.ip, highlight, pin,
|
||||
);
|
||||
const did = await discussion.add(
|
||||
domainId, typeMapper[type], name, this.user._id,
|
||||
title, content, this.request.ip, highlight, pin,
|
||||
@@ -217,7 +212,7 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
}
|
||||
|
||||
@param('did', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postReply(domainId: string, did: ObjectID, content: string) {
|
||||
this.checkPerm(PERM.PERM_REPLY_DISCUSSION);
|
||||
await this.limitRate('add_discussion', 3600, 60);
|
||||
@@ -236,7 +231,7 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
}
|
||||
|
||||
@param('drid', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postTailReply(domainId: string, drid: ObjectID, content: string) {
|
||||
this.checkPerm(PERM.PERM_REPLY_DISCUSSION);
|
||||
await this.limitRate('add_discussion', 3600, 60);
|
||||
@@ -245,7 +240,7 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
}
|
||||
|
||||
@param('drid', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postEditReply(domainId: string, drid: ObjectID, content: string) {
|
||||
this.checkPerm(PERM.PERM_EDIT_DISCUSSION_REPLY_SELF);
|
||||
if (this.drdoc.owner !== this.user._id) throw new PermissionError(PERM.PERM_EDIT_DISCUSSION_REPLY_SELF);
|
||||
@@ -268,7 +263,7 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
|
||||
@param('drid', Types.ObjectID)
|
||||
@param('drrid', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postEditTailReply(domainId: string, drid: ObjectID, drrid: ObjectID, content: string) {
|
||||
this.checkPerm(PERM.PERM_EDIT_DISCUSSION_REPLY_SELF);
|
||||
if (this.drdoc.owner !== this.user._id) throw new PermissionError(PERM.PERM_EDIT_DISCUSSION_REPLY_SELF);
|
||||
@@ -333,8 +328,8 @@ class DiscussionEditHandler extends DiscussionHandler {
|
||||
}
|
||||
|
||||
@param('did', Types.ObjectID)
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('highlight', Types.Boolean)
|
||||
@param('pin', Types.Boolean)
|
||||
async postUpdate(
|
||||
|
||||
@@ -130,14 +130,14 @@ class DomainUserHandler extends ManageHandler {
|
||||
}
|
||||
|
||||
@post('uid', Types.Int)
|
||||
@post('role', Types.String)
|
||||
@post('role', Types.Name)
|
||||
async postSetUser(domainId: string, uid: number, role: string) {
|
||||
await domain.setUserRole(domainId, uid, role);
|
||||
this.back();
|
||||
}
|
||||
|
||||
@param('uid', Types.NumericArray)
|
||||
@param('role', Types.String)
|
||||
@param('role', Types.Name)
|
||||
async postSetUsers(domainId: string, uid: number[], role: string) {
|
||||
await domain.setUserRole(domainId, uid, role);
|
||||
this.back();
|
||||
@@ -187,7 +187,7 @@ class DomainRoleHandler extends ManageHandler {
|
||||
this.response.body = { roles, domain: this.domain, path };
|
||||
}
|
||||
|
||||
@param('role', Types.String)
|
||||
@param('role', Types.Name)
|
||||
async postAdd(domainId: string, role: string) {
|
||||
const roles = await domain.getRoles(this.domain);
|
||||
const rdict: Dictionary<any> = {};
|
||||
@@ -229,9 +229,9 @@ class DomainJoinApplicationsHandler extends ManageHandler {
|
||||
}
|
||||
|
||||
@post('method', Types.Range([domain.JOIN_METHOD_NONE, domain.JOIN_METHOD_ALL, domain.JOIN_METHOD_CODE]))
|
||||
@post('role', Types.String, true)
|
||||
@post('role', Types.Name, true)
|
||||
@post('expire', Types.Int, true)
|
||||
@post('invitationCode', Types.String, true)
|
||||
@post('invitationCode', Types.Content, true)
|
||||
async post(domainId: string, method: number, role: string, expire: number, invitationCode = '') {
|
||||
const r = await domain.getRoles(this.domain);
|
||||
const roles = r.map((rl) => rl._id);
|
||||
@@ -269,7 +269,7 @@ class DomainJoinHandler extends Handler {
|
||||
if (this.user.role !== 'default') throw new DomainJoinAlreadyMemberError(this.domain._id, this.user._id);
|
||||
}
|
||||
|
||||
@param('code', Types.String, true)
|
||||
@param('code', Types.Content, true)
|
||||
async get(domainId: string, code: string) {
|
||||
this.response.template = 'domain_join.html';
|
||||
this.response.body.joinSettings = this.joinSettings;
|
||||
@@ -280,7 +280,7 @@ class DomainJoinHandler extends Handler {
|
||||
];
|
||||
}
|
||||
|
||||
@param('code', Types.String, true)
|
||||
@param('code', Types.Content, true)
|
||||
async post(domainId: string, code: string) {
|
||||
if (this.joinSettings.method === domain.JOIN_METHOD_CODE) {
|
||||
if (this.joinSettings.code !== code) {
|
||||
@@ -293,7 +293,7 @@ class DomainJoinHandler extends Handler {
|
||||
}
|
||||
|
||||
class DomainSearchHandler extends Handler {
|
||||
@param('q', Types.String)
|
||||
@param('q', Types.Content)
|
||||
async get(domainId: string, q: string) {
|
||||
const ddocs = await domain.getPrefixSearch(q, 20);
|
||||
for (let i = 0; i < ddocs.length; i++) {
|
||||
|
||||
@@ -151,7 +151,7 @@ class HomeSecurityHandler extends Handler {
|
||||
}
|
||||
|
||||
@param('currentPassword', Types.String)
|
||||
@param('mail', Types.String, isEmail)
|
||||
@param('mail', Types.Name, isEmail)
|
||||
async postChangeMail(domainId: string, current: string, email: string) {
|
||||
await this.limitRate('send_mail', 3600, 30);
|
||||
this.user.checkPassword(current);
|
||||
@@ -191,7 +191,7 @@ class HomeSecurityHandler extends Handler {
|
||||
}
|
||||
|
||||
class HomeSettingsHandler extends Handler {
|
||||
@param('category', Types.String)
|
||||
@param('category', Types.Name)
|
||||
async get(domainId: string, category: string) {
|
||||
const path = [
|
||||
['Hydro', 'homepage'],
|
||||
@@ -287,10 +287,10 @@ class HomeDomainCreateHandler extends Handler {
|
||||
this.response.template = 'domain_create.html';
|
||||
}
|
||||
|
||||
@param('id', Types.String)
|
||||
@param('name', Types.String, isTitle)
|
||||
@param('bulletin', Types.String, isContent)
|
||||
@param('gravatar', Types.String, true, isEmail)
|
||||
@param('id', Types.Name)
|
||||
@param('name', Types.Title)
|
||||
@param('bulletin', Types.Content)
|
||||
@param('gravatar', Types.Content, true, isEmail)
|
||||
async post(_: string, id: string, name: string, bulletin: string, gravatar: string) {
|
||||
const doc = await domain.get(id);
|
||||
if (doc) throw new DomainAlreadyExistsError(id);
|
||||
@@ -335,7 +335,7 @@ class HomeMessagesHandler extends Handler {
|
||||
}
|
||||
|
||||
@param('uid', Types.Int)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postSend(domainId: string, uid: number, content: string) {
|
||||
const udoc = await user.getById('system', uid);
|
||||
if (!udoc) throw new UserNotFoundError(uid);
|
||||
|
||||
@@ -174,8 +174,8 @@ class HomeworkDetailProblemSubmitHandler extends HomeworkDetailProblemHandler {
|
||||
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('pid', Types.UnsignedInt)
|
||||
@param('code', Types.String)
|
||||
@param('lang', Types.String)
|
||||
@param('code', Types.Content)
|
||||
@param('lang', Types.Name)
|
||||
async post(domainId: string, tid: ObjectID, pid: number, code: string, lang: string) {
|
||||
await this.limitRate('add_record', 60, 5);
|
||||
const tsdoc = await contest.getStatus(domainId, tid, this.user._id, document.TYPE_HOMEWORK);
|
||||
@@ -227,10 +227,10 @@ class HomeworkCreateHandler extends HomeworkHandler {
|
||||
@param('penaltySinceDate', Types.Date)
|
||||
@param('penaltySinceTime', Types.Time)
|
||||
@param('extensionDays', Types.Float)
|
||||
@param('penaltyRules', Types.String, validatePenaltyRules, convertPenaltyRules)
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('pids', Types.String)
|
||||
@param('penaltyRules', Types.Content, validatePenaltyRules, convertPenaltyRules)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('pids', Types.Content)
|
||||
@param('rated', Types.Boolean)
|
||||
async post(
|
||||
domainId: string, beginAtDate: string, beginAtTime: string,
|
||||
@@ -294,10 +294,10 @@ class HomeworkEditHandler extends HomeworkHandler {
|
||||
@param('penaltySinceDate', Types.Date)
|
||||
@param('penaltySinceTime', Types.Time)
|
||||
@param('extensionDays', Types.Float)
|
||||
@param('penaltyRules', Types.String, validatePenaltyRules, convertPenaltyRules)
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('pids', Types.String)
|
||||
@param('penaltyRules', Types.Content, validatePenaltyRules, convertPenaltyRules)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('pids', Types.Content)
|
||||
@param('rated', Types.Boolean)
|
||||
async post(
|
||||
domainId: string, tid: ObjectID, beginAtDate: string, beginAtTime: string,
|
||||
@@ -364,7 +364,7 @@ class HomeworkScoreboardHandler extends HomeworkHandler {
|
||||
|
||||
class HomeworkScoreboardDownloadHandler extends HomeworkHandler {
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('ext', Types.String)
|
||||
@param('ext', Types.Name)
|
||||
async get(domainId: string, tid: ObjectID, ext: string) {
|
||||
const getContent = {
|
||||
csv: (rows) => `\uFEFF${rows.map((c) => (c.map((i) => i.value).join(','))).join('\n')}`,
|
||||
|
||||
@@ -220,10 +220,10 @@ class ProblemImportSYZOJHandler extends Handler {
|
||||
return docId;
|
||||
}
|
||||
|
||||
@post('url', Types.String, true)
|
||||
@post('pid', Types.String, true, isPid)
|
||||
@post('url', Types.Content, true)
|
||||
@post('pid', Types.Name, true, isPid)
|
||||
@post('hidden', Types.Boolean)
|
||||
@post('prefix', Types.String, true)
|
||||
@post('prefix', Types.Name, true)
|
||||
@post('start', Types.UnsignedInt, true)
|
||||
@post('end', Types.UnsignedInt, true)
|
||||
async post(
|
||||
|
||||
@@ -102,8 +102,8 @@ class SystemScriptHandler extends SystemHandler {
|
||||
this.response.body.path.push(['manage_script', null]);
|
||||
}
|
||||
|
||||
@param('id', Types.String)
|
||||
@param('args', Types.String, true)
|
||||
@param('id', Types.Name)
|
||||
@param('args', Types.Content, true)
|
||||
async post(domainId: string, id: string, raw = '{}') {
|
||||
if (!global.Hydro.script[id]) throw new ValidationError('id');
|
||||
const args = JSON.parse(raw);
|
||||
@@ -189,7 +189,7 @@ class SystemUserImportHandler extends SystemHandler {
|
||||
this.response.template = 'manage_user_import.html';
|
||||
}
|
||||
|
||||
@param('users', Types.String)
|
||||
@param('users', Types.Content)
|
||||
@param('draft', Types.Boolean)
|
||||
async post(domainId: string, _users: string, draft: boolean) {
|
||||
const users = _users.split('\n');
|
||||
|
||||
@@ -36,7 +36,7 @@ class CheckInHandler extends Handler {
|
||||
}
|
||||
|
||||
class SwitchLanguageHandler extends Handler {
|
||||
@param('lang', Types.String)
|
||||
@param('lang', Types.Name)
|
||||
async get(domainId: string, lang: string) {
|
||||
if (this.user.hasPriv(PRIV.PRIV_USER_PROFILE)) {
|
||||
this.session.viewLang = lang;
|
||||
|
||||
@@ -53,7 +53,7 @@ export class ProblemHandler extends Handler {
|
||||
|
||||
export class ProblemMainHandler extends ProblemHandler {
|
||||
@param('page', Types.PositiveInt, true)
|
||||
@param('q', Types.String, true)
|
||||
@param('q', Types.Content, true)
|
||||
async get(domainId: string, page = 1, q = '') {
|
||||
this.response.template = 'problem_main.html';
|
||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||
@@ -112,7 +112,7 @@ export class ProblemMainHandler extends ProblemHandler {
|
||||
|
||||
export class ProblemCategoryHandler extends ProblemHandler {
|
||||
@param('page', Types.PositiveInt, true)
|
||||
@param('category', Types.String, null, parseCategory)
|
||||
@param('category', Types.Name, null, parseCategory)
|
||||
async get(domainId: string, page = 1, category: string[]) {
|
||||
this.response.template = 'problem_main.html';
|
||||
const q: any = { $and: [] };
|
||||
@@ -143,7 +143,7 @@ export class ProblemCategoryHandler extends ProblemHandler {
|
||||
}
|
||||
|
||||
export class ProblemRandomHandler extends ProblemHandler {
|
||||
@param('category', Types.String, true, null, parseCategory)
|
||||
@param('category', Types.Name, true, null, parseCategory)
|
||||
async get(domainId: string, category: string[] = []) {
|
||||
const q: FilterQuery<Pdoc> = category.length ? { $and: [] } : {};
|
||||
for (const tag of category) q.$and.push({ tag });
|
||||
@@ -160,7 +160,7 @@ export class ProblemDetailHandler extends ProblemHandler {
|
||||
pdoc: Pdoc;
|
||||
udoc: User;
|
||||
|
||||
@route('pid', Types.String, true, null, parsePid)
|
||||
@route('pid', Types.Name, true, null, parsePid)
|
||||
async _prepare(domainId: string, pid: number | string) {
|
||||
this.response.template = 'problem_detail.html';
|
||||
this.pdoc = await problem.get(domainId, pid, this.user._id);
|
||||
@@ -210,7 +210,7 @@ export class ProblemDetailHandler extends ProblemHandler {
|
||||
}
|
||||
|
||||
export class ProblemSubmitHandler extends ProblemDetailHandler {
|
||||
@param('pid', Types.String, null, parsePid)
|
||||
@param('pid', Types.Name, null, parsePid)
|
||||
async get(domainId: string, pid: string | number) {
|
||||
this.response.template = 'problem_submit.html';
|
||||
const rdocs = await record
|
||||
@@ -232,8 +232,8 @@ export class ProblemSubmitHandler extends ProblemDetailHandler {
|
||||
};
|
||||
}
|
||||
|
||||
@param('lang', Types.String)
|
||||
@param('code', Types.String)
|
||||
@param('lang', Types.Name)
|
||||
@param('code', Types.Content)
|
||||
async post(domainId: string, lang: string, code: string) {
|
||||
await this.limitRate('add_record', 60, 5);
|
||||
const rid = await record.add(domainId, this.pdoc.docId, this.user._id, lang, code, true);
|
||||
@@ -250,9 +250,9 @@ export class ProblemSubmitHandler extends ProblemDetailHandler {
|
||||
}
|
||||
|
||||
export class ProblemPretestHandler extends ProblemDetailHandler {
|
||||
@param('lang', Types.String)
|
||||
@param('code', Types.String)
|
||||
@param('input', Types.String, true)
|
||||
@param('lang', Types.Name)
|
||||
@param('code', Types.Content)
|
||||
@param('input', Types.Content, true)
|
||||
async post(domainId: string, lang: string, code: string, input = '') {
|
||||
await this.limitRate('add_record', 60, 5);
|
||||
const rid = await record.add(
|
||||
@@ -270,7 +270,7 @@ export class ProblemPretestConnectionHandler extends ConnectionHandler {
|
||||
domainId: string;
|
||||
dispose: bus.Disposable;
|
||||
|
||||
@param('pid', Types.String)
|
||||
@param('pid', Types.Name)
|
||||
async prepare(domainId: string, pid: string) {
|
||||
const pdoc = await problem.get(domainId, pid);
|
||||
if (!pdoc) throw new ProblemNotFoundError(domainId, pid);
|
||||
@@ -327,12 +327,12 @@ export class ProblemEditHandler extends ProblemManageHandler {
|
||||
];
|
||||
}
|
||||
|
||||
@route('pid', Types.String, null, parsePid)
|
||||
@post('title', Types.String, isTitle)
|
||||
@post('content', Types.String, isContent)
|
||||
@post('pid', Types.String, isPid, true)
|
||||
@route('pid', Types.Name, null, parsePid)
|
||||
@post('content', Types.Title)
|
||||
@post('content', Types.Content)
|
||||
@post('pid', Types.Name, isPid, true)
|
||||
@post('hidden', Types.Boolean)
|
||||
@post('tag', Types.String, true, null, parseCategory)
|
||||
@post('tag', Types.Content, true, null, parseCategory)
|
||||
async post(
|
||||
domainId: string, pid: string | number, title: string, content: string,
|
||||
newPid: string = '', hidden = false, tag: string[] = [],
|
||||
@@ -375,8 +375,8 @@ export class ProblemFilesHandler extends ProblemDetailHandler {
|
||||
this.response.body.links = links;
|
||||
}
|
||||
|
||||
@post('filename', Types.String)
|
||||
@post('type', Types.String, true)
|
||||
@post('filename', Types.Name)
|
||||
@post('type', Types.Content, true)
|
||||
async postUploadFile(domainId: string, filename: string, type = 'testdata') {
|
||||
if (!this.request.files.file) throw new ValidationError('file');
|
||||
if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
|
||||
@@ -413,7 +413,7 @@ export class ProblemFilesHandler extends ProblemDetailHandler {
|
||||
|
||||
export class ProblemFileDownloadHandler extends ProblemDetailHandler {
|
||||
@query('type', Types.Range(['additional_file', 'testdata']), true)
|
||||
@param('filename', Types.String)
|
||||
@param('filename', Types.Name)
|
||||
@param('noDisposition', Types.Boolean)
|
||||
async get(domainId: string, type = 'additional_file', filename: string, noDisposition = false) {
|
||||
if (type === 'testdata' && this.user._id !== this.pdoc.owner) this.checkPerm(PERM.PERM_READ_PROBLEM_DATA);
|
||||
@@ -456,14 +456,14 @@ export class ProblemSolutionHandler extends ProblemDetailHandler {
|
||||
await bus.serial('handler/solution/get', this);
|
||||
}
|
||||
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postSubmit(domainId: string, content: string) {
|
||||
this.checkPerm(PERM.PERM_CREATE_PROBLEM_SOLUTION);
|
||||
await solution.add(domainId, this.pdoc.docId, this.user._id, content);
|
||||
this.back();
|
||||
}
|
||||
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
@param('psid', Types.ObjectID)
|
||||
async postEditSolution(domainId: string, content: string, psid: ObjectID) {
|
||||
let psdoc = await solution.get(domainId, psid);
|
||||
@@ -483,7 +483,7 @@ export class ProblemSolutionHandler extends ProblemDetailHandler {
|
||||
}
|
||||
|
||||
@param('psid', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postReply(domainId: string, psid: ObjectID, content: string) {
|
||||
this.checkPerm(PERM.PERM_REPLY_PROBLEM_SOLUTION);
|
||||
const psdoc = await solution.get(domainId, psid);
|
||||
@@ -493,7 +493,7 @@ export class ProblemSolutionHandler extends ProblemDetailHandler {
|
||||
|
||||
@param('psid', Types.ObjectID)
|
||||
@param('psrid', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Content)
|
||||
async postEditReply(domainId: string, psid: ObjectID, psrid: ObjectID, content: string) {
|
||||
const [psdoc, psrdoc] = await solution.getReply(domainId, psid, psrid);
|
||||
if ((!psdoc) || psdoc.pid !== this.pdoc.docId) throw new SolutionNotFoundError(psid);
|
||||
@@ -561,11 +561,11 @@ export class ProblemCreateHandler extends Handler {
|
||||
};
|
||||
}
|
||||
|
||||
@post('title', Types.String, isTitle)
|
||||
@post('content', Types.String, isContent)
|
||||
@post('pid', Types.String, true, isPid)
|
||||
@post('content', Types.Title)
|
||||
@post('content', Types.Content)
|
||||
@post('pid', Types.Name, true, isPid)
|
||||
@post('hidden', Types.Boolean)
|
||||
@post('tag', Types.String, true, null, parseCategory)
|
||||
@post('tag', Types.Content, true, null, parseCategory)
|
||||
async post(domainId: string, title: string, content: string, pid: string, hidden = false, 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);
|
||||
|
||||
@@ -18,9 +18,9 @@ const RecordHandler = contest.ContestHandlerMixin(Handler);
|
||||
|
||||
class RecordListHandler extends RecordHandler {
|
||||
@param('page', Types.PositiveInt, true)
|
||||
@param('pid', Types.String, true)
|
||||
@param('pid', Types.Name, true)
|
||||
@param('tid', Types.ObjectID, true)
|
||||
@param('uidOrName', Types.String, true)
|
||||
@param('uidOrName', Types.Name, true)
|
||||
@param('allDomain', Types.Boolean, true)
|
||||
async get(domainId: string, page = 1, pid?: string, tid?: ObjectID, uidOrName?: string, all = false) {
|
||||
this.response.template = 'record_main.html';
|
||||
|
||||
@@ -50,7 +50,7 @@ export class ProblemSendHandler extends Handler {
|
||||
this.back();
|
||||
}
|
||||
|
||||
@post('token', Types.String)
|
||||
@post('token', Types.Content)
|
||||
async postInfo(domainId: string, tokenId: string) {
|
||||
const data = await token.get(tokenId, token.TYPE_EXPORT);
|
||||
if (!data) throw new InvalidTokenError(tokenId);
|
||||
@@ -60,7 +60,7 @@ export class ProblemSendHandler extends Handler {
|
||||
this.response.body = { pdocs: r, pids: data.pids };
|
||||
}
|
||||
|
||||
@post('token', Types.String, true)
|
||||
@post('token', Types.Content, true)
|
||||
@post('pids', Types.Array)
|
||||
async postFetch(domainId: string, tokenId: string, pids: number[]) {
|
||||
pids = pids.map((i) => (+i ? +i : i));
|
||||
|
||||
@@ -178,8 +178,8 @@ class TrainingCreateHandler extends Handler {
|
||||
this.response.body = { page_name: 'training_create', path };
|
||||
}
|
||||
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('dag', Types.String, isContent)
|
||||
@param('description', Types.String, isDescription)
|
||||
async post(
|
||||
@@ -224,8 +224,8 @@ class TrainingEditHandler extends Handler {
|
||||
}
|
||||
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('title', Types.String, isTitle)
|
||||
@param('content', Types.String, isContent)
|
||||
@param('content', Types.Title)
|
||||
@param('content', Types.Content)
|
||||
@param('dag', Types.String, isContent)
|
||||
@param('description', Types.String, isDescription)
|
||||
async post(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FilterQuery, ObjectID } from 'mongodb';
|
||||
import { omit } from 'lodash';
|
||||
import problem from './problem';
|
||||
import * as contest from './contest';
|
||||
import * as training from './training';
|
||||
@@ -63,24 +64,33 @@ export const typeDisplay = {
|
||||
[document.TYPE_HOMEWORK]: 'homework',
|
||||
};
|
||||
|
||||
export function add(
|
||||
export async function add(
|
||||
domainId: string, parentType: number, parentId: ObjectID | number | string,
|
||||
owner: number, title: string, content: string,
|
||||
ip: string | null = null, highlight: boolean, pin: boolean,
|
||||
): Promise<ObjectID> {
|
||||
return document.add(
|
||||
domainId, content, owner, document.TYPE_DISCUSSION,
|
||||
null, parentType, parentId,
|
||||
{
|
||||
title,
|
||||
ip,
|
||||
nReply: 0,
|
||||
highlight,
|
||||
pin,
|
||||
updateAt: new Date(),
|
||||
views: 0,
|
||||
},
|
||||
const payload: Partial<Ddoc> = {
|
||||
domainId,
|
||||
content,
|
||||
owner,
|
||||
parentType,
|
||||
parentId,
|
||||
title,
|
||||
ip,
|
||||
nReply: 0,
|
||||
highlight,
|
||||
pin,
|
||||
updateAt: new Date(),
|
||||
views: 0,
|
||||
};
|
||||
await bus.serial('discussion/before-add', payload);
|
||||
const res = await document.add(
|
||||
payload.domainId, payload.content, payload.owner, document.TYPE_DISCUSSION,
|
||||
null, payload.parentType, payload.parentId, omit(payload, ['domainId', 'content', 'owner', 'parentType', 'parentId']),
|
||||
);
|
||||
payload.docId = res;
|
||||
await bus.emit('discussion/add', payload);
|
||||
return payload.docId;
|
||||
}
|
||||
|
||||
// FIXME typings doesn't work
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Logger } from '../logger';
|
||||
import type {
|
||||
Mdoc, Pdoc, Rdoc, TrainingDoc, User,
|
||||
} from '../interface';
|
||||
import type { DomainDoc } from '../loader';
|
||||
import type { Ddoc, DomainDoc } from '../loader';
|
||||
import type { DocType } from '../model/document';
|
||||
import type { ProblemSolutionHandler } from '../handler/problem';
|
||||
import type { UserRegisterHandler } from '../handler/user';
|
||||
@@ -70,11 +70,8 @@ export interface EventMap extends Record<string, any> {
|
||||
'handler/finish/UserRegister': (thisArg: UserRegisterHandler) => VoidReturn
|
||||
'handler/solution/get': (thisArg: ProblemSolutionHandler) => VoidReturn
|
||||
|
||||
'discussion/before-add': (
|
||||
domainId: string, parentType: number, parentId: ObjectID | number | string,
|
||||
owner: number, title: string, content: string,
|
||||
ip: string | null, highlight: boolean, pin: boolean
|
||||
) => VoidReturn
|
||||
'discussion/before-add': (payload: Partial<Ddoc>) => VoidReturn
|
||||
'discussion/add': (payload: Partial<Ddoc>) => VoidReturn
|
||||
|
||||
'problem/before-add': (doc: Partial<Pdoc>) => VoidReturn
|
||||
'problem/add': (doc: Partial<Pdoc>, docId: number) => VoidReturn
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
NotFoundError, HydroError,
|
||||
} from '../error';
|
||||
import * as misc from '../lib/misc';
|
||||
import { isContent, isName, isTitle } from '../lib/validator';
|
||||
import user from '../model/user';
|
||||
import domain from '../model/domain';
|
||||
import * as system from '../model/system';
|
||||
@@ -57,6 +58,9 @@ interface ParamOption {
|
||||
type Type = [Converter, Validator, boolean?];
|
||||
|
||||
export interface Types {
|
||||
Content: Type,
|
||||
Name: Type,
|
||||
Title: Type,
|
||||
String: Type,
|
||||
Int: Type,
|
||||
UnsignedInt: Type,
|
||||
@@ -73,6 +77,9 @@ export interface Types {
|
||||
}
|
||||
|
||||
export const Types: Types = {
|
||||
Content: [(v) => v.toString(), isContent],
|
||||
Name: [(v) => v.toString(), isName],
|
||||
Title: [(v) => v.toString(), isTitle],
|
||||
String: [(v) => v.toString(), null],
|
||||
Int: [(v) => parseInt(v, 10), (v) => isSafeInteger(parseInt(v, 10))],
|
||||
UnsignedInt: [(v) => parseInt(v, 10), (v) => parseInt(v, 10) >= 0],
|
||||
|
||||
Reference in new issue
Block a user