From ca11d8077693ebfffdd96f85dd7e6ed2a7ab0f6a Mon Sep 17 00:00:00 2001 From: masnn Date: Thu, 11 Jun 2020 22:46:10 +0800 Subject: [PATCH] wiki --- README.md | 13 +- build/index.js | 3 + build/wiki.js | 27 +++ .../wiki/handler.js => hydro/handler/wiki.js | 10 +- hydro/loader.js | 15 +- module/migrate-vijos/script.js | 2 +- module/problem-import-syzoj/lib.js | 3 +- module/wiki/build.js | 24 --- module/wiki/hydro.json | 5 - module/wiki/locale/en.yaml | 3 - module/wiki/locale/zh_CN.yaml | 7 - module/wiki/raw/about/contents.json | 5 - module/wiki/raw/about/discuss.md | 23 --- module/wiki/raw/about/privacy.md | 23 --- module/wiki/raw/development/basic.md | 12 -- module/wiki/raw/development/contents.json | 11 - module/wiki/raw/development/file.md | 3 - module/wiki/raw/development/handler.md | 96 --------- module/wiki/raw/development/hydro.md | 11 - module/wiki/raw/development/lib.md | 3 - module/wiki/raw/development/locale.md | 3 - module/wiki/raw/development/module.md | 23 --- module/wiki/raw/development/readme.md | 3 - module/wiki/raw/development/service.md | 3 - module/wiki/raw/development/template.md | 31 --- module/wiki/raw/gettingstarted/contents.json | 4 - module/wiki/raw/gettingstarted/deploy.md | 13 -- .../wiki/raw/gettingstarted/introduction.md | 11 - module/wiki/raw/help/acratio.md | 3 - module/wiki/raw/help/ce.md | 19 -- module/wiki/raw/help/compiler.md | 14 -- module/wiki/raw/help/contents.json | 13 -- module/wiki/raw/help/contest.md | 8 - module/wiki/raw/help/dataformat.md | 3 - module/wiki/raw/help/io.md | 3 - module/wiki/raw/help/limits.md | 4 - module/wiki/raw/help/lostpass.md | 4 - module/wiki/raw/help/rp.md | 6 - module/wiki/raw/help/status.md | 17 -- module/wiki/raw/help/training.md | 3 - {module/wiki/template => templates}/wiki.html | 2 +- module/wiki/raw/about/tos.md => wiki/about.md | 52 ++++- wiki/deploy.md | 33 +++ wiki/development.md | 194 ++++++++++++++++++ wiki/help.md | 94 +++++++++ 45 files changed, 418 insertions(+), 444 deletions(-) create mode 100644 build/wiki.js rename module/wiki/handler.js => hydro/handler/wiki.js (61%) delete mode 100644 module/wiki/build.js delete mode 100644 module/wiki/hydro.json delete mode 100644 module/wiki/locale/en.yaml delete mode 100644 module/wiki/locale/zh_CN.yaml delete mode 100644 module/wiki/raw/about/contents.json delete mode 100644 module/wiki/raw/about/discuss.md delete mode 100644 module/wiki/raw/about/privacy.md delete mode 100644 module/wiki/raw/development/basic.md delete mode 100644 module/wiki/raw/development/contents.json delete mode 100644 module/wiki/raw/development/file.md delete mode 100644 module/wiki/raw/development/handler.md delete mode 100644 module/wiki/raw/development/hydro.md delete mode 100644 module/wiki/raw/development/lib.md delete mode 100644 module/wiki/raw/development/locale.md delete mode 100644 module/wiki/raw/development/module.md delete mode 100644 module/wiki/raw/development/readme.md delete mode 100644 module/wiki/raw/development/service.md delete mode 100644 module/wiki/raw/development/template.md delete mode 100644 module/wiki/raw/gettingstarted/contents.json delete mode 100644 module/wiki/raw/gettingstarted/deploy.md delete mode 100644 module/wiki/raw/gettingstarted/introduction.md delete mode 100644 module/wiki/raw/help/acratio.md delete mode 100644 module/wiki/raw/help/ce.md delete mode 100644 module/wiki/raw/help/compiler.md delete mode 100644 module/wiki/raw/help/contents.json delete mode 100644 module/wiki/raw/help/contest.md delete mode 100644 module/wiki/raw/help/dataformat.md delete mode 100644 module/wiki/raw/help/io.md delete mode 100644 module/wiki/raw/help/limits.md delete mode 100644 module/wiki/raw/help/lostpass.md delete mode 100644 module/wiki/raw/help/rp.md delete mode 100644 module/wiki/raw/help/status.md delete mode 100644 module/wiki/raw/help/training.md rename {module/wiki/template => templates}/wiki.html (91%) rename module/wiki/raw/about/tos.md => wiki/about.md (62%) create mode 100644 wiki/deploy.md create mode 100644 wiki/development.md create mode 100644 wiki/help.md diff --git a/README.md b/README.md index e6e619f56..98d92505b 100644 --- a/README.md +++ b/README.md @@ -3,19 +3,10 @@ Hydro是一个高效的信息学在线测评系统。 特点: 易于部署,轻量,功能强大。 +[中文文档](wiki/deploy.md) + Hydro 的界面基于 Vijos 二次开发。 -## 使用方式 - -#### 使用 `docker-compose`(推荐) - -// TODO(WIP) - -#### 直接部署: - -安装mongodb (省略) -下载Github Actions自动编译的 app.js 直接运行即可。 - ## 鸣谢 排名不分先后,按照链接字典序 diff --git a/build/index.js b/build/index.js index e82a93900..23d37ce90 100644 --- a/build/index.js +++ b/build/index.js @@ -6,6 +6,7 @@ const yaml = require('js-yaml'); const { root, ignoreFailure, rmdir } = require('./utils'); const template = require('./template'); const hack = require('./hack'); +const wikiBuild = require('./wiki'); const fsp = fs.promises; @@ -42,6 +43,8 @@ async function build(type) { template: template('templates'), public: {}, }; + const wiki = wikiBuild(); + builtin.lib = `Object.assign(global.Hydro.wiki,${JSON.stringify(wiki)})`; const files = getFiles('.uibuild'); for (const f of files) { if (fs.statSync(root(`.uibuild/${f}`)).isDirectory()) { diff --git a/build/wiki.js b/build/wiki.js new file mode 100644 index 000000000..b709210b7 --- /dev/null +++ b/build/wiki.js @@ -0,0 +1,27 @@ +const fs = require('fs'); +const { root } = require('./utils'); + +module.exports = () => { + const pages = fs.readdirSync(root('wiki')); + const res = {}; + for (const page of pages) { + const c = fs.readFileSync(root(`wiki/${page}`)).toString().split('\n'); + const pagename = page.split('.')[0]; + res[pagename] = []; + let content = null; + for (let i = 0; i < c.length; i++) { + const line = c[i]; + if (line.startsWith('# ')) { + if (content) res[pagename].push(content); + content = {}; + const t = line.split('# ')[1].split('|'); + [content.title, content.id] = t.map((q) => q.trim()); + content.content = ''; + } else { + content.content = `${content.content}${line}\n`; + } + res[pagename].push(content); + } + } + return res; +}; diff --git a/module/wiki/handler.js b/hydro/handler/wiki.js similarity index 61% rename from module/wiki/handler.js rename to hydro/handler/wiki.js index 4648c59de..2c859fb77 100644 --- a/module/wiki/handler.js +++ b/hydro/handler/wiki.js @@ -1,12 +1,10 @@ -const { Route, Handler } = global.Hydro.service.server; -const { NotFoundError } = global.Hydro.error; -// eslint-disable-next-line import/no-unresolved -const pages = require('./__build.json'); +const { Route, Handler } = require('../service/server'); +const { NotFoundError } = require('../error'); class WikiHandler extends Handler { async get({ name }) { - if (!pages[name]) throw new NotFoundError(name); - const contents = pages[name]; + if (!global.Hydro.wiki[name]) throw new NotFoundError(name); + const contents = global.Hydro.wiki[name]; const path = [ ['Hydro', '/'], ['wiki', '/wiki'], diff --git a/hydro/loader.js b/hydro/loader.js index 0746d8e63..9555e742b 100644 --- a/hydro/loader.js +++ b/hydro/loader.js @@ -166,7 +166,7 @@ const builtinModel = [ const builtinHandler = [ 'home', 'problem', 'record', 'judge', 'user', 'contest', 'training', 'discussion', 'manage', 'import', - 'misc', 'homework', 'domain', + 'misc', 'homework', 'domain', 'wiki', ]; const builtinScript = [ @@ -297,23 +297,25 @@ async function terminate() { } async function load() { + global.nodeModules = { + bson: require('bson'), + 'js-yaml': require('js-yaml'), + mongodb: require('mongodb'), + }; global.Hydro = { handler: {}, service: {}, model: {}, script: {}, lib: {}, - nodeModules: { - bson: require('bson'), - 'js-yaml': require('js-yaml'), - mongodb: require('mongodb'), - }, + wiki: {}, template: {}, ui: {}, }; global.onDestory = []; Error.stackTraceLimit = 50; process.on('unhandledRejection', (e) => console.error(e)); + process.on('SIGINT', terminate); if (cluster.isMaster) { console.log(`Master ${process.pid} Starting`); process.stdin.setEncoding('utf8'); @@ -326,7 +328,6 @@ async function load() { console.warn(e); } }); - process.on('SIGINT', terminate); await loadAsMaster(); cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} exit: ${code} ${signal}`); diff --git a/module/migrate-vijos/script.js b/module/migrate-vijos/script.js index c9fe00001..0a7bcf338 100644 --- a/module/migrate-vijos/script.js +++ b/module/migrate-vijos/script.js @@ -1,5 +1,5 @@ /* eslint-disable no-await-in-loop */ -const { mongodb } = global.Hydro.nodeModules; +const { mongodb } = global.nodeModules; const dst = global.Hydro.service.db; const { file, problem, discussion } = global.Hydro.model; diff --git a/module/problem-import-syzoj/lib.js b/module/problem-import-syzoj/lib.js index 17cf6b949..c9bc700e3 100644 --- a/module/problem-import-syzoj/lib.js +++ b/module/problem-import-syzoj/lib.js @@ -1,7 +1,6 @@ const assert = require('assert'); -const { download } = global.Hydro.lib; -const { axios } = global.Hydro.lib; +const { download, axios } = global.Hydro.lib; const { ValidationError, RemoteOnlineJudgeError } = global.Hydro.error; async function syzoj(url, handler) { diff --git a/module/wiki/build.js b/module/wiki/build.js deleted file mode 100644 index 93817cee0..000000000 --- a/module/wiki/build.js +++ /dev/null @@ -1,24 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -const root = (name) => path.resolve(__dirname, name); - -exports.prebuild = async () => { - const pages = fs.readdirSync(root('raw')); - const res = {}; - for (const page of pages) { - // eslint-disable-next-line import/no-dynamic-require - const contents = require(root(`raw/${page}/contents.json`)); - res[page] = []; - for (const id of contents) { - const content = {}; - const c = fs.readFileSync(root(`raw/${page}/${id}.md`)).toString().split('\n'); - // eslint-disable-next-line prefer-destructuring - content.title = c[0].split('# ')[1]; - content.id = id; - content.content = c.splice(1, c.length - 1).join('\n'); - res[page].push(content); - } - } - fs.writeFileSync(root('__build.json'), JSON.stringify(res)); -}; diff --git a/module/wiki/hydro.json b/module/wiki/hydro.json deleted file mode 100644 index f8685fbbe..000000000 --- a/module/wiki/hydro.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": "wiki", - "version": "1.0.0", - "description": "Basic wiki module." -} \ No newline at end of file diff --git a/module/wiki/locale/en.yaml b/module/wiki/locale/en.yaml deleted file mode 100644 index 67204791c..000000000 --- a/module/wiki/locale/en.yaml +++ /dev/null @@ -1,3 +0,0 @@ -wiki_about: About -wiki_help: Help -wiki_development: Development diff --git a/module/wiki/locale/zh_CN.yaml b/module/wiki/locale/zh_CN.yaml deleted file mode 100644 index a3560d232..000000000 --- a/module/wiki/locale/zh_CN.yaml +++ /dev/null @@ -1,7 +0,0 @@ -wiki_about: 关于 -wiki_help: 帮助 -wiki_development: 开发文档 -Basic: 基础 -Module: 模块 -Introduction: 介绍 -Deployment: 部署 diff --git a/module/wiki/raw/about/contents.json b/module/wiki/raw/about/contents.json deleted file mode 100644 index 8d99104f4..000000000 --- a/module/wiki/raw/about/contents.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - "privacy", - "tos", - "discuss" -] \ No newline at end of file diff --git a/module/wiki/raw/about/discuss.md b/module/wiki/raw/about/discuss.md deleted file mode 100644 index 950b8ac83..000000000 --- a/module/wiki/raw/about/discuss.md +++ /dev/null @@ -1,23 +0,0 @@ -# Discussion: Terms Of Service - -为了更好地发挥讨论、题解的积极作用,使广大用户学到知识、获得利益,进一步规范讨论和题解功能的使用,我们制定了《讨论和题解版规》(简称《版规》)。您在发布(或回复)讨论和题解时,即代表您已充分阅读、理解、接受并保证遵守此版规。 -您在发布(或回复)讨论和题解或使用相关功能时须遵守以下规定: - -- 第一次使用编辑器前,要先阅读编辑器快速入门和 Markdown 详细帮助。 -- 不得将讨论、题解混淆。例如,不得将题解发布到讨论中,题解应发布在相应题目的题解区中。 -- 发布(或回复)的所有内容不得包含会干扰 Hydro 用户界面呈现的相关内容。 -- 发布(或回复)的所有内容不得包含恶意代码和指向恶意网站或 Hydro 明确禁止的网站的链接。 -- 特别地,发布(或回复)含有代码的内容时,应当将代码高亮。一个简单的方法是选中代码块然后按下 Tab 键。 -- 发布的题解禁止只包含无详细注释的代码。题解中难以理解的代码应当有尽可能详细的注释。 -- 打分、投票和评价应当客观。例如,对于题解的打分、投票和评价应当关注于题解本身的质量。 -- 我们欢迎原创作品,并会对其作者给予数量不等的 RP 奖励。 - -您在发布、回复讨论和题解时还须遵守法律法规,不得发布违法违规内容,包括但不限于: - -- 危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容; -- 侵害他人知识产权、商业秘密等合法权利的内容; -- 恶意虚构事实、隐瞒真相以误导、欺骗他人的内容; -- 广告信息及垃圾信息; -- 其他法律法规禁止的内容。 - -对于违反《版规》的,我们将进行警告并删除相关内容、临时冻结用户、永久冻结用户等操作。 \ No newline at end of file diff --git a/module/wiki/raw/about/privacy.md b/module/wiki/raw/about/privacy.md deleted file mode 100644 index dfc47e071..000000000 --- a/module/wiki/raw/about/privacy.md +++ /dev/null @@ -1,23 +0,0 @@ -# Privacy - -#### 1. 收集的信息 - -我们收集信息是为了向所有用户提供更好的服务。我们有两种信息收集方式: -s -- 您向我们提供信息。在您注册 Hydro 帐户时,我们会要求您提供个人信息,例如您的电子邮件地址、QQ号码等。 -- 我们在您使用服务的过程中获取信息。我们会收集关于您使用的服务以及使用方式的信息,例如您在何时使用了我们服务。 - -#### 2. 如何使用收集到的信息 - -我们利用从所有服务中收集的信息来提供、维护、保护和改进这些服务,同时开发新的服务并保护 Hydro 以及用户的隐私。 -当我们要将信息用于本隐私权政策未载明的其它用途时,则会事先征求您的同意。 - -#### 3. 访问和更新您的个人信息 - -无论您在何时使用我们的服务,我们都力求让您能够访问自己的个人信息。如果这些信息有误,我们会努力通过各种方式让您快速更新信息或删除信息。在更新您的个人信息时,我们可能会要求您先验证自己的身份,然后再处理您的请求。 -我们力求对服务进行完善的维护,以保护信息免遭意外或恶意的破坏。因此,当您从我们的服务中删除信息后,我们可能不会立即从在用的服务器中删除这些信息的残留副本,也可能不会从备份系统中删除相应的信息。 - -#### 4. 信息安全 - -我们为您提供SSL加密访问服务,您可以通过SSL(https)使用我们的服务,这可以很大程度上保障在传输过程中您信息的安全。 -对于敏感数据(如您的密码),我们承诺在存储时进行高强度不可逆加密。Hydro 的管理员、维护人员等均不能够访问到敏感数据的明文,所有操作均无人工介入。 \ No newline at end of file diff --git a/module/wiki/raw/development/basic.md b/module/wiki/raw/development/basic.md deleted file mode 100644 index d51ff674d..000000000 --- a/module/wiki/raw/development/basic.md +++ /dev/null @@ -1,12 +0,0 @@ -# Basic - -Hydro 后端使用 NodeJS 编写,前端使用 JQuery + React。 -代码风格遵循 airbnb 标准(详见 .eslintrc.js)。 - -由于模块中不能使用 require() 引入 Hydro 的文件,因此需要从 global.Hydro 中取出需要的模块。 -例: - -```js -const { db } = global.Hydro.service; -const { problem } = global.Hydro.model; -``` diff --git a/module/wiki/raw/development/contents.json b/module/wiki/raw/development/contents.json deleted file mode 100644 index 439a1cae8..000000000 --- a/module/wiki/raw/development/contents.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - "basic", - "module", - "hydro", - "handler", - "service", - "lib", - "file", - "locale", - "template" -] \ No newline at end of file diff --git a/module/wiki/raw/development/file.md b/module/wiki/raw/development/file.md deleted file mode 100644 index 1679674e1..000000000 --- a/module/wiki/raw/development/file.md +++ /dev/null @@ -1,3 +0,0 @@ -# File - -file 文件夹下的所有文件将被自动解压到 `$TMPDIR/hydro/模块ID/路径` 的位置(权限755,通常用于启动子进程)。 diff --git a/module/wiki/raw/development/handler.md b/module/wiki/raw/development/handler.md deleted file mode 100644 index 90c87af8d..000000000 --- a/module/wiki/raw/development/handler.md +++ /dev/null @@ -1,96 +0,0 @@ -# Handler - -通常用于提供页面路由。 - -例:注册新路由: - -```js -const { Handler, Route } = global.Hydro.service.server; -const { user } = global.Hydro.model; -const { PERM_LOGGEDIN } = global.Hydro.permission; - -class CustomHandler extends Handler { - async prepare() { - this.checkPassword(PERM_LOGGEDIN); - } - - async get({ username, password }) { - const udoc = await user.getByUname(username); - udoc.checkPassword(password); - this.response.body = { udoc }; - } - - async post() { - // 当提交表单时会执行该函数 - } - - async postConfirm() { - // 当提交表单并存在 operation 值为 confirm 时执行。 - } -} - -async function apply() { - Route('/route/:username', module.exports.CustomHandler); -} - -global.Hydro.handler.custom = module.exports = { CustomHandler, apply }; -``` - -在路由中定义所有的函数应均为异步函数,支持的函数如下: - -_prepare, prepare, get, post, post[Operation], cleanup, _cleanup - -具体流程如下: - -先执行 _prepare(args) (如果存在) -args 为传入的参数集合(包括 QueryString, Body, Path)中的全部参数,并对以下字段进行了校验: - -| 名称 | 类型 | -| :------: | :-----------: | -| content | string | -| title | string | -| uid | number(int) | -| password | string | -| mail | string(mail) | -| uname | string | -| page | number(int) | -| duration | number(float) | -| role | string | -| roles | string[] | -| pids | string | -| tid | bson.ObjectID | -| rid | bson.ObjectID | -| did | bson.ObjectID | -| drid | bson.ObjectID | -| drrid | bson.ObjectID | -| psid | bson.ObjectID | -| psrid | bson.ObjectID | -| docId | bson.ObjectID | -| mongoId | bson.ObjectID | - -再执行 prepare(args) (如果存在) -检查请求类型: - -``` -为 GET ? - -> 执行 get(args) -为 POST ? - -> 执行 post(args) - -> 含有 operation 字段? - -> 执行 post[Operation] -``` - -执行 cleanup() -执行 _cleanup() - -如果在 this.response.template 指定模板则渲染,否则直接返回 this.response.body 中的内容。 - -* 在表单提交时的 operation 字段使用下划线,函数名使用驼峰命名。 - -如 `` 对应 `postConfirmDelete` 函数。 - -应当提供 `apply` 函数,并与定义的 Handler 一同挂载到 `global.Hydro.handler[模块名]` 位置。 -`apply` 函数将在初始化阶段被调用。 - -
请在 apply 函数中从 module.exports 引用,因为它们可能需要被其他模块修改。
- diff --git a/module/wiki/raw/development/hydro.md b/module/wiki/raw/development/hydro.md deleted file mode 100644 index 6872e2904..000000000 --- a/module/wiki/raw/development/hydro.md +++ /dev/null @@ -1,11 +0,0 @@ -# Hydro.json - -Hydro.json 是模块的声明文件,格式如下。 - -```json -{ - "id": "模块ID", - "version": "模块版本", - "description": "模块描述" -} -``` diff --git a/module/wiki/raw/development/lib.md b/module/wiki/raw/development/lib.md deleted file mode 100644 index 4cdd0ff62..000000000 --- a/module/wiki/raw/development/lib.md +++ /dev/null @@ -1,3 +0,0 @@ -# Lib - -库文件。通常用于提供一些功能(废话)。 diff --git a/module/wiki/raw/development/locale.md b/module/wiki/raw/development/locale.md deleted file mode 100644 index e97db3123..000000000 --- a/module/wiki/raw/development/locale.md +++ /dev/null @@ -1,3 +0,0 @@ -# Locale - -用于提供多国翻译。格式与 Hydro 的 locale 文件夹格式相同。 diff --git a/module/wiki/raw/development/module.md b/module/wiki/raw/development/module.md deleted file mode 100644 index 80f32b702..000000000 --- a/module/wiki/raw/development/module.md +++ /dev/null @@ -1,23 +0,0 @@ -# Module - -## 文件架构 - -Hydro 的模块由以下几个部分组成: - -service: 服务 -script: 脚本 -handler: 访问路由 -lib: 库 -model: 数据库模型 -file: 额外文件 -locale: 多国化 -template: UI 模板 -README.md: 介绍 -hydro.json: 声明文件(必须) - -## 模块编译 - -使用 `hydro-build` 进行编译。 -安装:`yarn add hydro-build -D` -编译:`hydro-build` -如果命运的齿轮没有出差错,您应该可以找到生成的.hydro文件了。 diff --git a/module/wiki/raw/development/readme.md b/module/wiki/raw/development/readme.md deleted file mode 100644 index 0dac92d71..000000000 --- a/module/wiki/raw/development/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# README.md - -项目的说明文件。 diff --git a/module/wiki/raw/development/service.md b/module/wiki/raw/development/service.md deleted file mode 100644 index 4774c18e1..000000000 --- a/module/wiki/raw/development/service.md +++ /dev/null @@ -1,3 +0,0 @@ -# Service - -通常用于提供与其他程序对接的接口。(如内置的 MongoDB 等) diff --git a/module/wiki/raw/development/template.md b/module/wiki/raw/development/template.md deleted file mode 100644 index b75f6f517..000000000 --- a/module/wiki/raw/development/template.md +++ /dev/null @@ -1,31 +0,0 @@ -# Template - -页面模板,使用 nunjucks 语法。 -传入了 _ 翻译函数与 model 等。 - -```html -{% set page_name = "page_name" %} -{% extends "layout/basic.html" %} -{% block content %} -
-
-
-
-
-

