core: remote judge api

pull/162/head
undefined 3 years ago
parent 939584ec5e
commit 680e3ccd32

@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "2.28.44",
"version": "2.28.45",
"bin": "bin/hydrooj.js",
"main": "dist/loader.js",
"typings": "dist/loader.d.ts",
@ -12,7 +12,7 @@
},
"preferUnplugged": true,
"dependencies": {
"@hydrooj/utils": "workspace:*",
"@hydrooj/utils": "workspace:packages/utils",
"adm-zip": "^0.5.5",
"ansi_up": "^5.0.1",
"cac": "^6.7.3",

@ -295,7 +295,8 @@ export class ContestProblemHandler extends Handler {
// Navigate to current additional file download
// e.g. ![img](a.jpg) will navigate to ![img](./pid/file/a.jpg)
this.response.body.pdoc.content = this.response.body.pdoc.content
.replace(/\(file:\/\//g, `(./${args[2]}/file/`);
.replace(/\(file:\/\//g, `(./${args[2]}/file/`)
.replace(/="file:\/\//g, `="./${args[2]}/file/`);
}
}
@ -344,6 +345,9 @@ export class ContestDetailProblemSubmitHandler extends ContestProblemHandler {
if (this.response.body.pdoc.config?.langs && !this.response.body.pdoc.config.langs.includes(lang)) {
throw new BadRequestError('Language not allowed.');
}
if (this.domain.langs && !this.domain.langs.includes(lang)) {
throw new BadRequestError('Language not allowed');
}
await this.limitRate('add_record', 60, 10);
const rid = await record.add(domainId, pid, this.user._id, lang, code, true, pretest ? input : {
type: document.TYPE_CONTEST,

@ -168,7 +168,8 @@ class HomeworkDetailProblemHandler extends Handler {
// Navigate to current additional file download
// e.g. ![img](a.jpg) will navigate to ![img](./pid/file/a.jpg)
this.response.body.pdoc.content = this.response.body.pdoc.content
.replace(/\(file:\/\//g, `(./${pid}/file/`);
.replace(/\(file:\/\//g, `(./${pid}/file/`)
.reaplce(/="file:\/\//g, `="./${pid}/file/`);
}
}
@ -219,6 +220,9 @@ class HomeworkDetailProblemSubmitHandler extends HomeworkDetailProblemHandler {
if (this.response.body.pdoc.config?.langs && !this.response.body.pdoc.config.langs.includes(lang)) {
throw new BadRequestError('Language not allowed.');
}
if (this.domain.langs && !this.domain.langs.includes(lang)) {
throw new BadRequestError('Language not allowed');
}
await this.limitRate('add_record', 60, 5);
const rid = await record.add(domainId, pid, this.user._id, lang, code, true, pretest ? input : {
type: document.TYPE_HOMEWORK,

@ -212,7 +212,8 @@ export class ProblemDetailHandler extends ProblemHandler {
// e.g. ![img](a.jpg) will navigate to ![img](./pid/file/a.jpg)
if (!this.request.json) {
this.response.body.pdoc.content = this.response.body.pdoc.content
.replace(/\(file:\/\//g, `(./${this.pdoc.docId}/file/`);
.replace(/\(file:\/\//g, `(./${this.pdoc.docId}/file/`)
.replace(/="file:\/\//g, `="./${this.pdoc.docId}/file/`);
}
if (this.psdoc) {
this.response.body.rdoc = await record.get(this.domainId, this.psdoc.rid);
@ -269,6 +270,9 @@ 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 (this.domain.langs && !this.domain.langs.includes(lang)) {
throw new BadRequestError('Language not allowed');
}
await this.limitRate('add_record', 60, 5);
const rid = await record.add(domainId, this.pdoc.docId, this.user._id, lang, code, true, pretest ? input : undefined);
const rdoc = await record.get(domainId, rid);

@ -136,15 +136,19 @@ export enum SubtaskType {
}
export interface SubtaskConfig {
time?: number,
memory?: number,
score?: number,
type?: SubtaskType,
cases?: TestCaseConfig[],
time?: number;
memory?: number;
score?: number;
if?: number[];
id?: number;
type?: SubtaskType;
cases?: TestCaseConfig[];
}
export interface ProblemConfigFile {
type?: ProblemType;
subType?: string;
target?: string;
score?: number;
time?: string;
memory?: string;
@ -168,6 +172,8 @@ export interface ProblemConfig {
timeMin: number;
langs?: string[];
type: string;
subType?: string;
target?: string;
}
export interface PlainContentNode {

@ -26,15 +26,20 @@ export function buildContent(source: ProblemSource | ContentNode[], type: 'markd
node.type !== 'Plain' ? `## ${node.sectionTitle}` : '',
...node.type === 'Sample'
? [
'',
`\`\`\`input${++cnt}`,
node.payload[0],
'```',
'',
`\`\`\`output${cnt}`,
node.payload[1],
'```',
'',
]
: [],
'',
node.text,
'',
].join('\n')).join('\n');
}
return type === 'html'

@ -16,6 +16,8 @@ export async function parseConfig(config: string | ProblemConfigFile = {}) {
timeMax: 0,
type: cfg.type || 'default',
};
if (cfg.subType) result.subType = cfg.subType;
if (cfg.target) result.target = cfg.target;
if (cfg.subtasks.length) {
for (const subtask of cfg.subtasks) {
result.memoryMax = Math.max(result.memoryMax, subtask.memory);

@ -39,7 +39,7 @@ export class ProblemModel {
domainId: 'system',
docType: document.TYPE_PROBLEM,
docId: 0,
pid: null,
pid: '',
owner: 1,
title: '*',
content: '',

@ -9,7 +9,7 @@ import { STATUS } from './builtin';
import task from './task';
import problem from './problem';
import {
RecordDoc, ContestInfo, ProblemConfigFile, ExternalProblemId,
RecordDoc, ContestInfo, ProblemConfigFile, ExternalProblemId, ProblemConfig,
} from '../interface';
import { ArgMethod, buildProjection, Time } from '../utils';
import { MaybeArray } from '../typeutils';
@ -62,11 +62,25 @@ class RecordModel {
static async judge(domainId: string, rid: ObjectID, priority = 0, config: ProblemConfigFile = {}) {
const rdoc = await RecordModel.get(domainId, rid);
let data = [];
delete rdoc._id;
if (rdoc.pid) {
const pdoc = await problem.get(rdoc.pdomain, rdoc.pid);
data = pdoc.data;
if (typeof pdoc.config === 'string') throw new Error(); // Just for typings. This won't happen.
if (pdoc.config.type === 'remote_judge') {
return await task.add({
...rdoc,
priority,
type: 'remotejudge',
subType: pdoc.config.subType,
target: pdoc.config.target,
rid,
domainId,
config,
data,
});
}
}
delete rdoc._id;
await task.add({
...rdoc,
priority,

@ -140,6 +140,7 @@ DomainSetting(
Setting('setting_domain', 'avatar', '', 'text', 'avatar', 'Will be used as the domain icon.'),
Setting('setting_domain', 'share', '', 'text', 'Share problem with domain (* for any)'),
Setting('setting_domain', 'bulletin', '', 'markdown', 'Bulletin'),
Setting('setting_domain', 'langs', '', 'text', 'Allowed langs', null),
Setting('setting_storage', 'host', '', 'text', 'Custom host', null, FLAG_HIDDEN | FLAG_DISABLED),
);

@ -503,6 +503,7 @@ export class Handler extends HandlerCommon {
throw new NotFoundError(domainId);
}
this.UiContext.domainId = this.domainId;
this.UiContext.domain = this.domain;
this.user = await user.getById(domainId, this.session.uid, this.session.scope);
if (!this.user) {
this.session.uid = 0;

Loading…
Cancel
Save