mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: fix icpc problem format import (#904)
This commit is contained in:
1 parent
5fd05c5052
commit
d1e79f3a9c
1 file changed
+22
-11
@@ -42,12 +42,16 @@ function sortable(source: string, namespaces: Record<string, string>) {
|
|||||||
function findOverrideContent(dir: string, base: string) {
|
function findOverrideContent(dir: string, base: string) {
|
||||||
let files = fs.readdirSync(dir);
|
let files = fs.readdirSync(dir);
|
||||||
if (files.includes(`${base}.md`)) return fs.readFileSync(path.join(dir, `${base}.md`), 'utf8');
|
if (files.includes(`${base}.md`)) return fs.readFileSync(path.join(dir, `${base}.md`), 'utf8');
|
||||||
|
if (files.includes(`${base}.pdf`)) return `@[PDF](file://${base}.pdf)`;
|
||||||
const languages = {};
|
const languages = {};
|
||||||
files = files.filter((i) => new RegExp(`^${base}_[a-zA-Z_]+\\.md$`).test(i));
|
files = files.filter((i) => new RegExp(`^${base}(?:_|.)([a-zA-Z_]+)\\.(md|pdf)$`).test(i));
|
||||||
if (!files.length) return null;
|
if (!files.length) return null;
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const lang = file.slice(8, -3);
|
const match = file.match(`^${base}(?:_|.)([a-zA-Z_]+)\\.(md|pdf)$`);
|
||||||
languages[lang] = fs.readFileSync(path.join(dir, file), 'utf8');
|
const lang = match[1];
|
||||||
|
const ext = match[2];
|
||||||
|
if (ext === 'pdf') languages[lang] = `@[PDF](file://${file})`;
|
||||||
|
else languages[lang] = fs.readFileSync(path.join(dir, file), 'utf8');
|
||||||
}
|
}
|
||||||
return JSON.stringify(languages);
|
return JSON.stringify(languages);
|
||||||
}
|
}
|
||||||
@@ -511,13 +515,16 @@ export class ProblemModel {
|
|||||||
}
|
}
|
||||||
if (!await isValidPid(pid)) pid = undefined;
|
if (!await isValidPid(pid)) pid = undefined;
|
||||||
}
|
}
|
||||||
const overrideContent = findOverrideContent(path.join(tmpdir, i), 'problem');
|
let overrideContent = findOverrideContent(path.join(tmpdir, i), 'problem');
|
||||||
|
overrideContent ||= findOverrideContent(path.join(tmpdir, i, 'statement'), 'problem');
|
||||||
|
overrideContent ||= findOverrideContent(path.join(tmpdir, i, 'problem_statement'), 'problem');
|
||||||
if (pdoc.difficulty && !Number.isSafeInteger(pdoc.difficulty)) delete pdoc.difficulty;
|
if (pdoc.difficulty && !Number.isSafeInteger(pdoc.difficulty)) delete pdoc.difficulty;
|
||||||
if (typeof pdoc.title !== 'string') throw new ValidationError('title', null, 'Invalid title');
|
const title = pdoc.title || (pdoc as any).name;
|
||||||
|
if (typeof title !== 'string') throw new ValidationError('title', null, 'Invalid title');
|
||||||
const allFiles = await getFiles(
|
const allFiles = await getFiles(
|
||||||
'testdata', 'additional_file',
|
'testdata', 'additional_file',
|
||||||
// The following is from https://icpc.io/problem-package-format/spec/2023-07-draft.html
|
// The following is from https://icpc.io/problem-package-format/spec/2023-07-draft.html
|
||||||
'attachments', 'generators', 'include', 'data', 'statement',
|
'attachments', 'generators', 'include', 'data', 'statement', 'problem_statement',
|
||||||
);
|
);
|
||||||
const totalSize = allFiles.map((f) => fs.statSync(f[1]).size).reduce((a, b) => a + b, 0);
|
const totalSize = allFiles.map((f) => fs.statSync(f[1]).size).reduce((a, b) => a + b, 0);
|
||||||
if (allFiles.length > SystemModel.get('limit.problem_files')) throw new ValidationError('files', null, 'Too many files');
|
if (allFiles.length > SystemModel.get('limit.problem_files')) throw new ValidationError('files', null, 'Too many files');
|
||||||
@@ -532,15 +539,19 @@ export class ProblemModel {
|
|||||||
// TODO: report this as a warning
|
// TODO: report this as a warning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((pdoc as any).limits) {
|
||||||
|
config.time = (pdoc as any).limits.time_limit;
|
||||||
|
config.memory = (pdoc as any).limits.memory;
|
||||||
|
}
|
||||||
const docId = overridePid
|
const docId = overridePid
|
||||||
? (await ProblemModel.edit(domainId, overridePid, {
|
? (await ProblemModel.edit(domainId, overridePid, {
|
||||||
title: pdoc.title.trim(),
|
title: title.trim(),
|
||||||
content: overrideContent || pdoc.content.toString() || 'No content',
|
content: overrideContent || pdoc.content?.toString() || 'No content',
|
||||||
tag,
|
tag,
|
||||||
difficulty: pdoc.difficulty,
|
difficulty: pdoc.difficulty,
|
||||||
})).docId
|
})).docId
|
||||||
: await ProblemModel.add(
|
: await ProblemModel.add(
|
||||||
domainId, pid, pdoc.title.trim(), overrideContent || pdoc.content.toString() || 'No content',
|
domainId, pid, title.trim(), overrideContent || pdoc.content?.toString() || 'No content',
|
||||||
operator || pdoc.owner, tag, { hidden: pdoc.hidden, difficulty: pdoc.difficulty },
|
operator || pdoc.owner, tag, { hidden: pdoc.hidden, difficulty: pdoc.difficulty },
|
||||||
);
|
);
|
||||||
// TODO delete unused file when updating pdoc
|
// TODO delete unused file when updating pdoc
|
||||||
@@ -559,7 +570,7 @@ export class ProblemModel {
|
|||||||
: null)?.(domainId, docId, file, path.join(loc, file));
|
: null)?.(domainId, docId, file, path.join(loc, file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const [f, loc] of await getFiles('additional_file', 'attachments', 'statement')) {
|
for (const [f, loc] of await getFiles('additional_file', 'attachments', 'statement', 'problem_statement')) {
|
||||||
if (!f.isFile()) continue;
|
if (!f.isFile()) continue;
|
||||||
await ProblemModel.addAdditionalFile(domainId, docId, f.name, loc);
|
await ProblemModel.addAdditionalFile(domainId, docId, f.name, loc);
|
||||||
}
|
}
|
||||||
@@ -583,7 +594,7 @@ export class ProblemModel {
|
|||||||
await RecordModel.add(domainId, docId, operator, f.name.split('.')[1], await fs.readFile(loc, 'utf-8'), true);
|
await RecordModel.add(domainId, docId, operator, f.name.split('.')[1], await fs.readFile(loc, 'utf-8'), true);
|
||||||
}
|
}
|
||||||
if (configChanged) await ProblemModel.addTestdata(domainId, docId, 'config.yaml', yaml.dump(config));
|
if (configChanged) await ProblemModel.addTestdata(domainId, docId, 'config.yaml', yaml.dump(config));
|
||||||
const message = `${overridePid ? 'Updated' : 'Imported'} problem ${pdoc.pid} (${pdoc.title})`;
|
const message = `${overridePid ? 'Updated' : 'Imported'} problem ${pdoc.pid || docId} (${title})`;
|
||||||
(process.env.HYDRO_CLI ? logger.info : progress)?.(message);
|
(process.env.HYDRO_CLI ? logger.info : progress)?.(message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
(process.env.HYDRO_CLI ? logger.info : progress)?.(`Error importing problem ${i}: ${e.message}`);
|
(process.env.HYDRO_CLI ? logger.info : progress)?.(`Error importing problem ${i}: ${e.message}`);
|
||||||
|
|||||||
Reference in new issue
Block a user