{{ _('Oops!') }}

-

{{ _(error.message).format(error.params) }}

-

{{ _('Technical Information') }}:

-

{{ _('Type') }}: {{ error.code }}

-

{{ _('Arguments') }}: -

    - {% for param in error.params %} -
  1. {{ param }}
  2. - {% endfor %} -
-

-
-
-{% endblock %} -``` - -
请不要覆盖已有模板。
\ No newline at end of file diff --git a/module/wiki/raw/gettingstarted/contents.json b/module/wiki/raw/gettingstarted/contents.json deleted file mode 100644 index 9c9af8add..000000000 --- a/module/wiki/raw/gettingstarted/contents.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "introduction", - "deploy" -] \ No newline at end of file diff --git a/module/wiki/raw/gettingstarted/deploy.md b/module/wiki/raw/gettingstarted/deploy.md deleted file mode 100644 index bbcfd41c0..000000000 --- a/module/wiki/raw/gettingstarted/deploy.md +++ /dev/null @@ -1,13 +0,0 @@ -# Deployment - -Hydro 依赖于 MongoDB 与 NodeJS,您应该先安装它们。 -之后您可以下载最新版的 Hydro 程序,放置于一个空文件夹,使用如下命令启动 Hydro: - -```sh -node hydro.js -``` - -Hydro 会自行初始化并监听 8888 端口。请用浏览器访问并进行相应配置。 -数据库配置完成后,会自动创建 Root 用户。(账号 `root` ,密码 `rootroot`),请及时修改。 - -之后的进阶配置可在 管理 面板进行。 diff --git a/module/wiki/raw/gettingstarted/introduction.md b/module/wiki/raw/gettingstarted/introduction.md deleted file mode 100644 index 3331a8aae..000000000 --- a/module/wiki/raw/gettingstarted/introduction.md +++ /dev/null @@ -1,11 +0,0 @@ -# Introduction - -为什么使用 Hydro ? - -- 安全:使用 cgroup 进行隔离,杜绝卡评测; -- 高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率; -- 扩展:Hydro 支持安装额外模块进行扩展; -- 强大:配合 Judger 模块(或 HydroJudger 独立评测机),可支持 spj,交互题,提交答案题,文件IO等多种特性; -- 简便:提供了多种迁移脚本,可从 Vijos 等快速升级至 Hydro; -- 自定:所有权限节点均可自由设置; -- 社区:Hydro 正在持续维护中; diff --git a/module/wiki/raw/help/acratio.md b/module/wiki/raw/help/acratio.md deleted file mode 100644 index 54c20d8aa..000000000 --- a/module/wiki/raw/help/acratio.md +++ /dev/null @@ -1,3 +0,0 @@ -# Accepted Ratio - -通过率的影响极其恶劣,Hydro 不提供也不承认通过率。 \ No newline at end of file diff --git a/module/wiki/raw/help/ce.md b/module/wiki/raw/help/ce.md deleted file mode 100644 index b9a51bb6b..000000000 --- a/module/wiki/raw/help/ce.md +++ /dev/null @@ -1,19 +0,0 @@ -# Compile Error - -可能有以下情况: - -- 递交时选错了编程语言 -- Java 的主类名没有使用 "Main" -- 对于 C/C++:见下 -- 一般性的编译错误 - -
- 对 C/C++ 选手的特别提醒: - -
diff --git a/module/wiki/raw/help/compiler.md b/module/wiki/raw/help/compiler.md deleted file mode 100644 index 6d4bf1d7d..000000000 --- a/module/wiki/raw/help/compiler.md +++ /dev/null @@ -1,14 +0,0 @@ -# Compilers' Version and Parameters - -Hydro使用 [HydroJudger](https://github.com/hydro-dev/HydroJudger) 进行评测,以docker镜像的形式安装至评测机。 -所使用的编译器均为创建镜像时 [debian testing](https://wiki.debian.org/DebianTesting) 分支的最新版。编译参数如下: - -- Free Pascal `fpc -O2 -o/out/foo /in/foo.pas` -- C `gcc -O2 -Wall -std=c99 -o /out/foo /in/foo.c -lm` -- C++ `g++ -O2 -Wall -std=c++11 -o /out/foo /in/foo.cc -lm` -- Java `javac Main.java` -- Python `python foo.py` -- Python 3 `python3 foo.py` -- PHP `php foo.php` -- Rust `rustc -O -o /out/foo /in/foo.rs` -- Haskell `ghc -O -outputdir /tmp -o /out/foo /in/foo.hs` diff --git a/module/wiki/raw/help/contents.json b/module/wiki/raw/help/contents.json deleted file mode 100644 index 4330fa883..000000000 --- a/module/wiki/raw/help/contents.json +++ /dev/null @@ -1,13 +0,0 @@ -[ - "compiler", - "limits", - "io", - "status", - "ce", - "training", - "contest", - "acratio", - "rp", - "dataformat", - "lostpass" -] \ No newline at end of file diff --git a/module/wiki/raw/help/contest.md b/module/wiki/raw/help/contest.md deleted file mode 100644 index 3a7fef3cd..000000000 --- a/module/wiki/raw/help/contest.md +++ /dev/null @@ -1,8 +0,0 @@ -# Contest - -按照赛制不同,有不同的递交、排名规则。 -OI 赛制所有题目均以最后一次递交为准,特别地,请避免编译错误。 -OI 赛制排名规则为:总分高的排在前面,总分相等则排名相同。 -ACM/ICPC 赛制所有题目递交后立即评测,以是否通过为准。 -ACM/ICPC 赛制排名规则为:通过题目数多的排在前面,通过题目数相同的做题耗时(含罚时)少的排在前。 -时间与空间限制以题目说明为准,默认限制参见[Limitations](#Limits)。 \ No newline at end of file diff --git a/module/wiki/raw/help/dataformat.md b/module/wiki/raw/help/dataformat.md deleted file mode 100644 index d60b42513..000000000 --- a/module/wiki/raw/help/dataformat.md +++ /dev/null @@ -1,3 +0,0 @@ -# Dataset Format - -TODO \ No newline at end of file diff --git a/module/wiki/raw/help/io.md b/module/wiki/raw/help/io.md deleted file mode 100644 index 6617847ec..000000000 --- a/module/wiki/raw/help/io.md +++ /dev/null @@ -1,3 +0,0 @@ -# IO - -若无特殊说明,Hydro 使用标准输入输出(控制台输入输出,屏幕输入输出,STD I/O)。 \ No newline at end of file diff --git a/module/wiki/raw/help/limits.md b/module/wiki/raw/help/limits.md deleted file mode 100644 index 3dd2a0e12..000000000 --- a/module/wiki/raw/help/limits.md +++ /dev/null @@ -1,4 +0,0 @@ -# Limitations - -Hydro 评测机使用进程的CPU时间计算时间消耗,时间的限定为题目中评测点所指定的时间。 -Hydro 评测机使用进程虚拟内存与物理内存总和计算内存空间消耗。内存空间默认限定为256MiB,题目中特别指明的,限定为题目中评测点所指定的内存空间。 \ No newline at end of file diff --git a/module/wiki/raw/help/lostpass.md b/module/wiki/raw/help/lostpass.md deleted file mode 100644 index 548f5ab57..000000000 --- a/module/wiki/raw/help/lostpass.md +++ /dev/null @@ -1,4 +0,0 @@ -# Forgot Password and/or Username - -如果您无法登录,请仔细想想,是不是用户名记错了。比如,自己原本想要注册的用户名已经被注册,所以使用了一个带有前和/或后缀的用户名。 -如果您确信您的账号被盗或者忘记了账号和/或密码,请及时[{{ _('Reset Password or Find Username') }}](/lostpass)。 \ No newline at end of file diff --git a/module/wiki/raw/help/rp.md b/module/wiki/raw/help/rp.md deleted file mode 100644 index a958b81ab..000000000 --- a/module/wiki/raw/help/rp.md +++ /dev/null @@ -1,6 +0,0 @@ -# RP - -Hydro RP 分为固定 RP 与浮动 RP ,固定 RP 可由活动、比赛等的奖励获得,浮动 RP 由一般性通过题目获得。 -浮动 RP 是一个动态的数值,每个用户在每道题上获得的 RP 都不一样,并且未来也不固定(即浮动之意)。 - -
每道题的浮动 RP 由该题通过总人数与该用户通过此题的名次计算得来。
\ No newline at end of file diff --git a/module/wiki/raw/help/status.md b/module/wiki/raw/help/status.md deleted file mode 100644 index d2e521d07..000000000 --- a/module/wiki/raw/help/status.md +++ /dev/null @@ -1,17 +0,0 @@ -# Judge Status - -- Waiting 评测:评测请求正在等待被评测机抓取 -- Fetched 评测:评测请求已被评测机抓取,正在准备开始评测 -- Compiling 评测:正在编译中 -- Judging 评测:编译成功,正在评测中 -- Accepted 通过:程序输出完全正确 -- Wrong Answer 不通过:程序输出与标准答案不一致(不包括行末空格以及文件末空行) -- Time Exceeded 不通过:程序运行时间超过了题目限制 -- Memory Exceeded 不通过:程序运行内存空间超过了题目限制 -- Runtime Error 不通过:程序运行时错误(如数组越界、被零除、运算溢出、栈溢出、无效指针等) -- Compile Error 不通过:编译失败 -- System Error 错误:系统错误(如果您遇到此问题,请及时在讨论区进行反馈) -- Canceled 其他:评测被取消 -- Unknown Error 其他:未知错误 - -
有“成绩取消”字样则说明管理员手动标记此记录为取消,可能违反了服务条款,比如代码被发现与其他用户的代码十分相似。
\ No newline at end of file diff --git a/module/wiki/raw/help/training.md b/module/wiki/raw/help/training.md deleted file mode 100644 index 8ef3a8ceb..000000000 --- a/module/wiki/raw/help/training.md +++ /dev/null @@ -1,3 +0,0 @@ -# Training - -我们精心挑选了一些题目组成了训练计划。单击导航栏的“训练”即可进入! \ No newline at end of file diff --git a/module/wiki/template/wiki.html b/templates/wiki.html similarity index 91% rename from module/wiki/template/wiki.html rename to templates/wiki.html index 1de4910d7..f584b3d62 100644 --- a/module/wiki/template/wiki.html +++ b/templates/wiki.html @@ -19,7 +19,7 @@ diff --git a/module/wiki/raw/about/tos.md b/wiki/about.md similarity index 62% rename from module/wiki/raw/about/tos.md rename to wiki/about.md index 590cb21b9..45ab4d1c3 100644 --- a/module/wiki/raw/about/tos.md +++ b/wiki/about.md @@ -1,4 +1,28 @@ -# Terms of Service +# Privacy | privacy + +#### 1. 收集的信息 + +我们收集信息是为了向所有用户提供更好的服务。我们有两种信息收集方式: +s +- 您向我们提供信息。在您注册 Hydro 帐户时,我们会要求您提供个人信息,例如您的电子邮件地址、QQ号码等。 +- 我们在您使用服务的过程中获取信息。我们会收集关于您使用的服务以及使用方式的信息,例如您在何时使用了我们服务。 + +#### 2. 如何使用收集到的信息 + +我们利用从所有服务中收集的信息来提供、维护、保护和改进这些服务,同时开发新的服务并保护 Hydro 以及用户的隐私。 +当我们要将信息用于本隐私权政策未载明的其它用途时,则会事先征求您的同意。 + +#### 3. 访问和更新您的个人信息 + +无论您在何时使用我们的服务,我们都力求让您能够访问自己的个人信息。如果这些信息有误,我们会努力通过各种方式让您快速更新信息或删除信息。在更新您的个人信息时,我们可能会要求您先验证自己的身份,然后再处理您的请求。 +我们力求对服务进行完善的维护,以保护信息免遭意外或恶意的破坏。因此,当您从我们的服务中删除信息后,我们可能不会立即从在用的服务器中删除这些信息的残留副本,也可能不会从备份系统中删除相应的信息。 + +#### 4. 信息安全 + +我们为您提供SSL加密访问服务,您可以通过SSL(https)使用我们的服务,这可以很大程度上保障在传输过程中您信息的安全。 +对于敏感数据(如您的密码),我们承诺在存储时进行高强度不可逆加密。Hydro 的管理员、维护人员等均不能够访问到敏感数据的明文,所有操作均无人工介入。 + +# Terms of Service | tos #### 0. 欢迎使用 Hydro @@ -57,4 +81,28 @@ #### 9. 其他 -如果您对这个协议或我们的服务有意见或建议,可与我们联系,我们会给予您必要的帮助。 \ No newline at end of file +如果您对这个协议或我们的服务有意见或建议,可与我们联系,我们会给予您必要的帮助。 + +# Discussion: Terms Of Service | discussion + +为了更好地发挥讨论、题解的积极作用,使广大用户学到知识、获得利益,进一步规范讨论和题解功能的使用,我们制定了《讨论和题解版规》(简称《版规》)。您在发布(或回复)讨论和题解时,即代表您已充分阅读、理解、接受并保证遵守此版规。 +您在发布(或回复)讨论和题解或使用相关功能时须遵守以下规定: + +- 第一次使用编辑器前,要先阅读编辑器快速入门和 Markdown 详细帮助。 +- 不得将讨论、题解混淆。例如,不得将题解发布到讨论中,题解应发布在相应题目的题解区中。 +- 发布(或回复)的所有内容不得包含会干扰 Hydro 用户界面呈现的相关内容。 +- 发布(或回复)的所有内容不得包含恶意代码和指向恶意网站或 Hydro 明确禁止的网站的链接。 +- 特别地,发布(或回复)含有代码的内容时,应当将代码高亮。一个简单的方法是选中代码块然后按下 Tab 键。 +- 发布的题解禁止只包含无详细注释的代码。题解中难以理解的代码应当有尽可能详细的注释。 +- 打分、投票和评价应当客观。例如,对于题解的打分、投票和评价应当关注于题解本身的质量。 +- 我们欢迎原创作品,并会对其作者给予数量不等的 RP 奖励。 + +您在发布、回复讨论和题解时还须遵守法律法规,不得发布违法违规内容,包括但不限于: + +- 危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容; +- 侵害他人知识产权、商业秘密等合法权利的内容; +- 恶意虚构事实、隐瞒真相以误导、欺骗他人的内容; +- 广告信息及垃圾信息; +- 其他法律法规禁止的内容。 + +对于违反《版规》的,我们将进行警告并删除相关内容、临时冻结用户、永久冻结用户等操作。 \ No newline at end of file diff --git a/wiki/deploy.md b/wiki/deploy.md new file mode 100644 index 000000000..3627301be --- /dev/null +++ b/wiki/deploy.md @@ -0,0 +1,33 @@ +# Introduction | introduction + +为什么使用 Hydro ? + +- 安全:使用 cgroup 进行隔离,杜绝卡评测; +- 高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率; +- 扩展:Hydro 支持安装额外模块进行扩展; +- 强大:配合 Judger 模块(或 HydroJudger 独立评测机),可支持 spj,交互题,提交答案题,文件IO等多种特性; +- 简便:提供了多种迁移脚本,可从 Vijos 等快速升级至 Hydro; +- 自定:所有权限节点均可自由设置; +- 社区:Hydro 正在持续维护中; + +# Deployment | deployment + +Hydro 依赖于 MongoDB 与 NodeJS,您应该先安装它们。 + +提示:推荐使用 [nvm](https://nvm.sh/) 安装 NodeJS。 + +clone 本项目到一个空文件夹,并进行编译: + +```sh +git clone https://github.com/hydro-dev/Hydro.git +cd Hydro +yarn build:all +node hydro/loader.js +``` + +注意:单个Hydro实例需要约100MB的运行内存,但在载入时可能需要较多内存(取决于安装的模块数量与大小) + +Hydro 会自行初始化并监听 8888 端口。请用浏览器访问并进行相应配置。 +数据库配置完成后,会自动创建 Root 用户。(账号 `root` ,密码 `rootroot`),请及时修改。 + +之后的进阶配置可在 管理 面板进行。 diff --git a/wiki/development.md b/wiki/development.md new file mode 100644 index 000000000..5b16dfa80 --- /dev/null +++ b/wiki/development.md @@ -0,0 +1,194 @@ +# Basic | basic + +Hydro 后端使用 NodeJS 编写,前端使用 JQuery + React。 +代码风格遵循 airbnb 标准(详见 .eslintrc.js)。 + +由于模块中不能使用 require() 引入 Hydro 的文件,因此需要从 global.Hydro 中取出需要的模块。 +例: + +```js +const { db } = global.Hydro.service; +const { problem } = global.Hydro.model; +``` + +# Module | module + +## 文件架构 + +Hydro 的模块由以下几个部分组成: + +service: 服务 +script: 脚本 +handler: 访问路由 +lib: 库 +model: 数据库模型 +file: 额外文件 +locale: 多国化 +template: UI 模板 +README.md: 介绍 +hydro.json: 声明文件(必须) + +## 模块编译 + +使用 `hydro-build` 进行编译。 +安装:`yarn add hydro-build -D` +编译:`hydro-build` +如果命运的齿轮没有出差错,您应该可以找到生成的.hydro文件了。 + +# Hydro.json | hydro + +Hydro.json 是模块的声明文件,格式如下。 + +```json +{ + "id": "模块ID", + "version": "模块版本", + "description": "模块描述" +} +``` + +# Handler | handler + +通常用于提供页面路由。 + +例:注册新路由: + +```js +const { Handler, Route } = global.Hydro.service.server; +const { user } = global.Hydro.model; +const { PERM_LOGGEDIN } = global.Hydro.permission; + +class CustomHandler extends Handler { + async prepare() { + this.checkPassword(PERM_LOGGEDIN); + } + + async get({ username, password }) { + const udoc = await user.getByUname(username); + udoc.checkPassword(password); + this.response.body = { udoc }; + } + + async post() { + // 当提交表单时会执行该函数 + } + + async postConfirm() { + // 当提交表单并存在 operation 值为 confirm 时执行。 + } +} + +async function apply() { + Route('/route/:username', CustomHandler); +} + +global.Hydro.handler.handlerName = module.exports = apply; +``` + +在路由中定义所有的函数应均为异步函数,支持的函数如下: + +_prepare, prepare, get, post, post[Operation], cleanup, _cleanup + +具体流程如下: + +先执行 _prepare(args) (如果存在) +args 为传入的参数集合(包括 QueryString, Body, Path)中的全部参数,并对以下字段进行了校验: + +| 名称 | 类型 | +| :------: | :-----------: | +| content | string | +| title | string | +| uid | number(int) | +| password | string | +| mail | string(mail) | +| uname | string | +| page | number(int) | +| duration | number(float) | +| role | string | +| roles | string[] | +| pids | string | +| tid | bson.ObjectID | +| rid | bson.ObjectID | +| did | bson.ObjectID | +| drid | bson.ObjectID | +| drrid | bson.ObjectID | +| psid | bson.ObjectID | +| psrid | bson.ObjectID | +| docId | bson.ObjectID | +| mongoId | bson.ObjectID | + +再执行 prepare(args) (如果存在) +检查请求类型: + +``` +为 GET ? + -> 执行 get(args) +为 POST ? + -> 执行 post(args) + -> 含有 operation 字段? + -> 执行 post[Operation] +``` + +执行 cleanup() +执行 _cleanup() + +如果在 this.response.template 指定模板则渲染,否则直接返回 this.response.body 中的内容。 + +* 在表单提交时的 operation 字段使用下划线,函数名使用驼峰命名。 + +如 `` 对应 `postConfirmDelete` 函数。 + +应当提供 `apply` 函数,并与定义的 Handler 一同挂载到 `global.Hydro.handler[模块名]` 位置。 +`apply` 函数将在初始化阶段被调用。 + +# Service | service + +通常用于提供与其他程序对接的接口或启动其他外部程序。(如内置的 MongoDB / 外置的沙箱模块等) + +# Lib | lib + +库文件。通常用于提供一些功能(废话)。 + +# File | file + +file 文件夹下的所有文件将被自动解压到 `$TMPDIR/hydro/模块ID/路径` 的位置(权限755,通常用于启动子进程)。 + +# Locale | locale + +用于提供多国翻译。格式与 Hydro 的 locale 文件夹格式相同。 + +# Template | template + +页面模板,使用 [nunjucks](https://mozilla.github.io/nunjucks/cn/templating.html) 语法。 +传入了 _ 翻译函数与 model 等。 + +```html +{% set page_name = "page_name" %} +{% extends "layout/basic.html" %} +{% block content %} +
+
+
+
+
+

