mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 17:38:19 +08:00
core: import: support solution and std
This commit is contained in:
1 file changed
+28
-19
@@ -22,6 +22,8 @@ import { buildProjection } from '../utils';
|
||||
import { PERM, STATUS } from './builtin';
|
||||
import * as document from './document';
|
||||
import DomainModel from './domain';
|
||||
import RecordModel from './record';
|
||||
import SolutionModel from './solution';
|
||||
import storage from './storage';
|
||||
import user from './user';
|
||||
|
||||
@@ -33,11 +35,11 @@ function sortable(source: string) {
|
||||
return source.replace(/(\d+)/g, (str) => (str.length >= 6 ? str : ('0'.repeat(6 - str.length) + str)));
|
||||
}
|
||||
|
||||
function findOverrideContent(dir: string) {
|
||||
function findOverrideContent(dir: string, base: string) {
|
||||
let files = fs.readdirSync(dir);
|
||||
if (files.includes('problem.md')) return fs.readFileSync(path.join(dir, 'problem.md'), 'utf8');
|
||||
if (files.includes(`${base}.md`)) return fs.readFileSync(path.join(dir, `${base}.md`), 'utf8');
|
||||
const languages = {};
|
||||
files = files.filter((i) => /^problem_[a-zA-Z_]+\.md$/.test(i));
|
||||
files = files.filter((i) => new RegExp(`^${base}_[a-zA-Z_]+\\.md$`).test(i));
|
||||
if (!files.length) return null;
|
||||
for (const file of files) {
|
||||
const lang = file.slice(8, -3);
|
||||
@@ -470,8 +472,8 @@ export class ProblemModel {
|
||||
if (process.env.HYDRO_CLI) logger.info(`Importing problem ${p.name}`);
|
||||
const i = p.name;
|
||||
if (!p.isDirectory()) continue;
|
||||
const files = await fs.readdir(path.join(tmpdir, i));
|
||||
if (!files.includes('problem.yaml')) continue;
|
||||
const files = await fs.readdir(path.join(tmpdir, i), { withFileTypes: true });
|
||||
if (!files.find((f) => f.name === 'problem.yaml')) continue;
|
||||
const content = fs.readFileSync(path.join(tmpdir, i, 'problem.yaml'), 'utf-8');
|
||||
const pdoc: ProblemDoc = yaml.load(content) as any;
|
||||
if (!pdoc) continue;
|
||||
@@ -482,6 +484,11 @@ export class ProblemModel {
|
||||
if (await ProblemModel.get(domainId, id)) return false;
|
||||
return true;
|
||||
};
|
||||
const getFiles = async (type: string) => {
|
||||
if (!files.find((f) => f.name === type && f.isDirectory())) return [];
|
||||
const rs = await fs.readdir(path.join(tmpdir, i, type), { withFileTypes: true });
|
||||
return rs.map((r) => [r, path.join(tmpdir, i, type, r.name)] as [fs.Dirent, string]);
|
||||
};
|
||||
|
||||
if (pid) {
|
||||
if (preferredPrefix) {
|
||||
@@ -490,31 +497,33 @@ export class ProblemModel {
|
||||
}
|
||||
if (!await isValidPid(pid)) pid = undefined;
|
||||
}
|
||||
const overrideContent = findOverrideContent(path.join(tmpdir, i));
|
||||
const overrideContent = findOverrideContent(path.join(tmpdir, i), 'problem');
|
||||
if (pdoc.difficulty && !Number.isSafeInteger(pdoc.difficulty)) delete pdoc.difficulty;
|
||||
if (typeof pdoc.title !== 'string') throw new ValidationError('title', null, 'Invalid title');
|
||||
const docId = await ProblemModel.add(
|
||||
domainId, pid, pdoc.title.trim(), overrideContent || pdoc.content || 'No content',
|
||||
operator || pdoc.owner, pdoc.tag || [], { hidden: pdoc.hidden, difficulty: pdoc.difficulty },
|
||||
);
|
||||
if (files.includes('testdata')) {
|
||||
const datas = await fs.readdir(path.join(tmpdir, i, 'testdata'), { withFileTypes: true });
|
||||
for (const f of datas) {
|
||||
for (const [f, loc] of await getFiles('testdata')) {
|
||||
if (f.isDirectory()) {
|
||||
const sub = await fs.readdir(path.join(tmpdir, i, 'testdata', f.name));
|
||||
const sub = await fs.readdir(loc);
|
||||
for (const s of sub) await ProblemModel.addTestdata(domainId, docId, s, path.join(tmpdir, i, 'testdata', f.name, s));
|
||||
} else if (f.isFile()) {
|
||||
await ProblemModel.addTestdata(domainId, docId, f.name, path.join(tmpdir, i, 'testdata', f.name));
|
||||
} else if (f.isFile()) await ProblemModel.addTestdata(domainId, docId, f.name, loc);
|
||||
}
|
||||
for (const [f, loc] of await getFiles('additional_file')) {
|
||||
if (!f.isFile()) continue;
|
||||
await ProblemModel.addAdditionalFile(domainId, docId, f.name, loc);
|
||||
}
|
||||
for (const [f, loc] of await getFiles('solution')) {
|
||||
if (!f.isFile()) continue;
|
||||
await SolutionModel.add(domainId, docId, operator, await fs.readFile(loc, 'utf-8'));
|
||||
}
|
||||
if (files.includes('additional_file')) {
|
||||
const datas = await fs.readdir(path.join(tmpdir, i, 'additional_file'), { withFileTypes: true });
|
||||
for (const f of datas) {
|
||||
if (f.isFile()) {
|
||||
await ProblemModel.addAdditionalFile(domainId, docId, f.name, path.join(tmpdir, i, 'additional_file', f.name));
|
||||
}
|
||||
}
|
||||
let count = 0;
|
||||
for (const [f, loc] of await getFiles('std')) {
|
||||
if (!f.isFile()) continue;
|
||||
count++;
|
||||
if (count > 5) continue;
|
||||
await RecordModel.add(domainId, docId, operator, f.name.split('.')[1], await fs.readFile(loc, 'utf-8'), true);
|
||||
}
|
||||
if (process.env.HYDRO_CLI) logger.info(`Imported problem ${pdoc.pid} (${pdoc.title})`);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user