From 2c2ce194a0bfab811d92062edd68784d6991a652 Mon Sep 17 00:00:00 2001 From: undefined Date: Sun, 6 Sep 2020 16:32:41 +0800 Subject: [PATCH] =?UTF-8?q?fps-importer:=20=E5=AF=B9=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E8=BF=9B=E8=A1=8Chtml-decode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/fps-importer/handler.ts | 44 ++++++++++++++++++++---------- packages/fps-importer/package.json | 3 +- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/packages/fps-importer/handler.ts b/packages/fps-importer/handler.ts index 5caa08f9c..f0f381f04 100644 --- a/packages/fps-importer/handler.ts +++ b/packages/fps-importer/handler.ts @@ -5,6 +5,8 @@ import fs from 'fs-extra'; import AdmZip from 'adm-zip'; import xml2js from 'xml2js'; import { ObjectID } from 'bson'; +import { filter } from 'lodash'; +import decodeHTML from 'decode-html'; import { LocalProblemConfig } from 'hydrooj'; import { Route, Handler, param, Types, @@ -14,28 +16,40 @@ import { ProblemAdd } from 'hydrooj/dist/lib/ui'; import * as file from 'hydrooj/dist/model/file'; import { PERM } from 'hydrooj/dist/model/builtin'; +const processing = {}; + class FpsProblemImportHandler extends Handler { @param('ufid', Types.ObjectID, true) async get(domainId: string, ufid?: ObjectID) { if (ufid) { + if (processing[ufid.toHexString()]) { + this.response.body = 'Processing'; + return; + } const stream = await file.get(ufid); - const buf = await streamToBuffer(stream); - let input = buf.toString(); + processing[ufid.toHexString()] = true; try { - await xml2js.parseStringPromise(input); - } catch (e) { - const zip = new AdmZip(buf); - const entries = zip.getEntries(); - for (const entry of entries) { - if (entry.entryName.endsWith('.xml')) { - input = entry.getData().toString(); - break; + const buf = await streamToBuffer(stream); + let input = buf.toString(); + try { + await xml2js.parseStringPromise(input); + } catch (e) { + const zip = new AdmZip(buf); + const entries = zip.getEntries(); + for (const entry of entries) { + if (entry.entryName.endsWith('.xml')) { + input = entry.getData().toString(); + break; + } } } + // @ts-ignore + await this.post({ domainId, input }); + await file.del(ufid); + } catch (e) { + processing[ufid.toHexString()] = false; + throw e; } - // @ts-ignore - await this.post({ domainId, input }); - await file.del(ufid); } else this.response.template = 'problem_import_fps.html'; } @@ -93,7 +107,9 @@ class FpsProblemImportHandler extends Handler { time: p.time_limit[0]._ + p.time_limit[0].$.unit, memory: p.memory_limit[0]._ + p.memory_limit[0].$.unit, }; - const pid = await problem.add(domainId, null, p.title.join(' '), content.join('\n'), this.user._id, p.source, []); + const title = decodeHTML(p.title.join(' ')); + const tags = filter(p.source, (i: string) => i.trim()); + const pid = await problem.add(domainId, null, title, content.join('\n'), this.user._id, tags, []); testdata.addFile('config.yaml', Buffer.from(`time: ${config.time}\nmemory: ${config.memory}`)); if (p.test_output) { for (let i = 0; i < p.test_input.length; i++) { diff --git a/packages/fps-importer/package.json b/packages/fps-importer/package.json index c50f70f3c..736dc61f4 100644 --- a/packages/fps-importer/package.json +++ b/packages/fps-importer/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/fps-importer", - "version": "1.1.0", + "version": "1.1.1", "description": "Import FPS problems", "main": "package.json", "repository": "https://github.com/hydro-dev/Hydro.git", @@ -8,6 +8,7 @@ "license": "AGPL-3.0-only", "dependencies": { "adm-zip": "^0.4.16", + "decode-html": "^2.0.0", "fs-extra": "^9.0.1", "xml2js": "^0.4.23" },