From 88fc0606ee700a0749e6a2f791f1fc1d2547a65b Mon Sep 17 00:00:00 2001 From: undefined Date: Sun, 10 May 2020 17:46:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E5=86=85=E7=BD=AEUI=E5=B0=81=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 18 ++++++++-------- README.md | 27 +----------------------- build/index.js | 30 +++++++++++++++++++++++--- hydro/loader.js | 42 ++++++++++++++++++++++++++----------- hydro/service/server.js | 9 ++++++-- 5 files changed, 74 insertions(+), 52 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b491fed7a..b90197f1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,15 @@ jobs: name: Build runs-on: ubuntu-latest steps: + - run: | + cd ui + yarn + yarn build:production + cd .. + - uses: actions/upload-artifact@v1 + with: + name: .uibuild + path: .uibuild - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: @@ -19,15 +28,6 @@ jobs: with: name: hydro path: .build - - run: | - cd ui - yarn - yarn build:production - cd .. - - uses: actions/upload-artifact@v1 - with: - name: .uibuild - path: .uibuild - uses: elgohr/Publish-Docker-Github-Action@master with: name: hydrooj/hydro:alpine diff --git a/README.md b/README.md index 514531991..b79903715 100644 --- a/README.md +++ b/README.md @@ -14,32 +14,7 @@ Hydro 的界面基于 Vijos 二次开发。 #### 直接部署: 安装mongodb (省略) -编辑 `config.yaml` : - -```yaml -db: - host: 127.0.0.1 - port: 27017 - name: hydro - username: hydro - password: db.drop(); -listen: - host: 127.0.0.1 - port: 8888 -session: - domain: '*' -``` - -运行: - -```sh -yarn -cd ui -yarn -yarn build:production -cd .. -node hydro/development.js -``` +下载Github Actions自动编译的 development.js 直接运行即可。 ## 鸣谢 diff --git a/build/index.js b/build/index.js index 07fa99ad9..990ab9746 100644 --- a/build/index.js +++ b/build/index.js @@ -1,10 +1,23 @@ const fs = require('fs'); +const path = require('path'); const zlib = require('zlib'); const yaml = require('js-yaml'); const root = require('./root'); const template = require('./template'); const ignoreFailure = require('./ignoreFailure'); +function getFiles(folder) { + const res = []; + const files = fs.readdirSync(root(folder)); + for (const filename of files) { + res.push(filename); + if (fs.statSync(root(path.join(folder, filename))).isDirectory()) { + res.push(...(getFiles(path.join(folder, filename)).map((i) => path.join(filename, i)))); + } + } + return res; +} + async function build(type) { if (!['development', 'production'].includes(type)) throw new Error(`Unknown type: ${type}`); ignoreFailure(fs.mkdirSync, root('.build')); @@ -20,10 +33,21 @@ async function build(type) { 'partials/problem_default.md', 'bsod.html', ]; - const builtin = {}; - builtin.locale = lang; - builtin.template = template('templates', exclude); + const builtin = { + locale: lang, + template: template('templates', exclude), + file: {}, + }; + const files = getFiles('.uibuild'); + for (const f of files) { + if (fs.statSync(root(`.uibuild/${f}`)).isDirectory()) { + builtin.file[f] = null; + } else { + builtin.file[f] = fs.readFileSync(root(`.uibuild/${f}`)).toString('base64'); + } + } const data = zlib.gzipSync(Buffer.from(yaml.safeDump(builtin)), { level: 3 }); + fs.writeFileSync(root('.build/builtin.json'), JSON.stringify({ data: data.toString('base64') })); fs.writeFileSync(root('.build/module/builtin.hydro'), data); await require('./buildModule')(type); await require('./webpack')(type); diff --git a/hydro/loader.js b/hydro/loader.js index 97c192d98..a7a2832b2 100644 --- a/hydro/loader.js +++ b/hydro/loader.js @@ -20,6 +20,13 @@ function ensureDir(dir) { } const active = []; +try { + const f = require('../.build/builtin.json'); + const m = { ...yaml.safeLoad(zlib.gunzipSync(f.data)), id: 'builtin' }; + active.push(m); +} catch (e) { + /* Ignore */ +} async function preload() { const files = fs.readdirSync(root('.build/module')); @@ -28,24 +35,35 @@ async function preload() { try { const f = fs.readFileSync(root(`.build/module/${file}`)); const m = { ...yaml.safeLoad(zlib.gunzipSync(f)), id: file.split('.')[0] }; - if (m.os) { - if (!m.os.includes(os.platform())) throw new Error('Unsupported OS'); - } - if (m.file) { - m.files = {}; - ensureDir(path.resolve(os.tmpdir(), 'hydro', file)); - for (const n in m.file) { - const e = path.resolve(os.tmpdir(), 'hydro', file, n); - fs.writeFileSync(e, Buffer.from(m.file[n], 'base64'), { mode: 755 }); - m.files[n] = e; - } - } active.push(m); } catch (e) { console.error(`Module Load Fail: ${file}`); } } } + for (const i of active) { + try { + if (i.os) { + if (!i.os.includes(os.platform())) throw new Error('Unsupported OS'); + } + if (i.file) { + i.files = {}; + ensureDir(path.resolve(os.tmpdir(), 'hydro', i.id)); + for (const n in i.file) { + if (i.file[n] === null) { + ensureDir(path.resolve(os.tmpdir(), 'hydro', i.id, n)); + } else { + const e = path.resolve(os.tmpdir(), 'hydro', i.id, n); + fs.writeFileSync(e, Buffer.from(i.file[n], 'base64'), { mode: 755 }); + i.files[n] = e; + } + } + } + } catch (e) { + console.error(`Module Load Fail: ${i.id}`); + console.error(e); + } + } } async function handler() { diff --git a/hydro/service/server.js b/hydro/service/server.js index 3a6ec2571..5a1c7ba59 100644 --- a/hydro/service/server.js +++ b/hydro/service/server.js @@ -1,4 +1,5 @@ const path = require('path'); +const os = require('os'); const { ObjectID } = require('bson'); const Koa = require('koa'); const morgan = require('koa-morgan'); @@ -28,7 +29,7 @@ async function prepare() { const useHttps = await system.get('listen.https'); server = (useHttps ? https : http).createServer(app.callback()); app.keys = await system.get('session.keys'); - app.use(cache(path.join(process.cwd(), '.uibuild'), { + app.use(cache(path.join(os.tmpdir(), 'hydro', 'builtin'), { maxAge: 365 * 24 * 60 * 60, })); app.use(Body({ @@ -395,6 +396,10 @@ function Connection(prefix, RouteConnHandler) { sock.installHandlers(server); } +function Middleware(middleware) { + app.use(middleware); +} + async function start() { app.use(morgan(':method :url :status :res[content-length] - :response-time ms')); app.use(router.routes()).use(router.allowedMethods()); @@ -404,5 +409,5 @@ async function start() { } global.Hydro.service.server = module.exports = { - Handler, ConnectionHandler, Route, Connection, prepare, start, + Handler, ConnectionHandler, Route, Connection, Middleware, prepare, start, };