judge: submit_answer

This commit is contained in:
undefined committed 2022-04-03 15:02:32 +08:00
1 parent 5c4221778e
commit 0cb5afa169
18 files changed
+191 -82

No files matched your search

+9 -1
View File
@@ -117,13 +117,20 @@ export class JudgeFilesDownloadHandler extends Handler {
// eslint-disable-next-line no-await-in-loop
links[file] = await storage.signDownloadLink(
`problem/${pdoc.domainId}/${pdoc.docId}/testdata/${file}`,
file, false, 'judge',
file, true, 'judge',
);
}
this.response.body.links = links;
}
}
export class SubmissionDataDownloadHandler extends Handler {
@post('id', Types.String)
async post(domainId: string, id: string) {
this.response.body = { url: await storage.signDownloadLink(`submission/${id}`, 'code', true, 'judge') };
}
}
class JudgeConnectionHandler extends ConnectionHandler {
processing: any = null;
closed = false;
@@ -190,6 +197,7 @@ class JudgeConnectionHandler extends ConnectionHandler {
export async function apply() {
Route('judge_files_download', '/judge/files', JudgeFilesDownloadHandler, builtin.PRIV.PRIV_JUDGE);
Route('judge_submission_download', '/judge/code', SubmissionDataDownloadHandler, builtin.PRIV.PRIV_JUDGE);
Connection('judge_conn', '/judge/conn', JudgeConnectionHandler, builtin.PRIV.PRIV_JUDGE);
}
+16 -5
View File
@@ -2,6 +2,7 @@ import AdmZip from 'adm-zip';
import { statSync } from 'fs-extra';
import { intersection, isSafeInteger } from 'lodash';
import { FilterQuery, ObjectID } from 'mongodb';
import { nanoid } from 'nanoid';
import { sortFiles } from '@hydrooj/utils/lib/utils';
import {
BadRequestError, ContestNotAttendedError, ContestNotEndedError,
@@ -462,7 +463,7 @@ export class ProblemSubmitHandler extends ProblemDetailHandler {
}
@param('lang', Types.Name)
@param('code', Types.Content)
@param('code', Types.Content, true)
@param('pretest', Types.Boolean)
@param('input', Types.String, true)
@param('tid', Types.ObjectID, true)
@@ -470,11 +471,21 @@ export class ProblemSubmitHandler extends ProblemDetailHandler {
if (this.response.body.pdoc.config?.langs && !this.response.body.pdoc.config.langs.includes(lang)) {
throw new BadRequestError('Language not allowed.');
}
if (pretest && setting.langs[lang]?.pretest) lang = setting.langs[lang].pretest;
if (pretest && setting.langs[lang]?.pretest === false) throw new BadRequestError('Cannot run pretest for this language.');
if (pretest && !['default', 'fileio', 'remote_judge'].includes(this.response.body.pdoc.config?.type)) {
throw new BadRequestError('unable to run pretest');
if (pretest) {
if (setting.langs[lang]?.pretest) lang = setting.langs[lang].pretest;
if (setting.langs[lang]?.pretest === false) throw new BadRequestError('Cannot run pretest for this language.');
if (!['default', 'fileio', 'remote_judge'].includes(this.response.body.pdoc.config?.type)) {
throw new BadRequestError('unable to run pretest');
}
}
if (!code) {
const file = this.request.files?.file;
if (!file) throw new ValidationError('code');
if (file.size > 128 * 1024 * 1024) throw new ValidationError('file');
const id = nanoid();
await storage.put(`submission/${this.user._id}/${id}`, file.path);
code = `@@hydro_submission_file@@${this.user._id}/${id}#${file.name}`;
} else if (code.startsWith('@@hydro_submission_file@@')) throw new ValidationError('code');
await this.limitRate('add_record', 60, system.get('limit.submission'));
const rid = await record.add(domainId, this.pdoc.docId, this.user._id, lang, code, true, pretest ? input : tid, tid && !pretest);
const rdoc = await record.get(domainId, rid);
+15 -1
View File
@@ -8,6 +8,8 @@ import { PERM, PRIV, STATUS } from '../model/builtin';
import * as contest from '../model/contest';
import problem from '../model/problem';
import record from '../model/record';
import { langs } from '../model/setting';
import storage from '../model/storage';
import * as system from '../model/system';
import TaskModel from '../model/task';
import user from '../model/user';
@@ -101,7 +103,8 @@ class RecordListHandler extends Handler {
class RecordDetailHandler extends Handler {
@param('rid', Types.ObjectID)
async get(domainId: string, rid: ObjectID) {
@param('download', Types.Boolean)
async get(domainId: string, rid: ObjectID, download = false) {
this.response.template = 'record_detail.html';
const rdoc = await record.get(domainId, rid);
if (!rdoc) throw new RecordNotFoundError(rid);
@@ -132,6 +135,17 @@ class RecordDetailHandler extends Handler {
rdoc.compilerTexts = [];
}
if (download && rdoc.code.startsWith('@@hydro_submission_file@@')) {
const [id, filename] = rdoc.code.split('@@hydro_submission_file@@')[1].split('#');
this.response.redirect = await storage.signDownloadLink(`submission/${id}`, filename || 'code', true, 'judge');
return;
}
if (download) {
const lang = langs[rdoc.lang]?.pretest || rdoc.lang;
this.response.body = rdoc.code;
this.response.disposition = `attachment; filename="${langs[lang].code_file}` || `foo.${rdoc.lang}"`;
return;
}
if (pdoc && !(rdoc.contest && this.user._id === rdoc.uid)) {
if (!problem.canViewBy(pdoc, this.user)) throw new PermissionError(PERM.PERM_VIEW_PROBLEM_HIDDEN);
}