core: 添加buildContent方法

This commit is contained in:
undefined committed 2020-11-20 19:40:13 +08:00
1 parent f81d7daa54
commit 19ebf5e9a8
5 files changed
+116 -92

No files matched your search

+11 -46
View File
@@ -11,7 +11,7 @@ import { LocalProblemConfig } from 'hydrooj';
import {
Route, Handler, param, Types,
} from 'hydrooj/dist/service/server';
import { streamToBuffer } from 'hydrooj/dist/utils';
import { buildContent, streamToBuffer } from 'hydrooj/dist/utils';
import { ProblemAdd } from 'hydrooj/dist/lib/ui';
import * as file from 'hydrooj/dist/model/file';
import * as solution from 'hydrooj/dist/model/solution';
@@ -60,57 +60,22 @@ class FpsProblemImportHandler extends Handler {
const problem = global.Hydro.model.problem;
for (const p of result.fps.item) {
const testdata = new AdmZip();
const content = [];
if (p.description) {
content.push(
`<h2>${this.translate('Description')}</h2>`,
...p.description,
);
}
if (p.input) {
content.push(
`<h2>${this.translate('Input Format')}</h2>`,
...p.input,
);
}
if (p.output) {
content.push(
`<h2>${this.translate('Output Format')}</h2>`,
...p.output,
);
}
if (p.sample_input) {
if (p.sample_input.length === 1) {
content.push(
`<h2>${this.translate('Sample Input')}</h2>`,
`<pre><code>${p.sample_input[0]}</code></pre>`,
`<h2>${this.translate('Sample Output')}</h2>`,
`<pre><code>${p.sample_output[0]}</code></pre>`,
);
} else {
for (let i = 0; i < p.sample_input.length; i++) {
content.push(
`<h2>${this.translate('Sample Input')}${i + 1}</h2>`,
`<pre><code>${p.sample_input[i]}</code></pre>`,
`<h2>${this.translate('Sample Output')}${i + 1}</h2>`,
`<pre><code>${p.sample_output[i]}</code></pre>`,
);
}
}
}
if (p.hint) {
content.push(
`<h2>${this.translate('Hint')}</h2>`,
...p.hint,
);
}
const content = buildContent({
description: p.description,
input: p.input,
output: p.output,
samples: p.sample_input
? p.sample_input.map((si: string, i: number) => [si, p.sample_output[i]])
: [],
hint: p.hint,
}, 'html', this.translate.bind(this));
const config: LocalProblemConfig = {
time: p.time_limit[0]._ + p.time_limit[0].$.unit,
memory: p.memory_limit[0]._ + p.memory_limit[0].$.unit,
};
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, []);
const pid = await problem.add(domainId, null, title, content, 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++) {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "2.13.52",
"version": "2.13.53",
"bin": "bin/hydrooj.js",
"main": "dist/loader.js",
"typings": "dist/loader.d.ts",
+68
View File
@@ -201,3 +201,71 @@ export function sleep(timeout: number) {
}, timeout);
});
}
function deepen(modifyString: (source: string) => string) {
function modifyObject<T>(source: T): T {
if (typeof source !== 'object' || !source) return source;
if (Array.isArray(source)) return source.map(modifyObject) as any;
const result = {} as T;
for (const key in source) {
result[modifyString(key)] = modifyObject(source[key]);
}
return result;
}
return function t<T>(source: T): T {
if (typeof source === 'string') {
return modifyString(source) as any;
}
return modifyObject(source);
};
}
export const camelCase = deepen((source) => source.replace(/[_-][a-z]/g, (str) => str.slice(1).toUpperCase()));
export const paramCase = deepen((source) => source.replace(/_/g, '-').replace(/(?<!^)[A-Z]/g, (str) => `-${str.toLowerCase()}`));
export const snakeCase = deepen((source) => source.replace(/-/g, '_').replace(/(?<!^)[A-Z]/g, (str) => `_${str.toLowerCase()}`));
interface ProblemSource {
description?: string,
input?: string,
output?: string,
samples?: [string, string][],
hint?: string,
source?: string,
}
export function buildContent(source: ProblemSource, type: 'markdown' | 'html' = 'markdown', translate?: Function) {
const _ = translate || ((s: string) => s);
return type === 'html'
? [
...source.description ? [`<h2>${_('Description')}</h2>`, source.description] : [],
...source.input ? [`<h2>${_('Input Format')}</h2>`, source.input] : [],
...source.output ? [`<h2>'${_('Output Format')}</h2>`, source.output] : [],
...(source.samples).map((sample, i) => [
`<h2>${_('Sample Input')} ${i + 1}</h2><pre>`,
sample[0],
`</pre><h2>${_('Sample Output')} ${i + 1}</h2><pre>`,
sample[1],
'</pre>',
].join('\n')),
...source.hint ? [`<h2>${_('Hint')}</h2>`, source.hint] : [],
...source.source ? [`<h2>${_('Source')}</h2>`, source.source] : [],
].join('\n')
: [
...source.description ? [`## ${_('Description')}`, source.description] : [],
...source.input ? [`## ${_('Input Format')}`, source.input] : [],
...source.output ? [`## '${_('Output Format')}`, source.output] : [],
...(source.samples).map((sample, i) => [
`## ${_('Sample Input')} ${i + 1}`,
'```',
sample[0],
'```',
`## ${_('Sample Output')} ${i + 1}`,
'```',
sample[1],
'```',
].join('\n')),
...source.hint ? [`## ${_('Hint')}`, source.hint] : [],
...source.source ? [`## ${_('Source')}`, source.source] : [],
].join('\n');
}
+9 -31
View File
@@ -10,7 +10,7 @@ import {
Route, Handler, param, Types,
} from 'hydrooj/dist/service/server';
import { BadRequestError } from 'hydrooj/dist/error';
import { streamToBuffer } from 'hydrooj/dist/utils';
import { buildContent, streamToBuffer } from 'hydrooj/dist/utils';
import { ProblemAdd } from 'hydrooj/dist/lib/ui';
import * as file from 'hydrooj/dist/model/file';
import * as problem from 'hydrooj/dist/model/problem';
@@ -31,36 +31,14 @@ class ImportQduojHandler extends Handler {
for (const folder of folders) {
const buf = await fs.readFile(path.join(tmp, folder, 'problem.json'));
const pdoc = JSON.parse(buf.toString());
const content = [
...pdoc.description?.value
? [
'<h2>Description</h2>',
pdoc.description.value,
] : [],
...pdoc.input_description?.value
? [
'<h2>Input Description</h2>',
pdoc.input_description.value,
] : [],
...pdoc.output_description?.value
? [
'<h2>Output Description</h2>',
pdoc.output_description.value,
] : [],
...(pdoc.samples as any[]).map((sample, i) => [
`<h2>Sample Input ${i + 1}</h2><pre>`,
sample.input,
`</pre><h2>Sample Output ${i + 1}</h2><pre>`,
sample.output,
'</pre>',
].join('\n')),
...pdoc.hint?.value
? [
'<h2>Hint</h2>',
pdoc.hint.value,
] : [],
...pdoc.source ? ['<h2>Source</h2>', pdoc.source] : [],
].join('\n');
const content = buildContent({
description: pdoc.description?.value,
input: pdoc.input_description?.value,
output: pdoc.output_description?.value,
samples: pdoc.samples.map((i) => [i.input, i.output]),
hint: pdoc.hint?.value,
source: pdoc.source?.value,
}, 'html');
const pid = await problem.add(domainId, pdoc.display_id, pdoc.title, content, this.user._id, pdoc.tags);
const testdata = new AdmZip();
const config: LocalProblemConfig = {
+27 -14
View File
@@ -2,6 +2,7 @@
/* eslint-disable no-await-in-loop */
import mysql from 'mysql';
import 'hydrooj';
import { buildContent } from 'hydrooj/dist/utils';
const {
user, problem, builtin: { PRIV },
@@ -79,20 +80,32 @@ export async function run({
submit int 11 Y 总提交次数
solved int 11 Y 解答(未用)
*/
const [pdocs] = await query('SELECT * FROM `problem`');
for (const pdoc of pdocs) {
const pid = await problem.add(
'system', `P${pdoc.problem_id}`,
pdoc.title, pdoc.description + pdoc.input + pdoc.output + pdoc.sample_input + pdoc.sample_output + pdoc.hint,
1, pdoc.source.split(' '), undefined, undefined, pdoc.defunct === 'Y',
);
const [cdoc] = await query(`SELECT * FROM 'privilege' WHERE rightstr = 'p${pdoc.problem_id}'`);
await problem.edit('system', pid, {
nAccept: pdoc.accepted,
nSubmit: pdoc.submit,
config: { time: `${pdoc.time_limit}s`, memory: `${pdoc.memory_limit}m` },
owner: uidMap[cdoc[0].user_id],
});
const [[pcount]] = await query('SELECT count(*) FROM `problem`');
const step = 50;
const pageCount = Math.ceil(pcount / step);
for (let pageId = 0; pageId < pageCount; pageId++) {
const [pdocs] = await query(`SELECT * FROM \`problem\` LIMIT ${pageId * step}, ${step}`);
for (const pdoc of pdocs) {
const pid = await problem.add(
'system', `P${pdoc.problem_id}`,
pdoc.title, buildContent({
description: pdoc.description,
input: pdoc.input,
output: pdoc.output,
samples: [[pdoc.sample_input, pdoc.sample_output]],
hint: pdoc.hint,
source: pdoc.source,
}, 'html'),
1, pdoc.source.split(' '), undefined, undefined, pdoc.defunct === 'Y',
);
const [cdoc] = await query(`SELECT * FROM 'privilege' WHERE rightstr = 'p${pdoc.problem_id}'`);
await problem.edit('system', pid, {
nAccept: pdoc.accepted,
nSubmit: pdoc.submit,
config: { time: `${pdoc.time_limit}s`, memory: `${pdoc.memory_limit}m` },
owner: uidMap[cdoc[0].user_id],
});
}
}
return true;
}