core: contest: support realtime scoreboard after freeze contest (#544)

Co-authored-by: panda <panda_dtdyy@outlook.com>
This commit is contained in:
undefinedandpanda authored and GitHub committed 2023-03-22 23:22:49 +08:00
1 parent e233bbb4cf
commit 17cf1194de
7 files changed
+96 -82

No files matched your search

+12 -4
View File
@@ -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}`);
}