You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Hydro/packages/migrate-hustoj/script.ts

117 lines
4.4 KiB
TypeScript

/* eslint-disable no-tabs */
/* eslint-disable no-await-in-loop */
import mysql from 'mysql';
import 'hydrooj';
import { buildContent } from 'hydrooj/src/lib/content';
const { user, problem, system } = global.Hydro.model;
export async function run({
host = 'localhost', port = 27017, name = 'vijos4', username, password,
}, report: Function) {
const src = mysql.createConnection({
host,
port,
user: username,
password,
database: name,
});
await new Promise((resolve) => src.connect(resolve));
const query = (q: string | mysql.Query): Promise<[values: any[], fields: mysql.FieldInfo[]]> => new Promise((res, rej) => {
src.query(q, (err, val, fields) => {
if (err) rej(err);
res([val, fields]);
});
});
report({ message: 'Connected to database' });
/*
user_id varchar 20 N id
email varchar 100 Y E-mail
submit int 11 Y
solved int 11 Y
defunct char 1 N Y/N
ip varchar 20 N ip
accesstime datetime Y
volume int 11 N
language int 11 N
password varchar 32 Y
reg_time datetime Y
nick varchar 100 N
school varchar 100 N
*/
const uidMap: Record<string, number> = {};
const [udocs] = await query('SELECT * FROM `users`');
for (const udoc of udocs) {
const uid = await user.create(udoc.email, udoc.nick, '', null, udoc.ip, udoc.defunct === 'Y' ? 0 : system.get('default.priv'));
uidMap[udoc.uid] = uid;
await user.setById(uid, {
nSubmit: udoc.submit,
nSolve: udoc.solved,
loginat: udoc.accesstime,
regat: udoc.reg_time,
hash: udoc.password,
salt: udoc.password,
hashType: 'hust',
});
}
const [admins] = await query("SELECT * FROM 'privilege' WHERE rightstr = 'administrator'");
for (const admin of admins) await user.setSuperAdmin(uidMap[admin.user_id]);
/*
problem_id int 11 N
title varchar 200 N
description text Y
inupt text Y
output text Y
sample_input text Y
sample_output text Y
spj char 1 N
hint text Y
source varchar 100 Y
in_date datetime Y
time_limit int 11 N
memory_limit int 11 N (MByte)
defunct char 1 N Y/N
accepted int 11 Y ac
submit int 11 Y
solved int 11 Y
*/
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(' '), 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,
4 years ago
config: `time: ${pdoc.time_limit}s\nmemory: ${pdoc.memory_limit}m`,
owner: uidMap[cdoc[0].user_id],
});
}
}
return true;
}
export const description = 'migrate from hustoj';
export const validate = {
host: 'string', port: 'number', name: 'string', username: 'string', password: 'string',
};
global.Hydro.script.migrateHustoj = { run, description, validate };