diff --git a/build/buildModule.js b/build/buildModule.js index 4a0e26c51..f44afb481 100644 --- a/build/buildModule.js +++ b/build/buildModule.js @@ -6,17 +6,11 @@ const zlib = require('zlib'); const webpack = require('webpack'); const yaml = require('js-yaml'); const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); -const root = require('./root'); +const { root, exist } = require('./utils'); const template = require('./template'); -const exist = (name) => { - try { - fs.statSync(root(name)); - } catch (e) { - return false; - } - return true; -}; +const prepare = ['model', 'lib', 'handler', 'service', 'script']; + const build = async (type) => { const modules = fs.readdirSync(root('module')); const failed = []; @@ -43,7 +37,6 @@ const build = async (type) => { const builder = require(root(`module/${i}/build.js`)); if (builder.prebuild) await builder.prebuild(); } - const prepare = ['model', 'lib', 'handler', 'service']; for (const j of prepare) { if (exist(`module/${i}/${j}.js`)) { const file = fs.readFileSync(root(`module/${i}/${j}.js`)); @@ -75,7 +68,6 @@ const build = async (type) => { if (!i.startsWith('.') && !failed.includes(i)) { try { const current = {}; - const prepare = ['model', 'lib', 'handler', 'service']; for (const j of prepare) { if (exist(`module/${i}/${j}.js`)) { const file = fs.readFileSync(root(`module/${i}/${j}.js`)); diff --git a/build/index.js b/build/index.js index 990ab9746..61f11c517 100644 --- a/build/index.js +++ b/build/index.js @@ -2,9 +2,8 @@ const fs = require('fs'); const path = require('path'); const zlib = require('zlib'); const yaml = require('js-yaml'); -const root = require('./root'); +const { root, ignoreFailure, rmdir } = require('./utils'); const template = require('./template'); -const ignoreFailure = require('./ignoreFailure'); function getFiles(folder) { const res = []; @@ -51,6 +50,11 @@ async function build(type) { fs.writeFileSync(root('.build/module/builtin.hydro'), data); await require('./buildModule')(type); await require('./webpack')(type); + const t = fs.readdirSync(root('.build/module')); + for (const f of t) { + if (fs.statSync(root(`.build/module/${f}`)).isDirectory()) rmdir(root(`.build/module/${f}`)); + } + fs.unlinkSync(root('.build/builtin.json')); } module.exports = build; diff --git a/build/root.js b/build/root.js deleted file mode 100644 index 924d194a5..000000000 --- a/build/root.js +++ /dev/null @@ -1,6 +0,0 @@ -const path = require('path'); - -function root(name) { - return path.resolve(__dirname, '..', name); -} -module.exports = root; diff --git a/build/template.js b/build/template.js index fe4dfcd87..4a0f2424e 100644 --- a/build/template.js +++ b/build/template.js @@ -1,5 +1,5 @@ const fs = require('fs'); -const root = require('./root'); +const { root } = require('./utils'); function getFiles(folder) { const files = []; diff --git a/build/utils.js b/build/utils.js new file mode 100644 index 000000000..9549f1793 --- /dev/null +++ b/build/utils.js @@ -0,0 +1,28 @@ +const fs = require('fs'); +const path = require('path'); + +exports.root = (name) => path.resolve(__dirname, '..', name); +exports.exist = (name) => { + try { + fs.statSync(exports.root(name)); + } catch (e) { + return false; + } + return true; +}; +exports.rmdir = function rmdir(p, recursive = true) { + if (!fs.existsSync(p)) return; + if (recursive) { + fs.readdirSync(p).forEach((file) => { + const curPath = `${p}/${file}`; + if (fs.statSync(curPath).isDirectory()) rmdir(curPath); + else fs.unlinkSync(curPath); + }); + } + fs.rmdirSync(p); +}; +exports.ignoreFailure = function ignoreFailure(func, ...params) { + try { + func(...params); + } catch (e) { } // eslint-disable-line no-empty +}; diff --git a/build/webpack.js b/build/webpack.js index 3f16590e9..684f1b1c7 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -2,7 +2,7 @@ const fs = require('fs'); const webpack = require('webpack'); const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); -const root = require('./root'); +const { root } = require('./utils'); const build = async (type) => { function hackNodeModuleFormidable() { diff --git a/hydro/loader.js b/hydro/loader.js index a7a2832b2..25f8c0353 100644 --- a/hydro/loader.js +++ b/hydro/loader.js @@ -21,6 +21,7 @@ function ensureDir(dir) { const active = []; try { + // eslint-disable-next-line import/no-unresolved const f = require('../.build/builtin.json'); const m = { ...yaml.safeLoad(zlib.gunzipSync(f.data)), id: 'builtin' }; active.push(m); @@ -201,7 +202,11 @@ async function load() { handler: {}, service: {}, model: {}, + script: {}, lib: {}, + nodeModules: { + mongodb: require('mongodb'), + }, template: {}, ui: {}, }; diff --git a/module/migrate-vijos/handler.js b/module/migrate-vijos/handler.js new file mode 100644 index 000000000..8239cdcca --- /dev/null +++ b/module/migrate-vijos/handler.js @@ -0,0 +1,41 @@ +const { + Route, Connection, Handler, ConnectionHandler, +} = global.Hydro.service.server; +const { PERM_MANAGE } = global.Hydro.permission; +const migrate = global.Hydro.script.migrateVijos; + +class MigrateVijosHandler extends Handler { + async prepare() { + this.checkPerm(PERM_MANAGE); + } + + async get() { + const path = [ + ['Hydro', '/'], + ['migrate_vijos', null], + ]; + this.response.body = { path }; + this.response.template = 'migrate_vijos.html'; + } +} + +class MigrateVijosConnectionHandler extends ConnectionHandler { + async prepare() { + this.checkPerm(PERM_MANAGE); + } + + async message(msg) { + if (msg.key === 'start') { + migrate(msg, (data) => { this.send(data); }); + } + } +} + +async function apply() { + Route('/migrate/vijos', module.exports.MigrateVijosHandler); + Connection('/migrate/vijos-conn', module.exports.MigrateVijosConnectionHandler); +} + +global.Hydro.handler.pastebin = module.exports = { + MigrateVijosHandler, MigrateVijosConnectionHandler, apply, +}; diff --git a/module/migrate-vijos/hydro.json b/module/migrate-vijos/hydro.json new file mode 100644 index 000000000..55a0cebdb --- /dev/null +++ b/module/migrate-vijos/hydro.json @@ -0,0 +1,5 @@ +{ + "name": "migrate-vijos", + "version": "0.0.1", + "description": "Migrate From Vijos" +} \ No newline at end of file diff --git a/module/migrate-vijos/script.js b/module/migrate-vijos/script.js new file mode 100644 index 000000000..732ff5b10 --- /dev/null +++ b/module/migrate-vijos/script.js @@ -0,0 +1,87 @@ +/* eslint-disable no-await-in-loop */ +const Mongo = global.Hydro.nodeModules.mongodb; +const { ObjectID } = global.Hydro.nodeModules.bson; +const dst = global.Hydro.service.db; + +function parseSolution(doc) { + return { + _id: doc._id, + title: doc.title, + content: doc.content, + vote: doc.vote, + }; +} + +async function problem(src, report) { + const count = await src.collection('document').find({ doc_type: 10 }).count(); + report({ progress: 1, message: `Found ${count} problems.` }); + for (let i = 0; i <= Math.floor(count / 50); i++) { + const docs = await src.collection('document').find({ doc_type: 10 }) + .skip(i * 50).limit(50) + .toArray(); + const problems = []; + for (const doc of docs) { + problems.push({ + _id: doc._id, + pid: doc.doc_id || new ObjectID(), + title: doc.title, + content: doc.content, + owner: doc.owner_uid, + data: doc.data, + category: doc.category, + tag: doc.tag, + nSubmit: doc.num_submit, + nAccept: doc.num_accept, + }); + } + await dst.collection('problem').insertMany(problems); + } +} + +async function contest(src, report) { + const RULES = ['', 'oi', 'acm']; + const count = await src.collection('document').find({ doc_type: 30 }).count(); + report({ progress: 1, message: `Found ${count} contests.` }); + for (let i = 0; i <= Math.floor(count / 50); i++) { + const docs = await src.collection('document').find({ doc_type: 30 }) + .skip(i * 50).limit(50) + .toArray(); + const contests = []; + for (const doc of docs) { + contests.push({ + _id: doc._id, + title: doc.title, + content: doc.content, + owner: doc.owner_uid, + rule: RULES[doc.rule], + beginAt: doc.begin_at, + endAt: doc.end_at, + pids: doc.pids, + attend: doc.attend, + }); + } + await dst.collection('contests').insertMany(contests); + } +} + +async function migrateVijos({ + host, port, name, username, password, +}, report = () => { }) { + let mongourl = 'mongodb://'; + if (username) mongourl += `${username}:${password}@`; + mongourl += `${host}:${port}/${name}`; + const Database = await Mongo.MongoClient.connect(mongourl, { + useNewUrlParser: true, useUnifiedTopology: true, + }); + const src = Database.db(name); + report({ progress: 0, message: 'Database connected.' }); + dst.collection('system').insertOne({ + _id: 'user', + value: (await src.collection('system').findOne({ _id: 'user_counter' })).value, + }); + report({ progress: 1, message: 'Collection:system done.' }); + await problem(src, report); + await contest(src, report); +} + +global.Hydro.script.migrateVijos = module.exports = migrateVijos; diff --git a/ui/build/main.js b/ui/build/main.js index d89d0b55a..6c40bba34 100644 --- a/ui/build/main.js +++ b/ui/build/main.js @@ -5,9 +5,14 @@ import runGulp from './runGulp'; import runWebpack from './runWebpack'; async function main() { + const dir = process.cwd(); + process.chdir(root()); await runGulp(argv); - runWebpack(argv); + await runWebpack(argv); + process.chdir(dir); } -process.chdir(root()); -main(); +module.exports = main; + +if (!module.parent) main(); +