mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: use problem import options
This commit is contained in:
2 files changed
+38
-13
No files matched your search
@@ -18,8 +18,8 @@ class ProblemImportHydroHandler extends Handler {
|
|||||||
if (!this.request.files.file) throw new ValidationError('file');
|
if (!this.request.files.file) throw new ValidationError('file');
|
||||||
if (preferredPrefix && !/^[a-zA-Z]+$/.test(preferredPrefix)) throw new ValidationError('preferredPrefix');
|
if (preferredPrefix && !/^[a-zA-Z]+$/.test(preferredPrefix)) throw new ValidationError('preferredPrefix');
|
||||||
const promise = problem.import(
|
const promise = problem.import(
|
||||||
domainId, this.request.files.file.filepath, keepUser ? null : this.user._id,
|
domainId, this.request.files.file.filepath,
|
||||||
preferredPrefix, this.progress.bind(this),
|
{ preferredPrefix, progress: this.progress.bind(this), operator: keepUser ? null : this.user._id },
|
||||||
).catch((e) => MessageModel.send(1, this.user._id, `Import failed: ${e.message}\n${e.stack}`));
|
).catch((e) => MessageModel.send(1, this.user._id, `Import failed: ${e.message}\n${e.stack}`));
|
||||||
let resolved = false;
|
let resolved = false;
|
||||||
await Promise.race([
|
await Promise.race([
|
||||||
|
|||||||
@@ -54,6 +54,13 @@ function findOverrideContent(dir: string, base: string) {
|
|||||||
return JSON.stringify(languages);
|
return JSON.stringify(languages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ProblemImportOptions {
|
||||||
|
preferredPrefix?: string;
|
||||||
|
progress?: any;
|
||||||
|
override?: boolean;
|
||||||
|
operator?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class ProblemModel {
|
export class ProblemModel {
|
||||||
static PROJECTION_CONTEST_LIST: Field[] = [
|
static PROJECTION_CONTEST_LIST: Field[] = [
|
||||||
'_id', 'domainId', 'docType', 'docId', 'pid',
|
'_id', 'domainId', 'docType', 'docId', 'pid',
|
||||||
@@ -439,9 +446,16 @@ export class ProblemModel {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async import(domainId: string, filepath: string, operator = 1, preferredPrefix?: string, progress = null) {
|
static async import(domainId: string, filepath: string, options: ProblemImportOptions = {}) {
|
||||||
let tmpdir = '';
|
let tmpdir = '';
|
||||||
let del = false;
|
let del = false;
|
||||||
|
if (typeof options !== 'object') {
|
||||||
|
logger.warn('ProblemModel.import: options should be an object');
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
preferredPrefix, progress, override = false, operator = 1,
|
||||||
|
} = options;
|
||||||
try {
|
try {
|
||||||
if (filepath.endsWith('.zip')) {
|
if (filepath.endsWith('.zip')) {
|
||||||
tmpdir = path.join(os.tmpdir(), 'hydro', `${Math.random()}.import`);
|
tmpdir = path.join(os.tmpdir(), 'hydro', `${Math.random()}.import`);
|
||||||
@@ -474,10 +488,16 @@ export class ProblemModel {
|
|||||||
const pdoc: ProblemDoc = yaml.load(content) as any;
|
const pdoc: ProblemDoc = yaml.load(content) as any;
|
||||||
if (!pdoc) continue;
|
if (!pdoc) continue;
|
||||||
let pid = pdoc.pid;
|
let pid = pdoc.pid;
|
||||||
|
let overridePid = null;
|
||||||
|
|
||||||
const isValidPid = async (id: string) => {
|
const isValidPid = async (id: string) => {
|
||||||
if (!(/^[A-Za-z]+[0-9A-Za-z]*$/.test(id))) return false;
|
if (!(/^[A-Za-z]+[0-9A-Za-z]*$/.test(id))) return false;
|
||||||
if (await ProblemModel.get(domainId, id)) return false;
|
const doc = await ProblemModel.get(domainId, id);
|
||||||
|
if (doc) {
|
||||||
|
if (!override) return false;
|
||||||
|
overridePid = doc.docId;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
const getFiles = async (type: string) => {
|
const getFiles = async (type: string) => {
|
||||||
@@ -496,10 +516,18 @@ export class ProblemModel {
|
|||||||
const overrideContent = findOverrideContent(path.join(tmpdir, i), 'problem');
|
const overrideContent = findOverrideContent(path.join(tmpdir, i), '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');
|
if (typeof pdoc.title !== 'string') throw new ValidationError('title', null, 'Invalid title');
|
||||||
const docId = await ProblemModel.add(
|
const docId = overridePid
|
||||||
domainId, pid, pdoc.title.trim(), overrideContent || pdoc.content || 'No content',
|
? (await ProblemModel.edit(domainId, overridePid, {
|
||||||
operator || pdoc.owner, pdoc.tag || [], { hidden: pdoc.hidden, difficulty: pdoc.difficulty },
|
title: pdoc.title.trim(),
|
||||||
);
|
content: overrideContent || pdoc.content || 'No content',
|
||||||
|
tag: pdoc.tag || [],
|
||||||
|
difficulty: pdoc.difficulty,
|
||||||
|
})).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 },
|
||||||
|
);
|
||||||
|
// TODO delete unused file when updating pdoc
|
||||||
for (const [f, loc] of await getFiles('testdata')) {
|
for (const [f, loc] of await getFiles('testdata')) {
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
const sub = await fs.readdir(loc);
|
const sub = await fs.readdir(loc);
|
||||||
@@ -521,11 +549,8 @@ export class ProblemModel {
|
|||||||
if (count > 5) continue;
|
if (count > 5) continue;
|
||||||
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 (process.env.HYDRO_CLI) {
|
const message = `${overridePid ? 'Updated' : 'Imported'} problem ${pdoc.pid} (${pdoc.title})`;
|
||||||
logger.info(`Imported problem ${pdoc.pid} (${pdoc.title})`);
|
(process.env.HYDRO_CLI ? logger.info : progress)?.(message);
|
||||||
} else {
|
|
||||||
progress?.(`Imported problem ${pdoc.pid} (${pdoc.title})`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (del) await fs.remove(tmpdir);
|
if (del) await fs.remove(tmpdir);
|
||||||
|
|||||||
Reference in new issue
Block a user