{{ _('Oops!') }}

+

{{ _(error.message).format(error.params) }}

+

{{ _('Technical Information') }}:

+

{{ _('Type') }}: {{ error.code }}

+

{{ _('Arguments') }}: +

    + {% for param in error.params %} +
  1. {{ param }}
  2. + {% endfor %} +
+

+
+
+{% endblock %} +``` + +
请不要覆盖已有模板。
+ +# README.md | readme + +项目的说明文件。 diff --git a/wiki/help.md b/wiki/help.md new file mode 100644 index 000000000..1ae2cdd9d --- /dev/null +++ b/wiki/help.md @@ -0,0 +1,94 @@ +# Compilers' Version and Parameters + +Hydro使用 [HydroJudger](https://github.com/hydro-dev/HydroJudger) 进行评测,以docker镜像的形式安装至评测机。 +所使用的编译器均为创建镜像时 [debian testing](https://wiki.debian.org/DebianTesting) 分支的最新版。编译参数如下: + +- Free Pascal `fpc -O2 -o/out/foo /in/foo.pas` +- C `gcc -O2 -Wall -std=c99 -o /out/foo /in/foo.c -lm` +- C++ `g++ -O2 -Wall -std=c++11 -o /out/foo /in/foo.cc -lm` +- Java `javac Main.java` +- Python `python foo.py` +- Python 3 `python3 foo.py` +- PHP `php foo.php` +- Rust `rustc -O -o /out/foo /in/foo.rs` +- Haskell `ghc -O -outputdir /tmp -o /out/foo /in/foo.hs` + +# Limitations + +Hydro 评测机使用进程的CPU时间计算时间消耗,时间的限定为题目中评测点所指定的时间。 +Hydro 评测机使用进程虚拟内存与物理内存总和计算内存空间消耗。内存空间默认限定为256MiB,题目中特别指明的,限定为题目中评测点所指定的内存空间。 + +# IO + +若无特殊说明,Hydro 使用标准输入输出(控制台输入输出,屏幕输入输出,STD I/O)。 + +# Judge Status + +- Waiting 评测:评测请求正在等待被评测机抓取 +- Fetched 评测:评测请求已被评测机抓取,正在准备开始评测 +- Compiling 评测:正在编译中 +- Judging 评测:编译成功,正在评测中 +- Accepted 通过:程序输出完全正确 +- Wrong Answer 不通过:程序输出与标准答案不一致(不包括行末空格以及文件末空行) +- Time Exceeded 不通过:程序运行时间超过了题目限制 +- Memory Exceeded 不通过:程序运行内存空间超过了题目限制 +- Runtime Error 不通过:程序运行时错误(如数组越界、被零除、运算溢出、栈溢出、无效指针等) +- Compile Error 不通过:编译失败 +- System Error 错误:系统错误(如果您遇到此问题,请及时在讨论区进行反馈) +- Canceled 其他:评测被取消 +- Unknown Error 其他:未知错误 + +
有“成绩取消”字样则说明管理员手动标记此记录为取消,可能违反了服务条款,比如代码被发现与其他用户的代码十分相似。
+ +# Compile Error + +可能有以下情况: + +- 递交时选错了编程语言 +- Java 的主类名没有使用 "Main" +- 对于 C/C++:见下 +- 一般性的编译错误 + +
+ 对 C/C++ 选手的特别提醒: + +
+ +# Training + +我们精心挑选了一些题目组成了训练计划。单击导航栏的“训练”即可进入! + +# Contest + +按照赛制不同,有不同的递交、排名规则。 +OI 赛制所有题目均以最后一次递交为准,特别地,请避免编译错误。 +OI 赛制排名规则为:总分高的排在前面,总分相等则排名相同。 +ACM/ICPC 赛制所有题目递交后立即评测,以是否通过为准。 +ACM/ICPC 赛制排名规则为:通过题目数多的排在前面,通过题目数相同的做题耗时(含罚时)少的排在前。 +时间与空间限制以题目说明为准,默认限制参见[Limitations](#Limits)。 + +# Accepted Ratio + +通过率的影响极其恶劣,Hydro 不提供也不承认通过率。 + +# RP + +Hydro RP 分为固定 RP 与浮动 RP ,固定 RP 可由活动、比赛等的奖励获得,浮动 RP 由一般性通过题目获得。 +浮动 RP 是一个动态的数值,每个用户在每道题上获得的 RP 都不一样,并且未来也不固定(即浮动之意)。 + +
每道题的浮动 RP 由该题通过总人数与该用户通过此题的名次计算得来。
+ +# Dataset Format + +TODO + +# Forgot Password and/or Username + +如果您无法登录,请仔细想想,是不是用户名记错了。比如,自己原本想要注册的用户名已经被注册,所以使用了一个带有前和/或后缀的用户名。 +如果您确信您的账号被盗或者忘记了账号和/或密码,请及时[{{ _('Reset Password or Find Username') }}](/lostpass)。