mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
wiki
This commit is contained in:
1 parent
8c20c34d8b
commit
ca11d80776
45 files changed
+418
-444
No files matched your search
@@ -3,19 +3,10 @@
|
|||||||
Hydro是一个高效的信息学在线测评系统。
|
Hydro是一个高效的信息学在线测评系统。
|
||||||
特点: 易于部署,轻量,功能强大。
|
特点: 易于部署,轻量,功能强大。
|
||||||
|
|
||||||
|
[中文文档](wiki/deploy.md)
|
||||||
|
|
||||||
Hydro 的界面基于 Vijos 二次开发。
|
Hydro 的界面基于 Vijos 二次开发。
|
||||||
|
|
||||||
## 使用方式
|
|
||||||
|
|
||||||
#### 使用 `docker-compose`(推荐)
|
|
||||||
|
|
||||||
// TODO(WIP)
|
|
||||||
|
|
||||||
#### 直接部署:
|
|
||||||
|
|
||||||
安装mongodb (省略)
|
|
||||||
下载Github Actions自动编译的 app.js 直接运行即可。
|
|
||||||
|
|
||||||
## 鸣谢
|
## 鸣谢
|
||||||
|
|
||||||
排名不分先后,按照链接字典序
|
排名不分先后,按照链接字典序
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const yaml = require('js-yaml');
|
|||||||
const { root, ignoreFailure, rmdir } = require('./utils');
|
const { root, ignoreFailure, rmdir } = require('./utils');
|
||||||
const template = require('./template');
|
const template = require('./template');
|
||||||
const hack = require('./hack');
|
const hack = require('./hack');
|
||||||
|
const wikiBuild = require('./wiki');
|
||||||
|
|
||||||
const fsp = fs.promises;
|
const fsp = fs.promises;
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ async function build(type) {
|
|||||||
template: template('templates'),
|
template: template('templates'),
|
||||||
public: {},
|
public: {},
|
||||||
};
|
};
|
||||||
|
const wiki = wikiBuild();
|
||||||
|
builtin.lib = `Object.assign(global.Hydro.wiki,${JSON.stringify(wiki)})`;
|
||||||
const files = getFiles('.uibuild');
|
const files = getFiles('.uibuild');
|
||||||
for (const f of files) {
|
for (const f of files) {
|
||||||
if (fs.statSync(root(`.uibuild/${f}`)).isDirectory()) {
|
if (fs.statSync(root(`.uibuild/${f}`)).isDirectory()) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
const { Route, Handler } = global.Hydro.service.server;
|
const { Route, Handler } = require('../service/server');
|
||||||
const { NotFoundError } = global.Hydro.error;
|
const { NotFoundError } = require('../error');
|
||||||
// eslint-disable-next-line import/no-unresolved
|
|
||||||
const pages = require('./__build.json');
|
|
||||||
|
|
||||||
class WikiHandler extends Handler {
|
class WikiHandler extends Handler {
|
||||||
async get({ name }) {
|
async get({ name }) {
|
||||||
if (!pages[name]) throw new NotFoundError(name);
|
if (!global.Hydro.wiki[name]) throw new NotFoundError(name);
|
||||||
const contents = pages[name];
|
const contents = global.Hydro.wiki[name];
|
||||||
const path = [
|
const path = [
|
||||||
['Hydro', '/'],
|
['Hydro', '/'],
|
||||||
['wiki', '/wiki'],
|
['wiki', '/wiki'],
|
||||||
+8
-7
@@ -166,7 +166,7 @@ const builtinModel = [
|
|||||||
const builtinHandler = [
|
const builtinHandler = [
|
||||||
'home', 'problem', 'record', 'judge', 'user',
|
'home', 'problem', 'record', 'judge', 'user',
|
||||||
'contest', 'training', 'discussion', 'manage', 'import',
|
'contest', 'training', 'discussion', 'manage', 'import',
|
||||||
'misc', 'homework', 'domain',
|
'misc', 'homework', 'domain', 'wiki',
|
||||||
];
|
];
|
||||||
|
|
||||||
const builtinScript = [
|
const builtinScript = [
|
||||||
@@ -297,23 +297,25 @@ async function terminate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function load() {
|
async function load() {
|
||||||
|
global.nodeModules = {
|
||||||
|
bson: require('bson'),
|
||||||
|
'js-yaml': require('js-yaml'),
|
||||||
|
mongodb: require('mongodb'),
|
||||||
|
};
|
||||||
global.Hydro = {
|
global.Hydro = {
|
||||||
handler: {},
|
handler: {},
|
||||||
service: {},
|
service: {},
|
||||||
model: {},
|
model: {},
|
||||||
script: {},
|
script: {},
|
||||||
lib: {},
|
lib: {},
|
||||||
nodeModules: {
|
wiki: {},
|
||||||
bson: require('bson'),
|
|
||||||
'js-yaml': require('js-yaml'),
|
|
||||||
mongodb: require('mongodb'),
|
|
||||||
},
|
|
||||||
template: {},
|
template: {},
|
||||||
ui: {},
|
ui: {},
|
||||||
};
|
};
|
||||||
global.onDestory = [];
|
global.onDestory = [];
|
||||||
Error.stackTraceLimit = 50;
|
Error.stackTraceLimit = 50;
|
||||||
process.on('unhandledRejection', (e) => console.error(e));
|
process.on('unhandledRejection', (e) => console.error(e));
|
||||||
|
process.on('SIGINT', terminate);
|
||||||
if (cluster.isMaster) {
|
if (cluster.isMaster) {
|
||||||
console.log(`Master ${process.pid} Starting`);
|
console.log(`Master ${process.pid} Starting`);
|
||||||
process.stdin.setEncoding('utf8');
|
process.stdin.setEncoding('utf8');
|
||||||
@@ -326,7 +328,6 @@ async function load() {
|
|||||||
console.warn(e);
|
console.warn(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
process.on('SIGINT', terminate);
|
|
||||||
await loadAsMaster();
|
await loadAsMaster();
|
||||||
cluster.on('exit', (worker, code, signal) => {
|
cluster.on('exit', (worker, code, signal) => {
|
||||||
console.log(`Worker ${worker.process.pid} exit: ${code} ${signal}`);
|
console.log(`Worker ${worker.process.pid} exit: ${code} ${signal}`);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
const { mongodb } = global.Hydro.nodeModules;
|
const { mongodb } = global.nodeModules;
|
||||||
const dst = global.Hydro.service.db;
|
const dst = global.Hydro.service.db;
|
||||||
const { file, problem, discussion } = global.Hydro.model;
|
const { file, problem, discussion } = global.Hydro.model;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
const { download } = global.Hydro.lib;
|
const { download, axios } = global.Hydro.lib;
|
||||||
const { axios } = global.Hydro.lib;
|
|
||||||
const { ValidationError, RemoteOnlineJudgeError } = global.Hydro.error;
|
const { ValidationError, RemoteOnlineJudgeError } = global.Hydro.error;
|
||||||
|
|
||||||
async function syzoj(url, handler) {
|
async function syzoj(url, handler) {
|
||||||
|
|||||||
@@ -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));
|
|
||||||
};
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "wiki",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "Basic wiki module."
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
wiki_about: About
|
|
||||||
wiki_help: Help
|
|
||||||
wiki_development: Development
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
wiki_about: 关于
|
|
||||||
wiki_help: 帮助
|
|
||||||
wiki_development: 开发文档
|
|
||||||
Basic: 基础
|
|
||||||
Module: 模块
|
|
||||||
Introduction: 介绍
|
|
||||||
Deployment: 部署
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
[
|
|
||||||
"privacy",
|
|
||||||
"tos",
|
|
||||||
"discuss"
|
|
||||||
]
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# Discussion: Terms Of Service
|
|
||||||
|
|
||||||
为了更好地发挥讨论、题解的积极作用,使广大用户学到知识、获得利益,进一步规范讨论和题解功能的使用,我们制定了《讨论和题解版规》(简称《版规》)。您在发布(或回复)讨论和题解时,即代表您已充分阅读、理解、接受并保证遵守此版规。
|
|
||||||
您在发布(或回复)讨论和题解或使用相关功能时须遵守以下规定:
|
|
||||||
|
|
||||||
- 第一次使用编辑器前,要先阅读编辑器快速入门和 Markdown 详细帮助。
|
|
||||||
- 不得将讨论、题解混淆。例如,不得将题解发布到讨论中,题解应发布在相应题目的题解区中。
|
|
||||||
- 发布(或回复)的所有内容不得包含会干扰 Hydro 用户界面呈现的相关内容。
|
|
||||||
- 发布(或回复)的所有内容不得包含恶意代码和指向恶意网站或 Hydro 明确禁止的网站的链接。
|
|
||||||
- 特别地,发布(或回复)含有代码的内容时,应当将代码高亮。一个简单的方法是选中代码块然后按下 Tab 键。
|
|
||||||
- 发布的题解禁止只包含无详细注释的代码。题解中难以理解的代码应当有尽可能详细的注释。
|
|
||||||
- 打分、投票和评价应当客观。例如,对于题解的打分、投票和评价应当关注于题解本身的质量。
|
|
||||||
- 我们欢迎原创作品,并会对其作者给予数量不等的 RP 奖励。
|
|
||||||
|
|
||||||
您在发布、回复讨论和题解时还须遵守法律法规,不得发布违法违规内容,包括但不限于:
|
|
||||||
|
|
||||||
- 危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
|
|
||||||
- 侵害他人知识产权、商业秘密等合法权利的内容;
|
|
||||||
- 恶意虚构事实、隐瞒真相以误导、欺骗他人的内容;
|
|
||||||
- 广告信息及垃圾信息;
|
|
||||||
- 其他法律法规禁止的内容。
|
|
||||||
|
|
||||||
对于违反《版规》的,我们将进行警告并删除相关内容、临时冻结用户、永久冻结用户等操作。
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# Privacy
|
|
||||||
|
|
||||||
#### 1. 收集的信息
|
|
||||||
|
|
||||||
我们收集信息是为了向所有用户提供更好的服务。我们有两种信息收集方式:
|
|
||||||
s
|
|
||||||
- 您向我们提供信息。在您注册 Hydro 帐户时,我们会要求您提供个人信息,例如您的电子邮件地址、QQ号码等。
|
|
||||||
- 我们在您使用服务的过程中获取信息。我们会收集关于您使用的服务以及使用方式的信息,例如您在何时使用了我们服务。
|
|
||||||
|
|
||||||
#### 2. 如何使用收集到的信息
|
|
||||||
|
|
||||||
我们利用从所有服务中收集的信息来提供、维护、保护和改进这些服务,同时开发新的服务并保护 Hydro 以及用户的隐私。
|
|
||||||
当我们要将信息用于本隐私权政策未载明的其它用途时,则会事先征求您的同意。
|
|
||||||
|
|
||||||
#### 3. 访问和更新您的个人信息
|
|
||||||
|
|
||||||
无论您在何时使用我们的服务,我们都力求让您能够访问自己的个人信息。如果这些信息有误,我们会努力通过各种方式让您快速更新信息或删除信息。在更新您的个人信息时,我们可能会要求您先验证自己的身份,然后再处理您的请求。
|
|
||||||
我们力求对服务进行完善的维护,以保护信息免遭意外或恶意的破坏。因此,当您从我们的服务中删除信息后,我们可能不会立即从在用的服务器中删除这些信息的残留副本,也可能不会从备份系统中删除相应的信息。
|
|
||||||
|
|
||||||
#### 4. 信息安全
|
|
||||||
|
|
||||||
我们为您提供SSL加密访问服务,您可以通过SSL(https)使用我们的服务,这可以很大程度上保障在传输过程中您信息的安全。
|
|
||||||
对于敏感数据(如您的密码),我们承诺在存储时进行高强度不可逆加密。Hydro 的管理员、维护人员等均不能够访问到敏感数据的明文,所有操作均无人工介入。
|
|
||||||
@@ -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;
|
|
||||||
```
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
[
|
|
||||||
"basic",
|
|
||||||
"module",
|
|
||||||
"hydro",
|
|
||||||
"handler",
|
|
||||||
"service",
|
|
||||||
"lib",
|
|
||||||
"file",
|
|
||||||
"locale",
|
|
||||||
"template"
|
|
||||||
]
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# File
|
|
||||||
|
|
||||||
file 文件夹下的所有文件将被自动解压到 `$TMPDIR/hydro/模块ID/路径` 的位置(权限755,通常用于启动子进程)。
|
|
||||||
@@ -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 字段使用下划线,函数名使用驼峰命名。
|
|
||||||
|
|
||||||
如 `<input type="hidden" name="operation" value="confirm_delete">` 对应 `postConfirmDelete` 函数。
|
|
||||||
|
|
||||||
应当提供 `apply` 函数,并与定义的 Handler 一同挂载到 `global.Hydro.handler[模块名]` 位置。
|
|
||||||
`apply` 函数将在初始化阶段被调用。
|
|
||||||
|
|
||||||
<blockquote class="note">请在 apply 函数中从 module.exports 引用,因为它们可能需要被其他模块修改。</blockquote>
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Hydro.json
|
|
||||||
|
|
||||||
Hydro.json 是模块的声明文件,格式如下。
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "模块ID",
|
|
||||||
"version": "模块版本",
|
|
||||||
"description": "模块描述"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Lib
|
|
||||||
|
|
||||||
库文件。通常用于提供一些功能(废话)。
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Locale
|
|
||||||
|
|
||||||
用于提供多国翻译。格式与 Hydro 的 locale 文件夹格式相同。
|
|
||||||
@@ -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文件了。
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# README.md
|
|
||||||
|
|
||||||
项目的说明文件。
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Service
|
|
||||||
|
|
||||||
通常用于提供与其他程序对接的接口。(如内置的 MongoDB 等)
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# Template
|
|
||||||
|
|
||||||
页面模板,使用 nunjucks 语法。
|
|
||||||
传入了 _ 翻译函数与 model 等。
|
|
||||||
|
|
||||||
```html
|
|
||||||
{% set page_name = "page_name" %}
|
|
||||||
{% extends "layout/basic.html" %}
|
|
||||||
{% block content %}
|
|
||||||
<div class="error__container clearfix">
|
|
||||||
<div class="error__icon-container">
|
|
||||||
<div class="error__twd2"></div>
|
|
||||||
</div>
|
|
||||||
<div class="error__text-container">
|
|
||||||
<h1>{{ _('Oops!') }}</h1>
|
|
||||||
<p>{{ _(error.message).format(error.params) }}</p>
|
|
||||||
<p>{{ _('Technical Information') }}:</p>
|
|
||||||
<p>{{ _('Type') }}: {{ error.code }}</p>
|
|
||||||
<p>{{ _('Arguments') }}:
|
|
||||||
<ol>
|
|
||||||
{% for param in error.params %}
|
|
||||||
<li>{{ param }}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ol>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
```
|
|
||||||
|
|
||||||
<blockquote class="note">请不要覆盖已有模板。</blockquote>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
[
|
|
||||||
"introduction",
|
|
||||||
"deploy"
|
|
||||||
]
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Deployment
|
|
||||||
|
|
||||||
Hydro 依赖于 MongoDB 与 NodeJS,您应该先安装它们。
|
|
||||||
之后您可以下载最新版的 Hydro 程序,放置于一个空文件夹,使用如下命令启动 Hydro:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
node hydro.js
|
|
||||||
```
|
|
||||||
|
|
||||||
Hydro 会自行初始化并监听 8888 端口。请用浏览器访问并进行相应配置。
|
|
||||||
数据库配置完成后,会自动创建 Root 用户。(账号 `root` ,密码 `rootroot`),请及时修改。
|
|
||||||
|
|
||||||
之后的进阶配置可在 管理 面板进行。
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Introduction
|
|
||||||
|
|
||||||
为什么使用 Hydro ?
|
|
||||||
|
|
||||||
- 安全:使用 cgroup 进行隔离,杜绝卡评测;
|
|
||||||
- 高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率;
|
|
||||||
- 扩展:Hydro 支持安装额外模块进行扩展;
|
|
||||||
- 强大:配合 Judger 模块(或 HydroJudger 独立评测机),可支持 spj,交互题,提交答案题,文件IO等多种特性;
|
|
||||||
- 简便:提供了多种迁移脚本,可从 Vijos 等快速升级至 Hydro;
|
|
||||||
- 自定:所有权限节点均可自由设置;
|
|
||||||
- 社区:Hydro 正在持续维护中;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Accepted Ratio
|
|
||||||
|
|
||||||
通过率的影响极其恶劣,Hydro 不提供也不承认通过率。
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# Compile Error
|
|
||||||
|
|
||||||
可能有以下情况:
|
|
||||||
|
|
||||||
- 递交时选错了编程语言
|
|
||||||
- Java 的主类名没有使用 "Main"
|
|
||||||
- 对于 C/C++:见下
|
|
||||||
- 一般性的编译错误
|
|
||||||
|
|
||||||
<blockquote class="warn">
|
|
||||||
对 C/C++ 选手的特别提醒:
|
|
||||||
<ul>
|
|
||||||
<li>1. __int64 在 GNU C++ 中应写成 long long 类型</li>
|
|
||||||
<li>2. main() 返回值必须定义为 int ,而不是 void</li>
|
|
||||||
<li>3. for 语句中的指标变量 i 将会在如"for (int i = 0...) {...}"语句之后变为无效</li>
|
|
||||||
<li>4. itoa 不是一个通用 ANSI 函数(标准 C/C++ 中无此函数)</li>
|
|
||||||
<li>5. printf 中使用 %lf 格式是不正确的</li>
|
|
||||||
</ul>
|
|
||||||
</blockquote>
|
|
||||||
@@ -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`
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[
|
|
||||||
"compiler",
|
|
||||||
"limits",
|
|
||||||
"io",
|
|
||||||
"status",
|
|
||||||
"ce",
|
|
||||||
"training",
|
|
||||||
"contest",
|
|
||||||
"acratio",
|
|
||||||
"rp",
|
|
||||||
"dataformat",
|
|
||||||
"lostpass"
|
|
||||||
]
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# Contest
|
|
||||||
|
|
||||||
按照赛制不同,有不同的递交、排名规则。
|
|
||||||
OI 赛制所有题目均以最后一次递交为准,特别地,请避免编译错误。
|
|
||||||
OI 赛制排名规则为:总分高的排在前面,总分相等则排名相同。
|
|
||||||
ACM/ICPC 赛制所有题目递交后立即评测,以是否通过为准。
|
|
||||||
ACM/ICPC 赛制排名规则为:通过题目数多的排在前面,通过题目数相同的做题耗时(含罚时)少的排在前。
|
|
||||||
时间与空间限制以题目说明为准,默认限制参见[Limitations](#Limits)。
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Dataset Format
|
|
||||||
|
|
||||||
TODO
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# IO
|
|
||||||
|
|
||||||
若无特殊说明,Hydro 使用标准输入输出(控制台输入输出,屏幕输入输出,STD I/O)。
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Limitations
|
|
||||||
|
|
||||||
Hydro 评测机使用进程的CPU时间计算时间消耗,时间的限定为题目中评测点所指定的时间。
|
|
||||||
Hydro 评测机使用进程虚拟内存与物理内存总和计算内存空间消耗。内存空间默认限定为256MiB,题目中特别指明的,限定为题目中评测点所指定的内存空间。
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Forgot Password and/or Username
|
|
||||||
|
|
||||||
如果您无法登录,请仔细想想,是不是用户名记错了。比如,自己原本想要注册的用户名已经被注册,所以使用了一个带有前和/或后缀的用户名。
|
|
||||||
如果您确信您的账号被盗或者忘记了账号和/或密码,请及时[{{ _('Reset Password or Find Username') }}](/lostpass)。
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# RP
|
|
||||||
|
|
||||||
Hydro RP 分为固定 RP 与浮动 RP ,固定 RP 可由活动、比赛等的奖励获得,浮动 RP 由一般性通过题目获得。
|
|
||||||
浮动 RP 是一个动态的数值,每个用户在每道题上获得的 RP 都不一样,并且未来也不固定(即浮动之意)。
|
|
||||||
|
|
||||||
<blockquote class="note">每道题的浮动 RP 由该题通过总人数与该用户通过此题的名次计算得来。</blockquote>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# Judge Status
|
|
||||||
|
|
||||||
- <span class="record-status--text pending">Waiting</span> 评测:评测请求正在等待被评测机抓取
|
|
||||||
- <span class="record-status--text progress">Fetched</span> 评测:评测请求已被评测机抓取,正在准备开始评测
|
|
||||||
- <span class="record-status--text progress">Compiling</span> 评测:正在编译中
|
|
||||||
- <span class="record-status--text progress">Judging</span> 评测:编译成功,正在评测中
|
|
||||||
- <span class="record-status--text pass">Accepted</span> 通过:程序输出完全正确
|
|
||||||
- <span class="record-status--text fail">Wrong Answer</span> 不通过:程序输出与标准答案不一致(不包括行末空格以及文件末空行)
|
|
||||||
- <span class="record-status--text fail">Time Exceeded</span> 不通过:程序运行时间超过了题目限制
|
|
||||||
- <span class="record-status--text fail">Memory Exceeded</span> 不通过:程序运行内存空间超过了题目限制
|
|
||||||
- <span class="record-status--text fail">Runtime Error</span> 不通过:程序运行时错误(如数组越界、被零除、运算溢出、栈溢出、无效指针等)
|
|
||||||
- <span class="record-status--text fail">Compile Error</span> 不通过:编译失败
|
|
||||||
- <span class="record-status--text fail">System Error</span> 错误:系统错误(如果您遇到此问题,请及时在讨论区进行反馈)
|
|
||||||
- <span class="record-status--text ignored">Canceled</span> 其他:评测被取消
|
|
||||||
- <span class="record-status--text fail">Unknown Error</span> 其他:未知错误
|
|
||||||
|
|
||||||
<blockquote class="note">有“成绩取消”字样则说明管理员手动标记此记录为取消,可能违反了服务条款,比如代码被发现与其他用户的代码十分相似。</blockquote>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Training
|
|
||||||
|
|
||||||
我们精心挑选了一些题目组成了训练计划。单击导航栏的“训练”即可进入!
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<ol class="menu">
|
<ol class="menu">
|
||||||
{{ sidemenu.render_item('info', 'wiki_about', '/wiki/about') }}
|
{{ sidemenu.render_item('info', 'wiki_about', '/wiki/about') }}
|
||||||
{{ sidemenu.render_item('help', 'wiki_help', '/wiki/help') }}
|
{{ sidemenu.render_item('help', 'wiki_help', '/wiki/help') }}
|
||||||
{{ sidemenu.render_item('help', 'wiki_gettingstarted', '/wiki/gettingstarted') }}
|
{{ sidemenu.render_item('help', 'wiki_deploy', '/wiki/deploy') }}
|
||||||
{{ sidemenu.render_item('help', 'wiki_development', '/wiki/development') }}
|
{{ sidemenu.render_item('help', 'wiki_development', '/wiki/development') }}
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
@@ -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
|
#### 0. 欢迎使用 Hydro
|
||||||
|
|
||||||
@@ -57,4 +81,28 @@
|
|||||||
|
|
||||||
#### 9. 其他
|
#### 9. 其他
|
||||||
|
|
||||||
如果您对这个协议或我们的服务有意见或建议,可与我们联系,我们会给予您必要的帮助。
|
如果您对这个协议或我们的服务有意见或建议,可与我们联系,我们会给予您必要的帮助。
|
||||||
|
|
||||||
|
# Discussion: Terms Of Service | discussion
|
||||||
|
|
||||||
|
为了更好地发挥讨论、题解的积极作用,使广大用户学到知识、获得利益,进一步规范讨论和题解功能的使用,我们制定了《讨论和题解版规》(简称《版规》)。您在发布(或回复)讨论和题解时,即代表您已充分阅读、理解、接受并保证遵守此版规。
|
||||||
|
您在发布(或回复)讨论和题解或使用相关功能时须遵守以下规定:
|
||||||
|
|
||||||
|
- 第一次使用编辑器前,要先阅读编辑器快速入门和 Markdown 详细帮助。
|
||||||
|
- 不得将讨论、题解混淆。例如,不得将题解发布到讨论中,题解应发布在相应题目的题解区中。
|
||||||
|
- 发布(或回复)的所有内容不得包含会干扰 Hydro 用户界面呈现的相关内容。
|
||||||
|
- 发布(或回复)的所有内容不得包含恶意代码和指向恶意网站或 Hydro 明确禁止的网站的链接。
|
||||||
|
- 特别地,发布(或回复)含有代码的内容时,应当将代码高亮。一个简单的方法是选中代码块然后按下 Tab 键。
|
||||||
|
- 发布的题解禁止只包含无详细注释的代码。题解中难以理解的代码应当有尽可能详细的注释。
|
||||||
|
- 打分、投票和评价应当客观。例如,对于题解的打分、投票和评价应当关注于题解本身的质量。
|
||||||
|
- 我们欢迎原创作品,并会对其作者给予数量不等的 RP 奖励。
|
||||||
|
|
||||||
|
您在发布、回复讨论和题解时还须遵守法律法规,不得发布违法违规内容,包括但不限于:
|
||||||
|
|
||||||
|
- 危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
|
||||||
|
- 侵害他人知识产权、商业秘密等合法权利的内容;
|
||||||
|
- 恶意虚构事实、隐瞒真相以误导、欺骗他人的内容;
|
||||||
|
- 广告信息及垃圾信息;
|
||||||
|
- 其他法律法规禁止的内容。
|
||||||
|
|
||||||
|
对于违反《版规》的,我们将进行警告并删除相关内容、临时冻结用户、永久冻结用户等操作。
|
||||||
@@ -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`),请及时修改。
|
||||||
|
|
||||||
|
之后的进阶配置可在 管理 面板进行。
|
||||||
@@ -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 字段使用下划线,函数名使用驼峰命名。
|
||||||
|
|
||||||
|
如 `<input type="hidden" name="operation" value="confirm_delete">` 对应 `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 %}
|
||||||
|
<div class="error__container clearfix">
|
||||||
|
<div class="error__icon-container">
|
||||||
|
<div class="error__twd2"></div>
|
||||||
|
</div>
|
||||||
|
<div class="error__text-container">
|
||||||
|
<h1>{{ _('Oops!') }}</h1>
|
||||||
|
<p>{{ _(error.message).format(error.params) }}</p>
|
||||||
|
<p>{{ _('Technical Information') }}:</p>
|
||||||
|
<p>{{ _('Type') }}: {{ error.code }}</p>
|
||||||
|
<p>{{ _('Arguments') }}:
|
||||||
|
<ol>
|
||||||
|
{% for param in error.params %}
|
||||||
|
<li>{{ param }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
```
|
||||||
|
|
||||||
|
<blockquote class="note">请不要覆盖已有模板。</blockquote>
|
||||||
|
|
||||||
|
# README.md | readme
|
||||||
|
|
||||||
|
项目的说明文件。
|
||||||
@@ -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
|
||||||
|
|
||||||
|
- <span class="record-status--text pending">Waiting</span> 评测:评测请求正在等待被评测机抓取
|
||||||
|
- <span class="record-status--text progress">Fetched</span> 评测:评测请求已被评测机抓取,正在准备开始评测
|
||||||
|
- <span class="record-status--text progress">Compiling</span> 评测:正在编译中
|
||||||
|
- <span class="record-status--text progress">Judging</span> 评测:编译成功,正在评测中
|
||||||
|
- <span class="record-status--text pass">Accepted</span> 通过:程序输出完全正确
|
||||||
|
- <span class="record-status--text fail">Wrong Answer</span> 不通过:程序输出与标准答案不一致(不包括行末空格以及文件末空行)
|
||||||
|
- <span class="record-status--text fail">Time Exceeded</span> 不通过:程序运行时间超过了题目限制
|
||||||
|
- <span class="record-status--text fail">Memory Exceeded</span> 不通过:程序运行内存空间超过了题目限制
|
||||||
|
- <span class="record-status--text fail">Runtime Error</span> 不通过:程序运行时错误(如数组越界、被零除、运算溢出、栈溢出、无效指针等)
|
||||||
|
- <span class="record-status--text fail">Compile Error</span> 不通过:编译失败
|
||||||
|
- <span class="record-status--text fail">System Error</span> 错误:系统错误(如果您遇到此问题,请及时在讨论区进行反馈)
|
||||||
|
- <span class="record-status--text ignored">Canceled</span> 其他:评测被取消
|
||||||
|
- <span class="record-status--text fail">Unknown Error</span> 其他:未知错误
|
||||||
|
|
||||||
|
<blockquote class="note">有“成绩取消”字样则说明管理员手动标记此记录为取消,可能违反了服务条款,比如代码被发现与其他用户的代码十分相似。</blockquote>
|
||||||
|
|
||||||
|
# Compile Error
|
||||||
|
|
||||||
|
可能有以下情况:
|
||||||
|
|
||||||
|
- 递交时选错了编程语言
|
||||||
|
- Java 的主类名没有使用 "Main"
|
||||||
|
- 对于 C/C++:见下
|
||||||
|
- 一般性的编译错误
|
||||||
|
|
||||||
|
<blockquote class="warn">
|
||||||
|
对 C/C++ 选手的特别提醒:
|
||||||
|
<ul>
|
||||||
|
<li>1. __int64 在 GNU C++ 中应写成 long long 类型</li>
|
||||||
|
<li>2. main() 返回值必须定义为 int ,而不是 void</li>
|
||||||
|
<li>3. for 语句中的指标变量 i 将会在如"for (int i = 0...) {...}"语句之后变为无效</li>
|
||||||
|
<li>4. itoa 不是一个通用 ANSI 函数(标准 C/C++ 中无此函数)</li>
|
||||||
|
<li>5. printf 中使用 %lf 格式是不正确的</li>
|
||||||
|
</ul>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
# Training
|
||||||
|
|
||||||
|
我们精心挑选了一些题目组成了训练计划。单击导航栏的“训练”即可进入!
|
||||||
|
|
||||||
|
# Contest
|
||||||
|
|
||||||
|
按照赛制不同,有不同的递交、排名规则。
|
||||||
|
OI 赛制所有题目均以最后一次递交为准,特别地,请避免编译错误。
|
||||||
|
OI 赛制排名规则为:总分高的排在前面,总分相等则排名相同。
|
||||||
|
ACM/ICPC 赛制所有题目递交后立即评测,以是否通过为准。
|
||||||
|
ACM/ICPC 赛制排名规则为:通过题目数多的排在前面,通过题目数相同的做题耗时(含罚时)少的排在前。
|
||||||
|
时间与空间限制以题目说明为准,默认限制参见[Limitations](#Limits)。
|
||||||
|
|
||||||
|
# Accepted Ratio
|
||||||
|
|
||||||
|
通过率的影响极其恶劣,Hydro 不提供也不承认通过率。
|
||||||
|
|
||||||
|
# RP
|
||||||
|
|
||||||
|
Hydro RP 分为固定 RP 与浮动 RP ,固定 RP 可由活动、比赛等的奖励获得,浮动 RP 由一般性通过题目获得。
|
||||||
|
浮动 RP 是一个动态的数值,每个用户在每道题上获得的 RP 都不一样,并且未来也不固定(即浮动之意)。
|
||||||
|
|
||||||
|
<blockquote class="note">每道题的浮动 RP 由该题通过总人数与该用户通过此题的名次计算得来。</blockquote>
|
||||||
|
|
||||||
|
# Dataset Format
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
# Forgot Password and/or Username
|
||||||
|
|
||||||
|
如果您无法登录,请仔细想想,是不是用户名记错了。比如,自己原本想要注册的用户名已经被注册,所以使用了一个带有前和/或后缀的用户名。
|
||||||
|
如果您确信您的账号被盗或者忘记了账号和/或密码,请及时[{{ _('Reset Password or Find Username') }}](/lostpass)。
|
||||||
Reference in new issue
Block a user