mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 17:38:19 +08:00
core: dump config.yaml to database (for #65)
This commit is contained in:
1 parent
3171277252
commit
dafa80f6f2
9 files changed
+152
-147
No files matched your search
@@ -1,7 +1,9 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import yaml from 'js-yaml';
|
||||
import { Dictionary, sum } from 'lodash';
|
||||
import { sum } from 'lodash';
|
||||
import readYamlCases, { convertIniConfig } from '@hydrooj/utils/lib/cases';
|
||||
import { changeErrorType } from '@hydrooj/utils/lib/utils';
|
||||
import { FormatError, SystemError } from './error';
|
||||
import { parseTimeMS, parseMemoryMB, ensureFile } from './utils';
|
||||
import { getConfig } from './config';
|
||||
@@ -193,102 +195,6 @@ async function readAutoCases(folder, { next }, cfg) {
|
||||
return config;
|
||||
}
|
||||
|
||||
export async function readYamlCases(folder: string, cfg: Dictionary<any> = {}, args) {
|
||||
const config: any = {
|
||||
checker_type: 'default',
|
||||
count: 0,
|
||||
subtasks: [],
|
||||
judge_extra_files: [],
|
||||
user_extra_files: [],
|
||||
};
|
||||
const next = args.next;
|
||||
const checkFile = ensureFile(folder);
|
||||
config.checker_type = cfg.checker_type || 'default';
|
||||
if (cfg.checker) config.checker = checkFile(cfg.checker, 'Cannot find checker {0}.');
|
||||
if (cfg.interactor) config.interactor = checkFile(cfg.interactor, 'Cannot find interactor {0}.');
|
||||
if (cfg.judge_extra_files) {
|
||||
if (typeof cfg.judge_extra_files === 'string') {
|
||||
config.judge_extra_files = [checkFile(cfg.judge_extra_files, 'Cannot find judge extra file {0}.')];
|
||||
} else if (cfg.judge_extra_files instanceof Array) {
|
||||
for (const file of cfg.judge_extra_files) {
|
||||
config.judge_extra_files.push(checkFile(file, 'Cannot find judge extra file {0}.'));
|
||||
}
|
||||
} else throw new FormatError('Invalid judge_extra_files config.');
|
||||
}
|
||||
if (cfg.user_extra_files) {
|
||||
if (typeof cfg.user_extra_files === 'string') {
|
||||
config.user_extra_files = [checkFile(cfg.user_extra_files, 'Cannot find user extra file {0}.')];
|
||||
} else if (cfg.user_extra_files instanceof Array) {
|
||||
for (const file of cfg.user_extra_files) {
|
||||
config.user_extra_files.push(checkFile(file, 'Cannot find user extra file {0}.'));
|
||||
}
|
||||
} else throw new FormatError('Invalid user_extra_files config.');
|
||||
}
|
||||
if (cfg.outputs) {
|
||||
config.type = 'submit_answer';
|
||||
} else if (cfg.cases) {
|
||||
config.subtasks = [{
|
||||
score: parseInt(cfg.score, 10) || Math.floor(100 / cfg.cases.length),
|
||||
time_limit_ms: parseTimeMS(cfg.time || '1s'),
|
||||
memory_limit_mb: parseMemoryMB(cfg.memory || '512m'),
|
||||
cases: [],
|
||||
type: 'sum',
|
||||
}];
|
||||
for (const c of cfg.cases) {
|
||||
config.count++;
|
||||
config.subtasks[0].cases.push({
|
||||
input: c.input ? checkFile(c.input, 'Cannot find input file {0}.') : '/dev/null',
|
||||
output: c.output ? checkFile(c.output, 'Cannot find output file {0}.') : '/dev/null',
|
||||
id: config.count,
|
||||
});
|
||||
}
|
||||
} else if (cfg.subtasks) {
|
||||
for (const subtask of cfg.subtasks) {
|
||||
const cases = [];
|
||||
for (const c of subtask.cases) {
|
||||
config.count++;
|
||||
cases.push({
|
||||
input: c.input ? checkFile(c.input, 'Cannot find input file {0}.') : '/dev/null',
|
||||
output: c.output ? checkFile(c.output, 'Cannot find output file {0}.') : '/dev/null',
|
||||
id: config.count,
|
||||
});
|
||||
}
|
||||
config.subtasks.push({
|
||||
score: parseInt(subtask.score, 10),
|
||||
if: subtask.if || [],
|
||||
cases,
|
||||
time_limit_ms: parseTimeMS(subtask.time || cfg.time || '1s'),
|
||||
memory_limit_mb: parseMemoryMB(subtask.memory || cfg.memory || '512m'),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const c = await readAutoCases(folder, { next }, cfg);
|
||||
config.subtasks = c.subtasks;
|
||||
config.count = c.count;
|
||||
}
|
||||
if (config.type === 'submit_answer' && !cfg.outputs) throw new FormatError('outputs config not found');
|
||||
return Object.assign(cfg, config);
|
||||
}
|
||||
|
||||
function convertIniConfig(ini: string) {
|
||||
const f = ini.split('\n');
|
||||
const count = parseInt(f[0], 10);
|
||||
const res = { subtasks: [] };
|
||||
for (let i = 1; i <= count; i++) {
|
||||
if (!f[i] || !f[i].trim()) throw new FormatError('Testcada count incorrect.');
|
||||
const [input, output, time, score, memory] = f[i].split('|');
|
||||
const cur = {
|
||||
cases: [{ input: `input/${input.toLowerCase()}`, output: `output/${output.toLowerCase()}` }],
|
||||
score: parseInt(score, 10),
|
||||
time: `${time}s`,
|
||||
memory: '512m',
|
||||
};
|
||||
if (!Number.isNaN(parseInt(memory, 10))) cur.memory = `${Math.floor(parseInt(memory, 10) / 1024)}m`;
|
||||
res.subtasks.push(cur);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function isValidConfig(config) {
|
||||
if (config.count > (getConfig('testcases_max') || 100)) {
|
||||
throw new FormatError('Too many testcases. Cancelled.');
|
||||
@@ -309,9 +215,23 @@ export default async function readCases(folder: string, cfg: Record<string, any>
|
||||
} else if (fs.existsSync(ymlConfig)) {
|
||||
config = { ...yaml.load(fs.readFileSync(ymlConfig).toString()) as object, ...cfg };
|
||||
} else if (fs.existsSync(iniConfig)) {
|
||||
config = { ...convertIniConfig(fs.readFileSync(iniConfig).toString()), ...cfg };
|
||||
try {
|
||||
config = { ...convertIniConfig(fs.readFileSync(iniConfig).toString()), ...cfg };
|
||||
} catch (e) {
|
||||
throw changeErrorType(e, FormatError);
|
||||
}
|
||||
} else config = cfg;
|
||||
const result = await readYamlCases(folder, config, args);
|
||||
let result;
|
||||
try {
|
||||
result = await readYamlCases(config, ensureFile(folder));
|
||||
} catch (e) {
|
||||
throw changeErrorType(e, FormatError);
|
||||
}
|
||||
if (!(result.outputs || result.subtasks.length)) {
|
||||
const c = await readAutoCases(folder, args, cfg);
|
||||
config.subtasks = c.subtasks;
|
||||
config.count = c.count;
|
||||
}
|
||||
isValidConfig(result);
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user