mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
Merge branch 'master' of https://github.com/hydro-dev/Hydro
This commit is contained in:
commit
fc0d9873a2
30 files changed
+309
-138
No files matched your search
@@ -12,6 +12,7 @@ const system = require('../model/system');
|
||||
const { Route, Handler } = require('../service/server');
|
||||
|
||||
const ContestHandler = contest.ContestHandlerMixin(Handler);
|
||||
|
||||
class ContestListHandler extends ContestHandler {
|
||||
async get({ rule = 0, page = 1 }) {
|
||||
this.response.template = 'contest_main.html';
|
||||
@@ -31,11 +32,16 @@ class ContestListHandler extends ContestHandler {
|
||||
const tids = [];
|
||||
for (const tdoc of tdocs) tids.push(tdoc._id);
|
||||
const tsdict = await contest.getListStatus(this.user._id, tids);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['contest_main', null],
|
||||
];
|
||||
this.response.body = {
|
||||
page, tpcount, qs, rule, tdocs, tsdict,
|
||||
page, tpcount, qs, rule, tdocs, tsdict, path,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ContestDetailHandler extends ContestHandler {
|
||||
async _prepare({ tid }) {
|
||||
this.tdoc = await contest.get(tid);
|
||||
@@ -62,6 +68,7 @@ class ContestDetailHandler extends ContestHandler {
|
||||
} else attended = false;
|
||||
const udict = await user.getList([this.tdoc.owner]);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['contest_main', '/c'],
|
||||
[this.tdoc.title, null, true],
|
||||
];
|
||||
@@ -76,10 +83,12 @@ class ContestDetailHandler extends ContestHandler {
|
||||
this.back();
|
||||
}
|
||||
}
|
||||
|
||||
class ContestScoreboardHandler extends ContestDetailHandler {
|
||||
async get({ tid }) {
|
||||
const [tdoc, rows, udict] = await this.getScoreboard(tid);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['contest_main', '/c'],
|
||||
[tdoc.title, `/c/${tid}`, true],
|
||||
['contest_scoreboard', null],
|
||||
@@ -90,6 +99,7 @@ class ContestScoreboardHandler extends ContestDetailHandler {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ContestScoreboardDownloadHandler extends ContestDetailHandler {
|
||||
async get({ tid, ext }) {
|
||||
const getContent = {
|
||||
@@ -101,6 +111,7 @@ class ContestScoreboardDownloadHandler extends ContestDetailHandler {
|
||||
this.binary(await getContent[ext](rows), `${this.tdoc.title}.${ext}`);
|
||||
}
|
||||
}
|
||||
|
||||
class ContestEditHandler extends ContestDetailHandler {
|
||||
async prepare({ tid }) {
|
||||
const tdoc = await contest.get(tid);
|
||||
@@ -113,6 +124,7 @@ class ContestEditHandler extends ContestDetailHandler {
|
||||
for (const i in contest.RULES) { rules[i] = contest.RULES[i].TEXT; }
|
||||
const duration = (this.tdoc.endAt.getTime() - this.tdoc.beginAt.getTime()) / 3600 / 1000;
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['contest_main', '/c'],
|
||||
[this.tdoc.title, `/c/${this.tdoc._id}`, true],
|
||||
['contest_edit', null],
|
||||
@@ -151,6 +163,7 @@ class ContestEditHandler extends ContestDetailHandler {
|
||||
else this.response.redirect = `/c/${this.tdoc._id}`;
|
||||
}
|
||||
}
|
||||
|
||||
class ContestProblemHandler extends ContestDetailHandler {
|
||||
async prepare({ tid, pid }) {
|
||||
[this.tdoc, this.pdoc] = await Promise.all([
|
||||
@@ -175,6 +188,7 @@ class ContestProblemHandler extends ContestDetailHandler {
|
||||
|
||||
async get({ tid }) {
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['contest_main', '/c'],
|
||||
[this.tdoc.title, `/c/${tid}`, true],
|
||||
[this.pdoc.title, null, true],
|
||||
@@ -189,6 +203,7 @@ class ContestProblemHandler extends ContestDetailHandler {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ContestProblemSubmitHandler extends ContestProblemHandler {
|
||||
async get({ tid, pid }) {
|
||||
let rdocs = [];
|
||||
@@ -198,6 +213,7 @@ class ContestProblemSubmitHandler extends ContestProblemHandler {
|
||||
}
|
||||
this.response.template = 'problem_submit.html';
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['contest_main', '/c'],
|
||||
[this.tdoc.title, `/c/${tid}`, true],
|
||||
[this.pdoc.title, `/c/${tid}/p/${pid}`, true],
|
||||
@@ -229,6 +245,7 @@ class ContestProblemSubmitHandler extends ContestProblemHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ContestCreateHandler extends ContestHandler {
|
||||
async prepare() {
|
||||
this.checkPerm(PERM_CREATE_CONTEST);
|
||||
@@ -242,8 +259,14 @@ class ContestCreateHandler extends ContestHandler {
|
||||
let ts = now.getTime();
|
||||
ts = ts - (ts % (15 * 60 * 1000)) + 15 * 60 * 1000;
|
||||
const dt = new Date(ts);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['contest_main', '/c'],
|
||||
['contest_create', null],
|
||||
];
|
||||
this.response.body = {
|
||||
rules,
|
||||
path,
|
||||
page_name: 'contest_create',
|
||||
date_text: `${dt.getFullYear()}-${dt.getMonth() + 1}-${dt.getDate()}`,
|
||||
time_text: `${dt.getHours()}:${dt.getMinutes()}`,
|
||||
|
||||
@@ -88,6 +88,7 @@ class DiscussionNodeHandler extends DiscussionHandler {
|
||||
);
|
||||
const udict = await user.getList(ddocs.map((ddoc) => ddoc.owner));
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['discussion_main', '/discuss'],
|
||||
[this.vnode.title, null, true],
|
||||
];
|
||||
@@ -112,6 +113,7 @@ class DiscussionCreateHandler extends DiscussionHandler {
|
||||
|
||||
async get({ type, docId }) {
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['discussion_main', '/discuss'],
|
||||
[this.vnode.title, `/discuss/${type}/${docId}`, true],
|
||||
['discussion_create', null],
|
||||
@@ -155,8 +157,9 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
}
|
||||
const udict = await user.getList(uids);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['discussion_main', '/discuss'],
|
||||
[this.vnode.title, '/discuss/{type}', true],
|
||||
[this.vnode.title, `/discuss/${this.ddoc.parentType}`, true],
|
||||
[this.ddoc.title, null, true],
|
||||
];
|
||||
this.response.template = 'discussion_detail.html';
|
||||
@@ -243,8 +246,15 @@ class DiscussionTailReplyRawHandler extends DiscussionHandler {
|
||||
class DiscussionEditHandler extends DiscussionHandler {
|
||||
async get() {
|
||||
if (this.ddoc.owner !== this.user._id) this.checkPerm(PERM_EDIT_DISCUSSION);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['discussion_main', '/discuss'],
|
||||
[this.vnode.title, `/discuss/${this.ddoc.parentType}`, true],
|
||||
[this.ddoc.title, `/discuss/${this.ddoc._id}`, true],
|
||||
['discussion_edit', null],
|
||||
];
|
||||
this.response.template = 'discussion_edit.html';
|
||||
this.response.body = { ddoc: this.ddoc };
|
||||
this.response.body = { ddoc: this.ddoc, path };
|
||||
}
|
||||
|
||||
async post({
|
||||
|
||||
+44
-10
@@ -22,15 +22,25 @@ class ManageMainHandler extends ManageHandler {
|
||||
|
||||
class ManageDashboardHandler extends ManageHandler {
|
||||
async get() {
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['manage', '/manage'],
|
||||
['manage_dashboard', null],
|
||||
];
|
||||
this.response.template = 'manage_dashboard.html';
|
||||
this.response.body = { system: this.system };
|
||||
this.response.body = { system: this.system, path };
|
||||
}
|
||||
}
|
||||
|
||||
class ManageEditHandler extends ManageHandler {
|
||||
async get() {
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['manage', '/manage'],
|
||||
['manage_edit', null],
|
||||
];
|
||||
this.response.template = 'manage_edit.html';
|
||||
this.response.body = { system: this.system };
|
||||
this.response.body = { system: this.system, path };
|
||||
}
|
||||
|
||||
async post({ uname, gravatar, bio }) {
|
||||
@@ -46,7 +56,7 @@ class ManageUserHandler extends ManageHandler {
|
||||
async get() {
|
||||
const uids = [];
|
||||
const rudocs = {};
|
||||
const [udocs, roles, system] = await Promise.all([
|
||||
const [udocs, roles, sys] = await Promise.all([
|
||||
user.getMulti({ role: { $nin: ['default', 'guest'] } }).toArray(),
|
||||
user.getRoles(),
|
||||
user.getById(0),
|
||||
@@ -58,9 +68,14 @@ class ManageUserHandler extends ManageHandler {
|
||||
}
|
||||
const rolesSelect = roles.map((role) => [role._id, role._id]);
|
||||
const udict = await user.getList(uids);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['manage', '/manage'],
|
||||
['manage_user', null],
|
||||
];
|
||||
this.response.template = 'manage_user.html';
|
||||
this.response.body = {
|
||||
roles, rolesSelect, rudocs, udict, system,
|
||||
roles, rolesSelect, rudocs, udict, system: sys, path,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,12 +87,17 @@ class ManageUserHandler extends ManageHandler {
|
||||
|
||||
class ManagePermissionHandler extends ManageHandler {
|
||||
async get() {
|
||||
const [roles, system] = await Promise.all([
|
||||
const [roles, sys] = await Promise.all([
|
||||
user.getRoles(),
|
||||
user.getById(0),
|
||||
]);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['manage', '/manage'],
|
||||
['manage_permission', null],
|
||||
];
|
||||
this.response.template = 'manage_permission.html';
|
||||
this.response.body = { roles, system };
|
||||
this.response.body = { roles, system: sys, path };
|
||||
}
|
||||
|
||||
async post({ roles }) {
|
||||
@@ -95,12 +115,17 @@ class ManagePermissionHandler extends ManageHandler {
|
||||
|
||||
class ManageRoleHandler extends ManageHandler {
|
||||
async get() {
|
||||
const [roles, system] = await Promise.all([
|
||||
const [roles, sys] = await Promise.all([
|
||||
user.getRoles(),
|
||||
user.getById(0),
|
||||
]);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['manage', '/manage'],
|
||||
['manage_role', null],
|
||||
];
|
||||
this.response.template = 'manage_role.html';
|
||||
this.response.body = { roles, system };
|
||||
this.response.body = { roles, system: sys, path };
|
||||
}
|
||||
|
||||
async postAdd({ role }) {
|
||||
@@ -127,11 +152,20 @@ class ManageRoleHandler extends ManageHandler {
|
||||
class ManageModuleHandler extends ManageHandler {
|
||||
async get() {
|
||||
const installed = await hpm.getInstalled();
|
||||
const active = loader.active.map((module) => module.id);
|
||||
this.response.body = { installed, active };
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['manage', '/manage'],
|
||||
['manage_module', null],
|
||||
];
|
||||
this.response.body = { installed, active: loader.active, path };
|
||||
this.response.template = 'manage_module.html';
|
||||
}
|
||||
|
||||
async postInstall({ url, id }) {
|
||||
await hpm.install(url, id);
|
||||
this.back();
|
||||
}
|
||||
|
||||
async postDelete({ id }) {
|
||||
await hpm.del(id);
|
||||
this.back();
|
||||
|
||||
@@ -32,7 +32,7 @@ class ProblemHandler extends Handler {
|
||||
this.response.template = 'problem_main.html';
|
||||
const q = {};
|
||||
let psdict = {};
|
||||
if (category) q.category = category;
|
||||
if (category) q.$or = [{ category }, { tag: category }];
|
||||
if (!this.user.hasPerm(PERM_VIEW_PROBLEM_HIDDEN)) q.hidden = false;
|
||||
const [pdocs, ppcount, pcount] = await paginate(
|
||||
problem.getMulti(q).sort({ pid: 1 }),
|
||||
@@ -50,6 +50,55 @@ class ProblemHandler extends Handler {
|
||||
path, page, pcount, ppcount, pdocs, psdict, category,
|
||||
};
|
||||
}
|
||||
|
||||
async cleanup() {
|
||||
if (this.response.template === 'problem_main.html' && this.preferJson) {
|
||||
const {
|
||||
path, page, pcount, ppcount, pdocs, psdict, category,
|
||||
} = this.response.body;
|
||||
this.response.body = {
|
||||
title: this.renderTitle(category),
|
||||
fragments: (await Promise.all([
|
||||
this.renderHTML('partials/problem_list.html', {
|
||||
page, ppcount, pcount, pdocs, psdict,
|
||||
}),
|
||||
this.renderHTML('partials/problem_stat.html', { pcount }),
|
||||
this.renderHTML('partials/problem_lucky.html', { category }),
|
||||
this.renderHTML('partials/path.html', { path }),
|
||||
])).map((i) => ({ html: i })),
|
||||
raw: {
|
||||
path, page, pcount, ppcount, pdocs, psdict, category,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ProblemCategoryHandler extends ProblemHandler {
|
||||
async get({ page = 1, category }) {
|
||||
this.response.template = 'problem_main.html';
|
||||
const q = {
|
||||
$or: [{ category }, { tag: category }],
|
||||
};
|
||||
let psdict = {};
|
||||
if (!this.user.hasPerm(PERM_VIEW_PROBLEM_HIDDEN)) q.hidden = false;
|
||||
const [pdocs, ppcount, pcount] = await paginate(
|
||||
problem.getMulti(q).sort({ pid: 1 }),
|
||||
page,
|
||||
await system.get('PROBLEM_PER_PAGE'),
|
||||
);
|
||||
if (this.user.hasPerm(PERM_LOGGEDIN)) {
|
||||
psdict = await problem.getListStatus(this.user._id, pdocs.map((pdoc) => pdoc._id));
|
||||
}
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['problem_main', '/p'],
|
||||
[category, null, true],
|
||||
];
|
||||
this.response.body = {
|
||||
path, page, pcount, ppcount, pdocs, psdict, category,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ProblemRandomHandler extends ProblemHandler {
|
||||
@@ -59,6 +108,7 @@ class ProblemRandomHandler extends ProblemHandler {
|
||||
const pid = await problem.random(q);
|
||||
if (!pid) throw new NoProblemError();
|
||||
this.response.body = { pid };
|
||||
this.response.redirect = `/p/${pid}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,6 +430,7 @@ class ProblemCreateHandler extends Handler {
|
||||
|
||||
async function apply() {
|
||||
Route('/p', module.exports.ProblemHandler);
|
||||
Route('/p/category/:category', module.exports.ProblemCategoryHandler);
|
||||
Route('/problem/random', module.exports.ProblemRandomHandler);
|
||||
Route('/p/:pid', module.exports.ProblemDetailHandler);
|
||||
Route('/p/:pid/submit', module.exports.ProblemSubmitHandler);
|
||||
@@ -398,6 +449,7 @@ async function apply() {
|
||||
|
||||
global.Hydro.handler.problem = module.exports = {
|
||||
ProblemHandler,
|
||||
ProblemCategoryHandler,
|
||||
ProblemRandomHandler,
|
||||
ProblemDetailHandler,
|
||||
ProblemSubmitHandler,
|
||||
|
||||
Reference in new issue
Block a user