mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
bump version
This commit is contained in:
3 files changed
+12
-75
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "4.14.0",
|
||||
"version": "4.14.1",
|
||||
"bin": "bin/hydrooj.js",
|
||||
"main": "src/plugin-api",
|
||||
"module": "src/plugin-api",
|
||||
|
||||
@@ -91,6 +91,11 @@ export class ContestDetailBaseHandler extends Handler {
|
||||
}
|
||||
}
|
||||
|
||||
tsdocAsPublic() {
|
||||
if (!this.tsdoc) return null;
|
||||
return pick(this.tsdoc, ['attend', 'startAt', ...(this.tdoc.duration ? ['endAt'] : [])]);
|
||||
}
|
||||
|
||||
@param('tid', Types.ObjectId, true)
|
||||
async after(domainId: string, tid: ObjectId) {
|
||||
if (!tid || this.tdoc.rule === 'homework') return;
|
||||
@@ -129,37 +134,19 @@ export class ContestDetailBaseHandler extends Handler {
|
||||
}
|
||||
}
|
||||
|
||||
export class ContestDetailHandler extends Handler {
|
||||
tdoc?: Tdoc;
|
||||
tsdoc?: any;
|
||||
|
||||
export class ContestDetailHandler extends ContestDetailBaseHandler {
|
||||
@param('tid', Types.ObjectId)
|
||||
async prepare(domainId: string, tid: ObjectId) {
|
||||
[this.tdoc, this.tsdoc] = await Promise.all([
|
||||
contest.get(domainId, tid),
|
||||
contest.getStatus(domainId, tid, this.user._id),
|
||||
]);
|
||||
if (contest.RULES[this.tdoc.rule].hidden) throw new ContestNotFoundError(domainId, tid);
|
||||
if (this.tdoc.assign?.length && !this.user.own(this.tdoc) && !this.user.hasPerm(PERM.PERM_VIEW_HIDDEN_CONTEST)) {
|
||||
const groups = await user.listGroup(domainId, this.user._id);
|
||||
if (!Set.intersection(this.tdoc.assign, groups.map((i) => i.name)).size) {
|
||||
throw new NotAssignedError('contest', tid);
|
||||
}
|
||||
}
|
||||
if (this.tdoc.duration && this.tsdoc?.startAt) {
|
||||
this.tsdoc.endAt = moment(this.tsdoc.startAt).add(this.tdoc.duration, 'hours').toDate();
|
||||
}
|
||||
}
|
||||
|
||||
@param('tid', Types.ObjectId)
|
||||
async get(domainId: string, tid: ObjectId) {
|
||||
this.response.template = 'contest_detail.html';
|
||||
const udict = await user.getList(domainId, [this.tdoc.owner]);
|
||||
const fields = ['attend', 'startAt'];
|
||||
if (this.tdoc.duration) fields.push('endAt');
|
||||
this.response.body = {
|
||||
tdoc: this.tdoc,
|
||||
tsdoc: pick(this.tsdoc, fields),
|
||||
tsdoc: this.tsdocAsPublic(),
|
||||
udict,
|
||||
files: sortFiles(this.tdoc.files || []),
|
||||
urlForFile: (filename: string) => this.url('contest_file_download', { tid, filename }),
|
||||
@@ -168,36 +155,6 @@ export class ContestDetailHandler extends Handler {
|
||||
this.response.body.tdoc.content = this.response.body.tdoc.content
|
||||
.replace(/\(file:\/\//g, `(./${this.tdoc.docId}/file/`)
|
||||
.replace(/="file:\/\//g, `="./${this.tdoc.docId}/file/`);
|
||||
const pdoc = 'pdoc' in this ? (this as any).pdoc : {};
|
||||
this.response.body.overrideNav = [
|
||||
{
|
||||
name: 'contest_main',
|
||||
args: {},
|
||||
displayName: 'Back to contest list',
|
||||
checker: () => true,
|
||||
},
|
||||
{
|
||||
name: 'contest_detail',
|
||||
displayName: this.tdoc.title,
|
||||
args: { tid, prefix: 'contest_detail' },
|
||||
checker: () => true,
|
||||
},
|
||||
{
|
||||
name: 'contest_problemlist',
|
||||
args: { tid },
|
||||
checker: () => true,
|
||||
},
|
||||
{
|
||||
name: 'contest_scoreboard',
|
||||
args: { tid, prefix: 'contest_scoreboard' },
|
||||
checker: () => contest.canShowScoreboard.call(this, this.tdoc, true),
|
||||
},
|
||||
{
|
||||
displayName: `${String.fromCharCode(65 + this.tdoc.pids.indexOf(pdoc.docId))}. ${pdoc.title}`,
|
||||
args: { query: { tid }, pid: pdoc.docId, prefix: 'contest_detail_problem' },
|
||||
checker: () => 'pdoc' in this,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@param('tid', Types.ObjectId)
|
||||
@@ -231,7 +188,7 @@ export class ContestProblemListHandler extends ContestDetailBaseHandler {
|
||||
await contest.setStatus(domainId, tid, this.user._id, { startAt: new Date() });
|
||||
this.tsdoc.startAt = new Date();
|
||||
}
|
||||
this.response.body.tsdoc = pick(this.tsdoc, ['attend', 'startAt', ...(this.tdoc.duration ? ['endAt'] : [])]);
|
||||
this.response.body.tsdoc = this.tsdocAsPublic();
|
||||
this.response.body.psdict = this.tsdoc.detail || {};
|
||||
const psdocs: any[] = Object.values(this.response.body.psdict);
|
||||
const canViewRecord = contest.canShowSelfRecord.call(this, this.tdoc);
|
||||
@@ -300,9 +257,8 @@ export class ContestScoreboardHandler extends ContestDetailBaseHandler {
|
||||
const page_name = this.tdoc.rule === 'homework'
|
||||
? 'homework_scoreboard'
|
||||
: 'contest_scoreboard';
|
||||
const tsdoc = pick(this.tsdoc, ['attend', 'startAt', ...(this.tdoc.duration ? ['endAt'] : [])]);
|
||||
this.response.body = {
|
||||
tdoc: this.tdoc, tsdoc, rows, udict, pdict, page_name, groups,
|
||||
tdoc: this.tdoc, tsdoc: this.tsdocAsPublic(), rows, udict, pdict, page_name, groups,
|
||||
};
|
||||
this.response.pjax = 'partials/scoreboard.html';
|
||||
this.response.template = 'contest_scoreboard.html';
|
||||
|
||||
@@ -11,7 +11,6 @@ import { PenaltyRules, Tdoc } from '../interface';
|
||||
import { PERM } from '../model/builtin';
|
||||
import * as contest from '../model/contest';
|
||||
import * as discussion from '../model/discussion';
|
||||
import * as oplog from '../model/oplog';
|
||||
import problem from '../model/problem';
|
||||
import record from '../model/record';
|
||||
import storage from '../model/storage';
|
||||
@@ -20,7 +19,7 @@ import user from '../model/user';
|
||||
import {
|
||||
Handler, param, post, Types,
|
||||
} from '../service/server';
|
||||
import { ContestCodeHandler, ContestScoreboardHandler } from './contest';
|
||||
import { ContestCodeHandler, ContestFileDownloadHandler, ContestScoreboardHandler } from './contest';
|
||||
|
||||
const validatePenaltyRules = (input: string) => yaml.load(input);
|
||||
const convertPenaltyRules = validatePenaltyRules;
|
||||
@@ -301,24 +300,6 @@ export class HomeworkFilesHandler extends Handler {
|
||||
}
|
||||
}
|
||||
|
||||
export class HomeworkFileDownloadHandler extends Handler {
|
||||
@param('tid', Types.ObjectId)
|
||||
@param('filename', Types.Filename)
|
||||
@param('noDisposition', Types.Boolean)
|
||||
async get(domainId: string, tid: ObjectId, filename: string, noDisposition = false) {
|
||||
this.response.addHeader('Cache-Control', 'public');
|
||||
const target = `contest/${domainId}/${tid}/${filename}`;
|
||||
const file = await storage.getMeta(target);
|
||||
await oplog.log(this, 'download.file.contest', {
|
||||
target,
|
||||
size: file?.size || 0,
|
||||
});
|
||||
this.response.redirect = await storage.signDownloadLink(
|
||||
target, noDisposition ? undefined : filename, false, 'user',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function apply(ctx) {
|
||||
ctx.Route('homework_main', '/homework', HomeworkMainHandler, PERM.PERM_VIEW_HOMEWORK);
|
||||
ctx.Route('homework_create', '/homework/create', HomeworkEditHandler);
|
||||
@@ -331,5 +312,5 @@ export async function apply(ctx) {
|
||||
ctx.Route('homework_code', '/homework/:tid/code', ContestCodeHandler, PERM.PERM_VIEW_HOMEWORK);
|
||||
ctx.Route('homework_edit', '/homework/:tid/edit', HomeworkEditHandler);
|
||||
ctx.Route('homework_files', '/homework/:tid/file', HomeworkFilesHandler, PERM.PERM_VIEW_HOMEWORK);
|
||||
ctx.Route('homework_file_download', '/homework/:tid/file/:filename', HomeworkFileDownloadHandler, PERM.PERM_VIEW_HOMEWORK);
|
||||
ctx.Route('homework_file_download', '/homework/:tid/file/:filename', ContestFileDownloadHandler, PERM.PERM_VIEW_HOMEWORK);
|
||||
}
|
||||
Reference in new issue
Block a user