From cdce227dad0d2c6324fbc8747b85b6ae07d3f679 Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 23 May 2022 15:44:07 +0800 Subject: [PATCH] migrate: hustoj: update file upload --- packages/migrate/package.json | 2 +- packages/migrate/scripts/hustoj.ts | 35 ++++++++++++++++++------------ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/packages/migrate/package.json b/packages/migrate/package.json index c59af13cf..8979a3517 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/migrate", - "version": "0.1.1", + "version": "0.1.2", "main": "package.json", "repository": "git@github.com:hydro-dev/Hydro.git", "author": "undefined ", diff --git a/packages/migrate/scripts/hustoj.ts b/packages/migrate/scripts/hustoj.ts index 06c7c0260..d314e958a 100644 --- a/packages/migrate/scripts/hustoj.ts +++ b/packages/migrate/scripts/hustoj.ts @@ -59,11 +59,10 @@ const nameMap = { 'test.in': 'test0.in', 'test.out': 'test0.out', }; - export async function run({ host = 'localhost', port = 3306, name = 'jol', username, password, domainId, contestType = 'oi', - dataDir, rerun = false, + dataDir, rerun = true, randomMail = false, }, report: Function) { const src = mysql.createConnection({ host, @@ -104,7 +103,9 @@ export async function run({ const precheck = await user.getMulti({ unameLower: { $in: udocs.map((u) => u.user_id.toLowerCase()) } }).toArray(); if (precheck.length) throw new Error(`Conflict username: ${precheck.map((u) => u.unameLower).join(', ')}`); for (const udoc of udocs) { - const current = await user.getByEmail(domainId, udoc.email || `${udoc.user_id}@hustoj.local`); + if (randomMail) delete udoc.email; + let current = await user.getByEmail(domainId, udoc.email || `${udoc.user_id}@hustoj.local`); + if (!current) current = await user.getByUname(domainId, udoc.user_id); if (current) { report({ message: `duplicate user with email ${udoc.email}: ${current.uname},${udoc.user_id}` }); uidMap[udoc.user_id] = current._id; @@ -119,6 +120,7 @@ export async function run({ regat: udoc.reg_time, hash: udoc.password, salt: udoc.password, + school: udoc.school || '', hashType: 'hust', }); await domain.setUserInDomain(domainId, uid, { @@ -133,6 +135,7 @@ export async function run({ const [admins] = await query("SELECT * FROM `privilege` WHERE `rightstr` = 'administrator'"); for (const admin of admins) await domain.setUserRole(domainId, uidMap[admin.user_id], 'root'); const adminUids = admins.map((admin) => uidMap[admin.user_id]); + report({ message: 'user finished' }); /* problem_id int 11 N 题目编号,主键 @@ -198,6 +201,7 @@ export async function run({ } } } + report({ message: 'problem finished' }); /* contest_id int 11 N 竞赛id(主键) @@ -215,7 +219,7 @@ export async function run({ const [tdocs] = await query('SELECT * FROM `contest`'); for (const tdoc of tdocs) { const [pdocs] = await query(`SELECT * FROM \`contest_problem\` WHERE \`contest_id\` = ${tdoc.contest_id}`); - const pids = pdocs.map((i) => pidMap[i.problem_id]); + const pids = pdocs.map((i) => pidMap[i.problem_id]).filter((i) => i); const tid = await contest.add( domainId, tdoc.title, tdoc.description || 'Description', adminUids[0], contestType, tdoc.start_time, tdoc.end_time, pids, true, @@ -223,6 +227,7 @@ export async function run({ ); tidMap[tdoc.contest_id] = tid.toHexString(); } + report({ message: 'contest finished' }); /* solution 程序运行结果记录 @@ -251,16 +256,16 @@ export async function run({ const [rdocs] = await query(`SELECT * FROM \`solution\` LIMIT ${pageId * step}, ${step}`); for (const rdoc of rdocs) { const data: RecordDoc = { - status: statusMap[rdoc.result], + status: statusMap[rdoc.result] || 0, _id: Time.getObjectID(rdoc.in_date, false), - uid: uidMap[rdoc.user_id], + uid: uidMap[rdoc.user_id] || 0, code: "HustOJ didn't provide user code", - lang: langMap[rdoc.language], - pid: pidMap[rdoc.problem_id], + lang: langMap[rdoc.language] || '', + pid: pidMap[rdoc.problem_id] || 0, domainId, score: rdoc.pass_rate ? Math.ceil(rdoc.pass_rate * 100) : rdoc.result === 4 ? 100 : 0, - time: rdoc.time, - memory: rdoc.memory, + time: rdoc.time || 0, + memory: rdoc.memory || 0, judgeTexts: [], compilerTexts: [], testCases: [], @@ -279,9 +284,10 @@ export async function run({ await contest.attend(domainId, data.contest, uidMap[rdoc.user_id]).catch(noop); } await record.coll.insertOne(data); - await postJudge(data); + await postJudge(data).catch((err) => report({ message: err.message })); } } + report({ message: 'record finished' }); src.end(); @@ -290,13 +296,14 @@ export async function run({ const files = await fs.readdir(dataDir, { withFileTypes: true }); for (const file of files) { if (!file.isDirectory()) continue; - const datas = await fs.readdir(`${dataDir}/${file.name}`); + const datas = await fs.readdir(`${dataDir}/${file.name}`, { withFileTypes: true }); const pdoc = await problem.get(domainId, `P${file.name}`, undefined, true); if (!pdoc) continue; report({ message: `Syncing testdata for ${file.name}` }); for (const data of datas) { - const filename = nameMap[data] || data; - await problem.addTestdata(domainId, pdoc.docId, filename, `${dataDir}/${file.name}/${data}`); + if (data.isDirectory()) continue; + const filename = nameMap[data.name] || data; + await problem.addTestdata(domainId, pdoc.docId, filename, `${dataDir}/${file.name}/${data.name}`); } await problem.addTestdata(domainId, pdoc.docId, 'config.yaml', Buffer.from(pdoc.config as string)); }