mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 09:38:19 +08:00
core: contest: support realtime scoreboard after freeze contest (#544)
Co-authored-by: panda <panda_dtdyy@outlook.com>
This commit is contained in:
1 parent
e233bbb4cf
commit
17cf1194de
7 files changed
+96
-82
No files matched your search
@@ -11,7 +11,7 @@ import {
|
||||
ContestScoreboardHiddenError, FileLimitExceededError, FileUploadError,
|
||||
InvalidTokenError, NotAssignedError, PermissionError, ValidationError,
|
||||
} from '../error';
|
||||
import { Tdoc } from '../interface';
|
||||
import { ScoreboardConfig, Tdoc } from '../interface';
|
||||
import paginate from '../lib/paginate';
|
||||
import { PERM, PRIV, STATUS } from '../model/builtin';
|
||||
import * as contest from '../model/contest';
|
||||
@@ -265,13 +265,21 @@ export class ContestProblemListHandler extends ContestDetailBaseHandler {
|
||||
export class ContestScoreboardHandler extends ContestDetailBaseHandler {
|
||||
@param('tid', Types.ObjectId)
|
||||
@param('ext', Types.Range(['csv', 'html', 'ghost']), true)
|
||||
async get(domainId: string, tid: ObjectId, ext = '') {
|
||||
@param('realtime', Types.Boolean)
|
||||
async get(domainId: string, tid: ObjectId, ext = '', realtime) {
|
||||
if (!contest.canShowScoreboard.call(this, this.tdoc, true)) throw new ContestScoreboardHiddenError(tid);
|
||||
if (realtime && !this.user.own(this.tdoc)) {
|
||||
this.checkPerm(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
|
||||
}
|
||||
if (ext) {
|
||||
await this.exportScoreboard(domainId, tid, ext);
|
||||
return;
|
||||
}
|
||||
const [, rows, udict, pdict] = await contest.getScoreboard.call(this, domainId, tid, false);
|
||||
const config: ScoreboardConfig = { isExport: false };
|
||||
if (!realtime && this.tdoc.lockAt && !this.tdoc.unlocked) {
|
||||
config.lockAt = this.tdoc.lockAt;
|
||||
}
|
||||
const [, rows, udict, pdict] = await contest.getScoreboard.call(this, domainId, tid, config);
|
||||
this.response.template = 'contest_scoreboard.html';
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const page_name = this.tdoc.rule === 'homework'
|
||||
@@ -334,7 +342,7 @@ export class ContestScoreboardHandler extends ContestDetailBaseHandler {
|
||||
csv: async (rows) => `\uFEFF${rows.map((c) => (c.map((i) => i.value?.toString().replace(/\n/g, ' ')).join(','))).join('\n')}`,
|
||||
html: (rows, tdoc) => this.renderHTML('contest_scoreboard_download_html.html', { rows, tdoc }),
|
||||
};
|
||||
const [, rows] = await contest.getScoreboard.call(this, domainId, tid, true);
|
||||
const [, rows] = await contest.getScoreboard.call(this, domainId, tid, { isExport: true, lockAt: this.tdoc.lockAt });
|
||||
this.binary(await getContent[ext](rows, this.tdoc), `${this.tdoc.title}.${ext}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Filter, ObjectId } from 'mongodb';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { sortFiles, streamToBuffer } from '@hydrooj/utils/lib/utils';
|
||||
import {
|
||||
ContestNotAttendedError, ContestNotEndedError, ContestNotFoundError, ContestNotLiveError,
|
||||
BadRequestError, ContestNotAttendedError, ContestNotEndedError, ContestNotFoundError, ContestNotLiveError,
|
||||
FileLimitExceededError, HackFailedError, NoProblemError, NotFoundError,
|
||||
PermissionError, ProblemAlreadyExistError, ProblemAlreadyUsedByContestError, ProblemConfigError,
|
||||
ProblemIsReferencedError, ProblemNotAllowLanguageError, ProblemNotAllowPretestError, ProblemNotFoundError,
|
||||
@@ -449,6 +449,7 @@ export class ProblemDetailHandler extends ContestDetailBaseHandler {
|
||||
|
||||
@param('target', Types.String)
|
||||
async postCopy(domainId: string, target: string) {
|
||||
if (this.pdoc.reference) throw new BadRequestError('Cannot copy a referenced problem');
|
||||
const t = `,${this.domain.share || ''},`;
|
||||
if (t !== ',*,' && !t.includes(`,${target},`)) throw new PermissionError(target);
|
||||
const ddoc = await domain.get(target);
|
||||
@@ -1011,7 +1012,7 @@ export class ProblemPrefixListHandler extends Handler {
|
||||
export async function apply(ctx) {
|
||||
ctx.Route('problem_main', '/p', ProblemMainHandler, PERM.PERM_VIEW_PROBLEM);
|
||||
ctx.Route('problem_random', '/problem/random', ProblemRandomHandler, PERM.PERM_VIEW_PROBLEM);
|
||||
ctx.Route('problem_detail', '/p/:pid', ProblemDetailHandler, PERM.PERM_VIEW_PROBLEM);
|
||||
ctx.Route('problem_detail', '/p/:pid', ProblemDetailHandler);
|
||||
ctx.Route('problem_submit', '/p/:pid/submit', ProblemSubmitHandler, PERM.PERM_SUBMIT_PROBLEM);
|
||||
ctx.Route('problem_hack', '/p/:pid/hack/:rid', ProblemHackHandler, PERM.PERM_SUBMIT_PROBLEM);
|
||||
ctx.Route('problem_edit', '/p/:pid/edit', ProblemEditHandler);
|
||||
|
||||
Reference in new issue
Block a user