mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
从syzoj系统导入题目
This commit is contained in:
1 parent
97b0d782b9
commit
ce3d11b999
12 files changed
+179
-34
No files matched your search
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user