mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
讨论节点
This commit is contained in:
1 parent
5e51bd2fe0
commit
7d27e56018
20 files changed
+154
-47
No files matched your search
+21
-13
@@ -1,6 +1,4 @@
|
|||||||
const paginate = require('../lib/paginate');
|
const paginate = require('../lib/paginate');
|
||||||
const problem = require('../model/problem');
|
|
||||||
const contest = require('../model/contest');
|
|
||||||
const system = require('../model/system');
|
const system = require('../model/system');
|
||||||
const user = require('../model/user');
|
const user = require('../model/user');
|
||||||
const discussion = require('../model/discussion');
|
const discussion = require('../model/discussion');
|
||||||
@@ -8,20 +6,20 @@ const {
|
|||||||
Route, Handler,
|
Route, Handler,
|
||||||
} = require('../service/server');
|
} = require('../service/server');
|
||||||
const {
|
const {
|
||||||
DiscussionNodeNotFoundError, DiscussionNotFoundError, DocumentNotFoundError,
|
DiscussionNotFoundError, DocumentNotFoundError,
|
||||||
} = require('../error');
|
} = require('../error');
|
||||||
const {
|
const {
|
||||||
PERM_VIEW_DISCUSSION, PERM_EDIT_DISCUSSION, PERM_EDIT_DISCUSSION_REPLY,
|
PERM_VIEW_DISCUSSION, PERM_EDIT_DISCUSSION, PERM_EDIT_DISCUSSION_REPLY,
|
||||||
PERM_VIEW_PROBLEM_HIDDEN, PERM_DELETE_DISCUSSION, PERM_DELETE_DISCUSSION_REPLY,
|
PERM_DELETE_DISCUSSION, PERM_DELETE_DISCUSSION_REPLY, PERM_HIGHLIGHT_DISCUSSION,
|
||||||
PERM_HIGHLIGHT_DISCUSSION, PERM_LOGGEDIN, PERM_CREATE_DISCUSSION,
|
PERM_LOGGEDIN, PERM_CREATE_DISCUSSION, PERM_REPLY_DISCUSSION,
|
||||||
PERM_REPLY_DISCUSSION,
|
|
||||||
} = require('../permission');
|
} = require('../permission');
|
||||||
|
|
||||||
class DiscussionHandler extends Handler {
|
class DiscussionHandler extends Handler {
|
||||||
async _prepare({
|
async _prepare({
|
||||||
type, docId, did, drid, drrid,
|
type = 'node', docId, name, did, drid, drrid,
|
||||||
}) {
|
}) {
|
||||||
this.checkPerm(PERM_VIEW_DISCUSSION);
|
this.checkPerm(PERM_VIEW_DISCUSSION);
|
||||||
|
docId = docId || name;
|
||||||
if (did) {
|
if (did) {
|
||||||
this.ddoc = await discussion.get(did);
|
this.ddoc = await discussion.get(did);
|
||||||
if (!this.ddoc) throw new DiscussionNotFoundError(did);
|
if (!this.ddoc) throw new DiscussionNotFoundError(did);
|
||||||
@@ -44,8 +42,11 @@ class DiscussionHandler extends Handler {
|
|||||||
// TODO(twd2): exclude problem/contest discussions?
|
// TODO(twd2): exclude problem/contest discussions?
|
||||||
// TODO(iceboy): continuation based pagination.
|
// TODO(iceboy): continuation based pagination.
|
||||||
this.vnode = await discussion.getVnode({ parentType: type, parentId: docId }, this);
|
this.vnode = await discussion.getVnode({ parentType: type, parentId: docId }, this);
|
||||||
this.ddoc.parentType = this.ddoc.parentType || this.vnode.type;
|
if (this.ddoc) {
|
||||||
this.ddoc.parentId = this.ddoc.parentId || this.vnode.id;
|
this.ddoc.parentType = this.ddoc.parentType || this.vnode.type;
|
||||||
|
this.ddoc.parentId = this.ddoc.parentId || this.vnode.id;
|
||||||
|
}
|
||||||
|
console.log(this.vnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +70,10 @@ class DiscussionMainHandler extends DiscussionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DiscussionNodeHandler extends DiscussionHandler {
|
class DiscussionNodeHandler extends DiscussionHandler {
|
||||||
async get({ type, docId, page = 1 }) {
|
async get({
|
||||||
|
type = 'node', docId, name, page = 1,
|
||||||
|
}) {
|
||||||
|
docId = docId || name;
|
||||||
const [ddocs, dpcount] = await paginate(
|
const [ddocs, dpcount] = await paginate(
|
||||||
discussion.getMulti({ type, docId }),
|
discussion.getMulti({ type, docId }),
|
||||||
page,
|
page,
|
||||||
@@ -100,7 +104,8 @@ class DiscussionCreateHandler extends DiscussionHandler {
|
|||||||
this.checkPerm(PERM_CREATE_DISCUSSION);
|
this.checkPerm(PERM_CREATE_DISCUSSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
async get({ type, docId }) {
|
async get({ type = 'node', docId, name }) {
|
||||||
|
docId = docId || name;
|
||||||
const path = [
|
const path = [
|
||||||
['Hydro', '/'],
|
['Hydro', '/'],
|
||||||
['discussion_main', '/discuss'],
|
['discussion_main', '/discuss'],
|
||||||
@@ -112,8 +117,9 @@ class DiscussionCreateHandler extends DiscussionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async post({
|
async post({
|
||||||
type, docId, title, content, highlight,
|
type = 'node', docId, name, title, content, highlight,
|
||||||
}) {
|
}) {
|
||||||
|
docId = docId || name;
|
||||||
this.limitRate('add_discussion', 3600, 30);
|
this.limitRate('add_discussion', 3600, 30);
|
||||||
if (highlight) this.checkPerm(PERM_HIGHLIGHT_DISCUSSION);
|
if (highlight) this.checkPerm(PERM_HIGHLIGHT_DISCUSSION);
|
||||||
const did = await discussion.add(
|
const did = await discussion.add(
|
||||||
@@ -153,7 +159,7 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
|||||||
];
|
];
|
||||||
this.response.template = 'discussion_detail.html';
|
this.response.template = 'discussion_detail.html';
|
||||||
this.response.body = {
|
this.response.body = {
|
||||||
path, ddoc: this.ddoc, dsdoc, drdocs, page, pcount, drcount, udict,
|
path, ddoc: this.ddoc, dsdoc, drdocs, page, pcount, drcount, udict, vnode: this.vnode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,6 +278,8 @@ async function apply() {
|
|||||||
Route('/discuss/:did/raw', module.exports.DiscussionDetailRawHandler);
|
Route('/discuss/:did/raw', module.exports.DiscussionDetailRawHandler);
|
||||||
Route('/discuss/:did/:drid/raw', module.exports.DiscussionReplyRawHandler);
|
Route('/discuss/:did/:drid/raw', module.exports.DiscussionReplyRawHandler);
|
||||||
Route('/discuss/:did/:drid/:drrid/raw', module.exports.DiscussionTailReplyRawHandler);
|
Route('/discuss/:did/:drid/:drrid/raw', module.exports.DiscussionTailReplyRawHandler);
|
||||||
|
Route('/discuss/node/:name', module.exports.DiscussionNodeHandler);
|
||||||
|
Route('/discuss/node/:name/create', module.exports.DiscussionCreateHandler);
|
||||||
Route('/discuss/:type/:docId', module.exports.DiscussionNodeHandler);
|
Route('/discuss/:type/:docId', module.exports.DiscussionNodeHandler);
|
||||||
Route('/discuss/:type/:docId/create', module.exports.DiscussionCreateHandler);
|
Route('/discuss/:type/:docId/create', module.exports.DiscussionCreateHandler);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const { Route, Handler } = require('../service/server');
|
|||||||
|
|
||||||
class FileDownloadHandler extends Handler {
|
class FileDownloadHandler extends Handler {
|
||||||
async get({ id, secret, name }) {
|
async get({ id, secret, name }) {
|
||||||
|
if (name) name = Buffer.from(name, 'base64').toString();
|
||||||
this.response.attachment(name || id);
|
this.response.attachment(name || id);
|
||||||
this.response.body = await file.get(id, secret);
|
this.response.body = await file.get(id, secret);
|
||||||
}
|
}
|
||||||
@@ -10,6 +11,7 @@ class FileDownloadHandler extends Handler {
|
|||||||
|
|
||||||
async function apply() {
|
async function apply() {
|
||||||
Route('/fs/:id/:secret', module.exports.FileDownloadHandler);
|
Route('/fs/:id/:secret', module.exports.FileDownloadHandler);
|
||||||
|
Route('/fs/:id/:name/:secret', module.exports.FileDownloadHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
global.Hydro.handler.file = module.exports = {
|
global.Hydro.handler.file = module.exports = {
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ try {
|
|||||||
pending.push(m);
|
pending.push(m);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
// Ignore Missing
|
||||||
}
|
}
|
||||||
|
|
||||||
async function preload() {
|
async function preload() {
|
||||||
|
|||||||
@@ -5,6 +5,66 @@ const BUILTIN_ROLES = [
|
|||||||
{ _id: 'default', perm: perm.PERM_DEFAULT, count: 0 },
|
{ _id: 'default', perm: perm.PERM_DEFAULT, count: 0 },
|
||||||
{ _id: 'root', perm: perm.PERM_ALL, count: 0 },
|
{ _id: 'root', perm: perm.PERM_ALL, count: 0 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const DEFAULT_NODES = {
|
||||||
|
探索: [
|
||||||
|
{ pic: 'qa', name: '问答' },
|
||||||
|
{ pic: 'share', name: '分享' },
|
||||||
|
{ pic: 'solution', name: '题解' },
|
||||||
|
],
|
||||||
|
Vijos: [
|
||||||
|
{ pic: 'vijos', name: 'Vijos' },
|
||||||
|
{ pic: null, name: '团队' },
|
||||||
|
{ pic: null, name: '月赛' },
|
||||||
|
{ pic: 'advice', name: '建议' },
|
||||||
|
],
|
||||||
|
数据结构: [
|
||||||
|
{ pic: null, name: '散列表' },
|
||||||
|
{ pic: null, name: '搜索树' },
|
||||||
|
{ pic: null, name: '栈和队列' },
|
||||||
|
{ pic: null, name: '图' },
|
||||||
|
{ pic: null, name: '堆' },
|
||||||
|
],
|
||||||
|
算法: [
|
||||||
|
{ pic: null, name: '数论' },
|
||||||
|
{ pic: null, name: '几何' },
|
||||||
|
{ pic: null, name: '图论' },
|
||||||
|
{ pic: null, name: '网络流' },
|
||||||
|
{ pic: null, name: '动态规划' },
|
||||||
|
{ pic: null, name: '背包' },
|
||||||
|
{ pic: null, name: '排序' },
|
||||||
|
{ pic: null, name: '搜索' },
|
||||||
|
{ pic: null, name: '并查集' },
|
||||||
|
{ pic: null, name: '贪心' },
|
||||||
|
{ pic: null, name: '博弈论' },
|
||||||
|
],
|
||||||
|
在线题库: [
|
||||||
|
{ pic: null, name: 'CodeForces' },
|
||||||
|
{ pic: null, name: 'TopCoder' },
|
||||||
|
{ pic: null, name: 'POJ' },
|
||||||
|
{ pic: null, name: 'BZOJ' },
|
||||||
|
{ pic: null, name: 'USACO' },
|
||||||
|
{ pic: null, name: 'RQNOJ' },
|
||||||
|
{ pic: null, name: 'UOJ' },
|
||||||
|
{ pic: null, name: 'LOJ' },
|
||||||
|
{ pic: null, name: '洛谷' },
|
||||||
|
],
|
||||||
|
泛: [
|
||||||
|
{ pic: null, name: '数学' },
|
||||||
|
{ pic: null, name: '编程' },
|
||||||
|
{ pic: null, name: '数据库' },
|
||||||
|
{ pic: null, name: 'C' },
|
||||||
|
{ pic: null, name: 'C++' },
|
||||||
|
{ pic: null, name: 'Pascal' },
|
||||||
|
{ pic: null, name: 'Java' },
|
||||||
|
{ pic: null, name: 'PHP' },
|
||||||
|
{ pic: null, name: 'Python' },
|
||||||
|
{ pic: null, name: '游戏' },
|
||||||
|
{ pic: null, name: '保送' },
|
||||||
|
{ pic: null, name: 'ACM' },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
const CATEGORIES = {
|
const CATEGORIES = {
|
||||||
动态规划: [
|
动态规划: [
|
||||||
'LCS',
|
'LCS',
|
||||||
@@ -232,6 +292,7 @@ const STATUS_CODES = {
|
|||||||
|
|
||||||
global.Hydro.model.builtin = module.exports = {
|
global.Hydro.model.builtin = module.exports = {
|
||||||
BUILTIN_ROLES,
|
BUILTIN_ROLES,
|
||||||
|
DEFAULT_NODES,
|
||||||
CATEGORIES,
|
CATEGORIES,
|
||||||
VIEW_LANGS,
|
VIEW_LANGS,
|
||||||
FOOTER_EXTRA_HTMLS,
|
FOOTER_EXTRA_HTMLS,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const problem = require('./problem');
|
|||||||
const contest = require('./contest');
|
const contest = require('./contest');
|
||||||
const { PERM_VIEW_PROBLEM_HIDDEN } = require('../permission');
|
const { PERM_VIEW_PROBLEM_HIDDEN } = require('../permission');
|
||||||
const { DocumentNotFoundError } = require('../error');
|
const { DocumentNotFoundError } = require('../error');
|
||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
|
|
||||||
const coll = db.collection('discussion');
|
const coll = db.collection('discussion');
|
||||||
const collReply = db.collection('discussion.reply');
|
const collReply = db.collection('discussion.reply');
|
||||||
@@ -133,6 +133,10 @@ function getStatus(did, uid) {
|
|||||||
return collStatus.findOne({ did, uid });
|
return collStatus.findOne({ did, uid });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addNode(_id, category) {
|
||||||
|
return collNode.insertOne({ _id, category });
|
||||||
|
}
|
||||||
|
|
||||||
function getNode(_id) {
|
function getNode(_id) {
|
||||||
return collNode.findOne({ _id });
|
return collNode.findOne({ _id });
|
||||||
}
|
}
|
||||||
@@ -148,7 +152,7 @@ async function getVnode(ddoc, handler) {
|
|||||||
return { ...tdoc, type: ddoc.parentType, id: ddoc.parentId };
|
return { ...tdoc, type: ddoc.parentType, id: ddoc.parentId };
|
||||||
} if (ddoc.parentType === 'node') {
|
} if (ddoc.parentType === 'node') {
|
||||||
const ndoc = await getNode(ddoc.parentId);
|
const ndoc = await getNode(ddoc.parentId);
|
||||||
return { ...ndoc, type: ddoc.parentType, id: ddoc.parentId };
|
return { title: ndoc._id, type: ddoc.parentType, id: ddoc.parentId };
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
title: 'Missing Node',
|
title: 'Missing Node',
|
||||||
@@ -185,6 +189,7 @@ global.Hydro.model.discussion = module.exports = {
|
|||||||
delTailReply,
|
delTailReply,
|
||||||
setStar,
|
setStar,
|
||||||
getStatus,
|
getStatus,
|
||||||
|
addNode,
|
||||||
getVnode,
|
getVnode,
|
||||||
getListVnodes,
|
getListVnodes,
|
||||||
};
|
};
|
||||||
+12
-8
@@ -5,6 +5,10 @@ const hash = require('../lib/hash.hydro');
|
|||||||
|
|
||||||
const coll = db.collection('file');
|
const coll = db.collection('file');
|
||||||
|
|
||||||
|
function _timestamp() {
|
||||||
|
return Math.floor(Number(new Date()) / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
async function add(stream, filename, meta = {}) {
|
async function add(stream, filename, meta = {}) {
|
||||||
const file = await coll.insertOne(meta);
|
const file = await coll.insertOne(meta);
|
||||||
const w = fs.openUploadStreamWithId(file.insertedId, filename);
|
const w = fs.openUploadStreamWithId(file.insertedId, filename);
|
||||||
@@ -43,11 +47,11 @@ async function dec(_id) {
|
|||||||
async function get(_id, secret = null) {
|
async function get(_id, secret = null) {
|
||||||
const file = await coll.findOne({ _id });
|
const file = await coll.findOne({ _id });
|
||||||
if (typeof secret !== 'undefined') {
|
if (typeof secret !== 'undefined') {
|
||||||
const timestamp = Math.floor(Number(new Date())).toString();
|
const timestamp = _timestamp();
|
||||||
if (!(
|
if (!hash.check(file.secret, timestamp.toString(), secret)) {
|
||||||
hash.check(file.secret, timestamp, secret)
|
if (!hash.check(file.secret, timestamp.toString() - 1, secret)) {
|
||||||
|| hash.check(file.secret, timestamp - 1, secret))) {
|
throw new ForbiddenError();
|
||||||
throw new ForbiddenError();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fs.openDownloadStream(_id);
|
return fs.openDownloadStream(_id);
|
||||||
@@ -59,11 +63,11 @@ function getMeta(_id) {
|
|||||||
|
|
||||||
async function url(_id, name) {
|
async function url(_id, name) {
|
||||||
const file = await coll.findOne({ _id });
|
const file = await coll.findOne({ _id });
|
||||||
const secret = hash.hash(file.secret, Math.floor(Number(new Date())).toString());
|
const secret = hash.hash(file.secret, _timestamp().toString());
|
||||||
if (name) return `/fs/${_id}/${secret}?name=${Buffer.from(name).toString('base64')}`;
|
if (name) return `/fs/${_id}/${Buffer.from(name).toString('base64')}/${secret}`;
|
||||||
return `/fs/${_id}/${secret}`;
|
return `/fs/${_id}/${secret}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
global.Hydro.model.blacklist = module.exports = {
|
global.Hydro.model.file = module.exports = {
|
||||||
add, get, del, inc, dec, getMeta, url,
|
add, get, del, inc, dec, getMeta, url,
|
||||||
};
|
};
|
||||||
@@ -13,4 +13,5 @@ module.exports = {
|
|||||||
task: require('./task'),
|
task: require('./task'),
|
||||||
message: require('./message'),
|
message: require('./message'),
|
||||||
setting: require('./setting'),
|
setting: require('./setting'),
|
||||||
|
file: require('./file'),
|
||||||
};
|
};
|
||||||
@@ -21,8 +21,8 @@ async function send(from, to, content) {
|
|||||||
$setOnInsert: {
|
$setOnInsert: {
|
||||||
from: Math.min(from, to),
|
from: Math.min(from, to),
|
||||||
to: Math.max(from, to),
|
to: Math.max(from, to),
|
||||||
fromUnread: false,
|
fromUnread: from > to,
|
||||||
toUnread: true,
|
toUnread: from < to,
|
||||||
},
|
},
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
return await coll.findOne({ // eslint-disable-line no-return-await
|
return await coll.findOne({ // eslint-disable-line no-return-await
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const { OpcountExceededError } = require('../error');
|
const { OpcountExceededError } = require('../error');
|
||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
|
|
||||||
const coll = db.collection('opcount');
|
const coll = db.collection('opcount');
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const { STATUS_WAITING } = require('./builtin').STATUS;
|
|||||||
const task = require('./task');
|
const task = require('./task');
|
||||||
const problem = require('./problem');
|
const problem = require('./problem');
|
||||||
const { RecordNotFoundError } = require('../error');
|
const { RecordNotFoundError } = require('../error');
|
||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
|
|
||||||
const coll = db.collection('record');
|
const coll = db.collection('record');
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const { ObjectID } = require('bson');
|
const { ObjectID } = require('bson');
|
||||||
const { SolutionNotFoundError } = require('../error');
|
const { SolutionNotFoundError } = require('../error');
|
||||||
const validator = require('../lib/validator');
|
const validator = require('../lib/validator');
|
||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
|
|
||||||
const coll = db.collection('solution');
|
const coll = db.collection('solution');
|
||||||
const collStatus = db.collection('solution.status');
|
const collStatus = db.collection('solution.status');
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
|
|
||||||
const coll = db.collection('system');
|
const coll = db.collection('system');
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
|
|
||||||
const coll = db.collection('task');
|
const coll = db.collection('task');
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
const { ValidationError } = require('../error');
|
const { ValidationError } = require('../error');
|
||||||
|
|
||||||
const coll = db.collection('token');
|
const coll = db.collection('token');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const validator = require('../lib/validator');
|
const validator = require('../lib/validator');
|
||||||
const { ValidationError, TrainingNotFoundError, TrainingAlreadyEnrollError } = require('../error');
|
const { ValidationError, TrainingNotFoundError, TrainingAlreadyEnrollError } = require('../error');
|
||||||
const db = require('../service/db.js');
|
const db = require('../service/db');
|
||||||
|
|
||||||
const coll = db.collection('traning');
|
const coll = db.collection('traning');
|
||||||
const collStatus = db.collection('training.status');
|
const collStatus = db.collection('training.status');
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ class USER {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkPassword(password) {
|
checkPassword(password) {
|
||||||
const h = global.Hydro.lib[`hash.${this.hashType}`];
|
const h = global.Hydro.lib[`hash.${this.hashType || 'hydro'}`];
|
||||||
if (!h) throw new Error('Unknown hash method');
|
if (!h) throw new Error('Unknown hash method');
|
||||||
return h.check(password, this.salt(), this.hash());
|
return h.check(password, this.salt(), this.hash());
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -1,6 +1,7 @@
|
|||||||
const { defaults } = require('lodash');
|
const { defaults } = require('lodash');
|
||||||
const db = require('../service/db');
|
const db = require('../service/db');
|
||||||
const builtin = require('../model/builtin');
|
const builtin = require('../model/builtin');
|
||||||
|
const discussion = require('../model/discussion');
|
||||||
const system = require('../model/system');
|
const system = require('../model/system');
|
||||||
const pwhash = require('../lib/hash.hydro');
|
const pwhash = require('../lib/hash.hydro');
|
||||||
const { udoc } = require('../interface');
|
const { udoc } = require('../interface');
|
||||||
@@ -36,7 +37,7 @@ async function run() {
|
|||||||
changemail_token_expire_seconds: 3600 * 24,
|
changemail_token_expire_seconds: 3600 * 24,
|
||||||
registration_token_expire_seconds: 600,
|
registration_token_expire_seconds: 600,
|
||||||
};
|
};
|
||||||
const tasks = [];
|
let tasks = [];
|
||||||
for (const key in def) {
|
for (const key in def) {
|
||||||
tasks.push(system.set(key, def[key]));
|
tasks.push(system.set(key, def[key]));
|
||||||
}
|
}
|
||||||
@@ -77,6 +78,14 @@ async function run() {
|
|||||||
}
|
}
|
||||||
await collRole.deleteMany({ _id: { $in: builtin.BUILTIN_ROLES.map((role) => role._id) } });
|
await collRole.deleteMany({ _id: { $in: builtin.BUILTIN_ROLES.map((role) => role._id) } });
|
||||||
await collRole.insertMany(builtin.BUILTIN_ROLES);
|
await collRole.insertMany(builtin.BUILTIN_ROLES);
|
||||||
|
tasks = [];
|
||||||
|
for (const category in builtin.DEFAULT_NODES) {
|
||||||
|
const nodes = builtin.DEFAULT_NODES[category];
|
||||||
|
for (const node of nodes) {
|
||||||
|
tasks.push(discussion.addNode(node.name, category));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Promise.all(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
global.Hydro.script.install = module.exports = { run };
|
global.Hydro.script.install = module.exports = { run };
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
const homework = require('./homework');
|
const homework = require('./homework');
|
||||||
|
|
||||||
const rules = global.Hydro['model.contest'].RULES;
|
global.Hydro.model.contest.RULES.homework = homework;
|
||||||
rules.homework = homework;
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
const { mongodb } = global.Hydro.nodeModules;
|
const { mongodb } = global.Hydro.nodeModules;
|
||||||
const dst = global.Hydro.service.db;
|
const dst = global.Hydro.service.db;
|
||||||
const { problem } = global.Hydro.model;
|
const { problem, discussion } = global.Hydro.model;
|
||||||
|
|
||||||
const map = {};
|
const map = {};
|
||||||
|
|
||||||
@@ -112,8 +112,8 @@ const tasks = {
|
|||||||
nReply: doc.num_replies,
|
nReply: doc.num_replies,
|
||||||
ip: doc.ip,
|
ip: doc.ip,
|
||||||
updateAt: doc.update_at,
|
updateAt: doc.update_at,
|
||||||
parentType: TYPE[doc.parentType],
|
parentType: TYPE[doc.parent_doc_type],
|
||||||
parentId: doc.parentId,
|
parentId: doc.parent_doc_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return discussions;
|
return discussions;
|
||||||
@@ -123,8 +123,23 @@ const tasks = {
|
|||||||
owner: doc.owner_uid,
|
owner: doc.owner_uid,
|
||||||
ip: doc.ip,
|
ip: doc.ip,
|
||||||
content: doc.content,
|
content: doc.content,
|
||||||
parentId: doc.parent_doc_id,
|
did: doc.parent_doc_id,
|
||||||
})),
|
})),
|
||||||
|
'discussion.node': async (docs) => {
|
||||||
|
const t = [];
|
||||||
|
for (const doc of docs) {
|
||||||
|
if (doc.domain_id === 'system') {
|
||||||
|
for (const r of doc.content) {
|
||||||
|
const category = r[0];
|
||||||
|
for (const n of r[1]) {
|
||||||
|
t.push(discussion.addNode(n.name, category));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Promise.all(t);
|
||||||
|
return [];
|
||||||
|
},
|
||||||
contest: async (docs) => {
|
contest: async (docs) => {
|
||||||
const RULES = {
|
const RULES = {
|
||||||
2: 'oi',
|
2: 'oi',
|
||||||
@@ -268,6 +283,7 @@ const cursor = {
|
|||||||
solution: (s) => s.collection('document').find({ doc_type: 11 }),
|
solution: (s) => s.collection('document').find({ doc_type: 11 }),
|
||||||
discussion: (s) => s.collection('document').find({ doc_type: 21 }),
|
discussion: (s) => s.collection('document').find({ doc_type: 21 }),
|
||||||
'discussion.reply': (s) => s.collection('document').find({ doc_type: 22 }),
|
'discussion.reply': (s) => s.collection('document').find({ doc_type: 22 }),
|
||||||
|
'discussion.node': (s) => s.collection('document').find({ doc_type: 20 }),
|
||||||
contest: (s) => s.collection('document').find({ doc_type: 30 }),
|
contest: (s) => s.collection('document').find({ doc_type: 30 }),
|
||||||
'contest.status': (s) => s.collection('document.status').find({ doc_type: 30 }),
|
'contest.status': (s) => s.collection('document.status').find({ doc_type: 30 }),
|
||||||
training: (s) => s.collection('document').find({ doc_type: 40 }),
|
training: (s) => s.collection('document').find({ doc_type: 40 }),
|
||||||
@@ -322,15 +338,15 @@ async function migrateVijos({
|
|||||||
}
|
}
|
||||||
const d = [
|
const d = [
|
||||||
'problem', 'problem.status', 'solution', 'discussion', 'discussion.reply',
|
'problem', 'problem.status', 'solution', 'discussion', 'discussion.reply',
|
||||||
'contest', 'training', 'training.status', 'record', 'file',
|
'discussion.node', 'contest', 'training', 'training.status', 'record', 'file',
|
||||||
];
|
];
|
||||||
for (const i of d) {
|
for (const i of d) {
|
||||||
await dst.collection(i).deleteMany();
|
await dst.collection(i).deleteMany();
|
||||||
}
|
}
|
||||||
const t = [
|
const t = [
|
||||||
'user', 'problem', 'problem.status', 'solution', 'discussion',
|
'user', 'problem', 'problem.status', 'solution', 'discussion',
|
||||||
'discussion.reply', 'contest', 'training', 'training.status', 'record',
|
'discussion.reply', 'discussion.node', 'contest', 'training', 'training.status',
|
||||||
'file',
|
'record', 'file',
|
||||||
];
|
];
|
||||||
for (const i of t) await task(i, src, report);
|
for (const i of t) await task(i, src, report);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,9 +117,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% set pdoc=vnode %}
|
{% if vnode.type == 'problem' %}
|
||||||
{% set owner_udoc=udict[vnode['owner']] %}
|
{% set pdoc = vnode %}
|
||||||
{% include "partials/problem_sidebar.html" %}
|
{% set owner_udoc = udict[vnode['owner']] %}
|
||||||
|
{% include "partials/problem_sidebar.html" %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Reference in new issue
Block a user