(domainId: string, filepath: string, options: ProblemImportOptions = {})
| 465 | } |
| 466 | |
| 467 | static async import(domainId: string, filepath: string, options: ProblemImportOptions = {}) { |
| 468 | let tmpdir = ''; |
| 469 | if (typeof options !== 'object') { |
| 470 | logger.warn('ProblemModel.import: options should be an object'); |
| 471 | options = {}; |
| 472 | } |
| 473 | const { |
| 474 | preferredPrefix, progress, override = false, operator = 1, |
| 475 | } = options; |
| 476 | let delSource = options.delSource; |
| 477 | let problems: string[]; |
| 478 | const ddoc = await DomainModel.get(domainId); |
| 479 | if (!ddoc) throw new NotFoundError(domainId); |
| 480 | try { |
| 481 | if (filepath.endsWith('.zip')) { |
| 482 | tmpdir = path.join(os.tmpdir(), 'hydro', `${Math.random()}.import`); |
| 483 | const zip = new ZipReader(Readable.toWeb(fs.createReadStream(filepath))); |
| 484 | let entries: Entry[]; |
| 485 | try { |
| 486 | entries = await zip.getEntries(); |
| 487 | } catch (e) { |
| 488 | throw new ValidationError('zip', null, e.message); |
| 489 | } |
| 490 | delSource = true; |
| 491 | await extractZip(entries, tmpdir); |
| 492 | } else if (fs.statSync(filepath).isDirectory()) { |
| 493 | tmpdir = filepath; |
| 494 | } else { |
| 495 | throw new ValidationError('file', null, 'Invalid file'); |
| 496 | } |
| 497 | const files = await fs.readdir(tmpdir, { withFileTypes: true }); |
| 498 | if (files.find((f) => f.name === 'problem.yaml')) { |
| 499 | problems = ['.']; // special case for ICPC problem package |
| 500 | } else { |
| 501 | problems = files.filter((f) => f.isDirectory()).map((i) => i.name); |
| 502 | } |
| 503 | } catch (e) { |
| 504 | if (delSource) await fs.remove(tmpdir); |
| 505 | throw e; |
| 506 | } |
| 507 | for (const i of problems) { |
| 508 | try { |
| 509 | const files = await fs.readdir(path.join(tmpdir, i), { withFileTypes: true }); |
| 510 | if (!files.find((f) => f.name === 'problem.yaml')) continue; |
| 511 | if (process.env.HYDRO_CLI) logger.info(`Importing problem ${i}`); |
| 512 | const content = fs.readFileSync(path.join(tmpdir, i, 'problem.yaml'), 'utf-8'); |
| 513 | const pdoc: ProblemDoc = yaml.load(content) as any; |
| 514 | if (!pdoc) { |
| 515 | if (process.env.HYDRO_CLI) logger.error(`Invalid problem.yaml ${i}`); |
| 516 | continue; |
| 517 | } |
| 518 | let pid = pdoc.pid; |
| 519 | let overridePid = null; |
| 520 | |
| 521 | const isValidPid = async (id: string) => { |
| 522 | if (!(/^(?:[a-z0-9]{1,10}-)?[a-z][0-9a-z]*$/i.test(id))) return false; |
| 523 | if (id.includes('-')) { |
| 524 | const [prefix] = id.split('-'); |
no test coverage detected