mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
migrate: add universaloj & hustoj upload file (#553)
Co-authored-by: undefined <i@undefined.moe>
This commit is contained in:
1 parent
e07fe63368
commit
d20c405da9
5 files changed
+617
-22
No files matched your search
@@ -1,10 +1,11 @@
|
||||
/* eslint-disable no-tabs */
|
||||
/* eslint-disable no-await-in-loop */
|
||||
import path from 'path';
|
||||
import mariadb from 'mariadb';
|
||||
import TurndownService from 'turndown';
|
||||
import {
|
||||
buildContent, ContestModel, DomainModel, fs, noop, NotFoundError, ObjectId, postJudge, ProblemModel,
|
||||
RecordDoc, RecordModel, SolutionModel, STATUS, SystemModel, Time, UserModel,
|
||||
_, buildContent, ContestModel, DomainModel, fs, noop, NotFoundError, ObjectId, postJudge, ProblemModel,
|
||||
RecordDoc, RecordModel, SolutionModel, STATUS, StorageModel, SystemModel, Time, UserModel,
|
||||
} from 'hydrooj';
|
||||
|
||||
const turndown = new TurndownService({
|
||||
@@ -48,10 +49,21 @@ const nameMap: Record<string, string> = {
|
||||
'test.in': 'test0.in',
|
||||
'test.out': 'test0.out',
|
||||
};
|
||||
|
||||
async function addContestFile(domainId: string, tid: ObjectId, filename: string, filepath: string) {
|
||||
const tdoc = await ContestModel.get(domainId, tid);
|
||||
await StorageModel.put(`contest/${domainId}/${tid}/${filename}`, filepath, 1);
|
||||
const meta = await StorageModel.getMeta(`contest/${domainId}/${tid}/${filename}`);
|
||||
const payload = { _id: filename, name: filename, ..._.pick(meta, ['size', 'lastModified', 'etag']) };
|
||||
if (!meta) return false;
|
||||
await ContestModel.edit(domainId, tid, { files: [...(tdoc.files || []), payload] });
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function run({
|
||||
host = 'localhost', port = 3306, name = 'jol',
|
||||
username, password, domainId, contestType = 'oi',
|
||||
dataDir, rerun = true, randomMail = false,
|
||||
dataDir, uploadDir = '/home/judge/src/web/upload/', rerun = true, randomMail = false,
|
||||
}, report: Function) {
|
||||
const src = await mariadb.createConnection({
|
||||
host,
|
||||
@@ -153,19 +165,28 @@ export async function run({
|
||||
if (opdoc) pidMap[pdoc.problem_id] = opdoc.docId;
|
||||
}
|
||||
if (!pidMap[pdoc.problem_id]) {
|
||||
const files = {};
|
||||
let content = buildContent({
|
||||
description: pdoc.description,
|
||||
input: pdoc.input,
|
||||
output: pdoc.output,
|
||||
samples: [[pdoc.sample_input.trim(), pdoc.sample_output.trim()]],
|
||||
hint: pdoc.hint,
|
||||
source: pdoc.source,
|
||||
}, 'html');
|
||||
const uploadFiles = content.matchAll(/(?:src|href)="\/upload\/([^"]+\/([^"]+))"/g);
|
||||
for (const file of uploadFiles) {
|
||||
files[file[2]] = await fs.readFile(path.join(uploadDir, file[1]));
|
||||
content = content.replace(`/upload/${file[1]}`, `file://${file[2]}`);
|
||||
}
|
||||
const pid = await ProblemModel.add(
|
||||
domainId, `P${pdoc.problem_id}`,
|
||||
pdoc.title, buildContent({
|
||||
description: pdoc.description,
|
||||
input: pdoc.input,
|
||||
output: pdoc.output,
|
||||
samples: [[pdoc.sample_input.trim(), pdoc.sample_output.trim()]],
|
||||
hint: pdoc.hint,
|
||||
source: pdoc.source,
|
||||
}, 'html'),
|
||||
pdoc.title, content,
|
||||
1, pdoc.source.split(' ').map((i) => i.trim()).filter((i) => i), pdoc.defunct === 'Y',
|
||||
);
|
||||
pidMap[pdoc.problem_id] = pid;
|
||||
await Promise.all(Object.keys(files).map((filename) => ProblemModel.addAdditionalFile(domainId, pid, filename, files[filename])));
|
||||
if (Object.keys(files).length) report({ message: `move ${Object.keys(files).length} file for problem ${pid}` });
|
||||
}
|
||||
const cdoc = await query(`SELECT * FROM \`privilege\` WHERE \`rightstr\` = 'p${pdoc.problem_id}'`);
|
||||
const maintainer = [];
|
||||
@@ -203,15 +224,23 @@ export async function run({
|
||||
for (const tdoc of tdocs) {
|
||||
const pdocs = await query(`SELECT * FROM \`contest_problem\` WHERE \`contest_id\` = ${tdoc.contest_id}`);
|
||||
const pids = pdocs.map((i) => pidMap[i.problem_id]).filter((i) => i);
|
||||
const files = {};
|
||||
let description = tdoc.description;
|
||||
const uploadFiles = description.matchAll(/(?:src|href)="\/upload\/([^"]+\/([^"]+))"/g);
|
||||
for (const file of uploadFiles) {
|
||||
files[file[2]] = await fs.readFile(path.join(uploadDir, file[1]));
|
||||
description = description.replace(`/upload/${file[1]}`, `file://${file[2]}`);
|
||||
}
|
||||
const tid = await ContestModel.add(
|
||||
domainId, tdoc.title, tdoc.description || 'Description',
|
||||
adminUids[0], contestType, tdoc.start_time, tdoc.end_time, pids, true,
|
||||
{ _code: password },
|
||||
);
|
||||
tidMap[tdoc.contest_id] = tid.toHexString();
|
||||
await Promise.all(Object.keys(files).map((filename) => addContestFile(domainId, tid, filename, files[filename])));
|
||||
if (Object.keys(files).length) report({ message: `move ${Object.keys(files).length} file for contest ${tidMap[tdoc.contest_id]}` });
|
||||
}
|
||||
report({ message: 'contest finished' });
|
||||
|
||||
/*
|
||||
solution 程序运行结果记录
|
||||
字段名 类型 长度 是否允许为空 备注
|
||||
|
||||
Reference in new issue
Block a user