MCPcopy Index your code
hub / github.com/hydro-dev/Hydro / FpsProblemImportHandler

Class FpsProblemImportHandler

packages/fps-importer/index.ts:14–118  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

12};
13
14class FpsProblemImportHandler extends Handler {
15 async get() {
16 this.response.template = 'problem_import_fps.html';
17 }
18
19 async run(domainId: string, result: any) {
20 if (!result?.fps) throw new BadRequestError('Selected file is not a valid FPS problemset.');
21 for (const p of result.fps.item) {
22 const markdown = [p.description?.[0], p.input?.[0], p.output?.[0], p.hint?.[0]].some((i) => i?.includes('[md]'));
23 let content = buildContent({
24 description: p.description?.[0],
25 input: p.input?.[0],
26 output: p.output?.[0],
27 samples: p.sample_input?.map((input, i) => [input, p.sample_output[i]]),
28 hint: p.hint?.[0],
29 source: p.source?.join(' '),
30 }, 'html', (s) => this.translate(s)).replace(/<math xm<x>lns=/g, '<math xmlns=').replace(/\[\/?md\]/g, '');
31 const config: ProblemConfigFile = {
32 time: p.time_limit[0]._ + p.time_limit[0].$.unit,
33 memory: p.memory_limit[0]._ + p.memory_limit[0].$.unit,
34 };
35 if (p.remote_oj?.[0]) {
36 config.type = ProblemType.Remote;
37 config.subType = knownRemoteMapping[p.remote_oj[0]] || p.remote_oj[0];
38 config.target = p.remote_id[0];
39 }
40 const title = decodeHTML(p.title.join(' '));
41 const tags = _.filter(p.source, (i: string) => i.trim()).flatMap((i) => i.split(' ')).filter((i) => i);
42 const pid = await ProblemModel.add(domainId, null, title, content, this.user._id, tags);
43 const tasks: Promise<any>[] = [ProblemModel.addTestdata(domainId, pid, 'config.yaml', Buffer.from(yaml.dump(config)))];
44 if (!markdown) tasks.push(ProblemModel.edit(domainId, pid, { html: true }));
45 const addTestdata = (node: any, index: string, ext: string) => {
46 if (!node || !['object', 'string'].includes(typeof node)) return; // Ignore file not exist
47 const id = node.$?.name || `${index}`;
48 // `filename` attribute introduced by winterant/OnlineJudge
49 // PLEASE, respect the spec
50 const filename = node.$?.filename || `${id}.${ext}`;
51 const c = node._ || (typeof node === 'string' ? node : '');
52 tasks.push(ProblemModel.addTestdata(domainId, pid, filename, Buffer.from(c)));
53 };
54 if (p.test_output) {
55 for (let i = 0; i < p.test_input.length; i++) {
56 addTestdata(p.test_input[i], `${i + 1}`, 'in');
57 addTestdata(p.test_output[i], `${i + 1}`, 'out');
58 }
59 } else if (p.test_input) {
60 // Some version of hustoj exports only test_input section
61 for (let i = 0; i < p.test_input.length / 2; i++) {
62 addTestdata(p.test_input[2 * i], `${i + 1}`, 'in');
63 addTestdata(p.test_input[2 * i + 1], `${i + 1}`, 'out');
64 }
65 }
66 if (p.img?.length) {
67 for (const img of p.img) {
68 const filename = randomstring(8) + img.src[0].split('/').pop().split('.').pop();
69 tasks.push(ProblemModel.addAdditionalFile(domainId, pid, filename, Buffer.from(img.base64[0], 'base64')));
70 content = content.replace(img.src[0], `file://${filename}`);
71 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected