从syzoj系统导入题目

This commit is contained in:
masnn committed 2020-04-17 12:47:45 +08:00
1 parent 97b0d782b9
commit ce3d11b999
12 files changed
+179 -34

No files matched your search

+85
View File
@@ -0,0 +1,85 @@
const assert = require('assert');
const download = require('../lib/download');
const problem = require('../model/problem');
const { Route, Handler } = require('../service/server');
const { PERM_CREATE_PROBLEM } = require('../permission');
const axios = require('../lib/axios');
const { ValidationError, RemoteOnlineJudgeError } = require('../error');
class ProblemImportHandler extends Handler {
async syzoj(url) {
const RE_SYZOJ = /https?:\/\/([a-zA-Z0-9\.]+)\/problem\/([0-9]+)\/?/i;
assert(url.match(RE_SYZOJ), new ValidationError('url'));
if (!url.endsWith('/')) url += '/';
const [, host, pid] = RE_SYZOJ.exec(url);
const res = await axios.get(`${url}export`);
assert(res.status === 200, new RemoteOnlineJudgeError('Cannot connect to target server'));
assert(res.data.success, new RemoteOnlineJudgeError((res.data.error || {}).message));
const p = res.data.obj;
const content = [
this.translate('problem.import.problem_description'),
p.description,
this.translate('problem.import.input_format'),
p.input_format,
this.translate('problem.import.output_format'),
p.output_format,
this.translate('problem.import.hint'),
p.hint,
this.translate('problem.import.limit_and_hint'),
p.limit_and_hint,
];
if (p.have_additional_file) {
content.push(
this.translate('problem.import.additional_file'),
`${url}download/additional_file`,
);
}
const pdoc = {
title: p.title,
content: content.join(' \n'),
owner: this.user._id,
from: url,
pid: `${host}_${pid}`,
config: {
time: p.time_limit,
memory: p.memory_limit * 1024,
filename: p.file_io_input_name,
type: p.type,
tags: p.tags,
},
};
const r = await download(`${url}testdata/download`);
return [pdoc, r];
}
async prepare() {
this.checkPerm(PERM_CREATE_PROBLEM);
}
async get() {
this.response.template = 'problem_import.html';
this.response.body = {
path: [
['Hydro', '/'],
['problem_main', '/p'],
['problem_import', null],
],
};
}
async post({
url, pid, hidden, remoteType,
}) {
if (remoteType !== 'syzoj') throw new ValidationError('remoteType');
const [pdoc, testdata] = await this.syzoj(url);
if (pid) pdoc.pid = pid;
if (hidden) pdoc.hidden = true;
const _id = await problem.add(pdoc);
console.log(_id);
await problem.setTestdata(_id, testdata);
this.response.body = { pid: pid || _id };
this.response.redirect = `/p/${pid || _id}/settings`;
}
}
Route('/problem/import', ProblemImportHandler);
+4 -4
View File
@@ -13,8 +13,8 @@ async function next(body) {
let rdoc = await record.get(body.rid);
const $set = {};
if (body.case) {
rdoc.cases.push(body.case);
$set.cases = rdoc.cases;
rdoc.testCases.push(body.case);
$set.testCases = rdoc.testCases;
}
if (body.judge_text) {
rdoc.judgeTexts.push(body.judge_text);
@@ -35,8 +35,8 @@ async function end(body) {
let rdoc = await record.get(body.rid);
const $set = {};
if (body.case) {
rdoc.cases.push(body.case);
$set.cases = rdoc.cases;
rdoc.testCases.push(body.case);
$set.testCases = rdoc.testCases;
}
if (body.judge_text) {
rdoc.judgeTexts.push(body.judge_text);
+3 -10
View File
@@ -142,12 +142,12 @@ class ProblemSettingsHandler extends ProblemManageHandler {
}
class ProblemEditHandler extends ProblemManageHandler {
async get() {
async get({ pid }) {
this.response.template = 'problem_edit.html';
this.response.body.path = [
['Hydro', '/'],
['problem_main', '/p'],
[this.pdoc.title, `/p/${this.request.params.pid}`, true],
[this.pdoc.title, `/p/${pid}`, true],
['problem_edit', null],
];
this.response.body.page_name = 'problem_edit';
@@ -177,14 +177,7 @@ class ProblemDataUploadHandler extends ProblemManageHandler {
async post() {
if (!this.request.files.file) throw new BadRequestError();
const r = fs.createReadStream(this.request.files.file.path);
const f = gridfs.openUploadStream('data.zip');
await new Promise((resolve, reject) => {
r.pipe(f);
f.once('finish', resolve);
f.once('error', reject);
});
if (this.pdoc.data && typeof this.pdoc.data === 'object') { gridfs.delete(this.pdoc.data); }
this.pdoc = await problem.edit(this.pdoc._id, { data: f.id });
await problem.setTestdata(this.pdoc._id, r);
if (this.pdoc.data && typeof this.pdoc.data === 'object') {
const files = await gridfs.find({ _id: this.pdoc.data }).toArray();
this.md5 = files[0].md5;