mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 17:38:19 +08:00
bug fix
This commit is contained in:
1 parent
2b6a510c1e
commit
f2bcc3bc93
23 files changed
+241
-119
No files matched your search
+46
-11
@@ -10,6 +10,7 @@ const misc = require('../lib/misc');
|
||||
const md5 = require('../lib/md5');
|
||||
const contest = require('../model/contest');
|
||||
const message = require('../model/message');
|
||||
const document = require('../model/document');
|
||||
const system = require('../model/system');
|
||||
const user = require('../model/user');
|
||||
const setting = require('../model/setting');
|
||||
@@ -18,12 +19,26 @@ const token = require('../model/token');
|
||||
const training = require('../model/training');
|
||||
const {
|
||||
PERM_VIEW_TRAINING, PERM_VIEW_CONTEST, PERM_VIEW_DISCUSSION,
|
||||
PERM_LOGGEDIN,
|
||||
PERM_LOGGEDIN, PERM_VIEW_HOMEWORK,
|
||||
} = require('../permission');
|
||||
|
||||
const { geoip, useragent } = global.Hydro.lib;
|
||||
|
||||
class HomeHandler extends Handler {
|
||||
async homework(domainId) {
|
||||
if (this.user.hasPerm(PERM_VIEW_HOMEWORK)) {
|
||||
const tdocs = await contest.getMulti(domainId, {}, document.TYPE_HOMEWORK)
|
||||
.limit(await system.get('HOMEWORK_ON_MAIN'))
|
||||
.toArray();
|
||||
const tsdict = await contest.getListStatus(
|
||||
domainId, this.user._id,
|
||||
tdocs.map((tdoc) => tdoc.docId), document.TYPE_HOMEWORK,
|
||||
);
|
||||
return [tdocs, tsdict];
|
||||
}
|
||||
return [[], {}];
|
||||
}
|
||||
|
||||
async contest(domainId) {
|
||||
if (this.user.hasPerm(PERM_VIEW_CONTEST)) {
|
||||
const tdocs = await contest.getMulti(domainId)
|
||||
@@ -63,13 +78,17 @@ class HomeHandler extends Handler {
|
||||
}
|
||||
|
||||
async get({ domainId }) {
|
||||
const [[tdocs, tsdict], [trdocs, trsdict], [ddocs, vndict]] = await Promise.all([
|
||||
this.contest(domainId), this.training(domainId), this.discussion(domainId),
|
||||
const [
|
||||
[htdocs, htsdict], [tdocs, tsdict],
|
||||
[trdocs, trsdict], [ddocs, vndict],
|
||||
] = await Promise.all([
|
||||
this.homework(domainId), this.contest(domainId),
|
||||
this.training(domainId), this.discussion(domainId),
|
||||
]);
|
||||
const udict = await user.getList(domainId, ddocs.map((ddoc) => ddoc.owner));
|
||||
this.response.template = 'main.html';
|
||||
this.response.body = {
|
||||
tdocs, tsdict, trdocs, trsdict, ddocs, vndict, udict,
|
||||
htdocs, htsdict, tdocs, tsdict, trdocs, trsdict, ddocs, vndict, udict,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -190,21 +209,37 @@ class HomeMessagesHandler extends Handler {
|
||||
|
||||
async get() {
|
||||
// TODO(iceboy): projection, pagination.
|
||||
const mdocs = await message.getMulti(this.user._id).sort('_id', -1).limit(50).toArray();
|
||||
const messages = await message.getByUser(this.user._id);
|
||||
const udict = await user.getList([
|
||||
...mdocs.map((mdoc) => mdoc.from),
|
||||
...mdocs.map((mdoc) => mdoc.to),
|
||||
...messages.map((mdoc) => mdoc.from),
|
||||
...messages.map((mdoc) => mdoc.to),
|
||||
]);
|
||||
// TODO(twd2): improve here:
|
||||
for (const mdoc of mdocs) {
|
||||
this.udoc(udict, mdoc.from);
|
||||
this.udoc(udict, mdoc.to);
|
||||
const parsed = {};
|
||||
for (const m of messages) {
|
||||
if (m.from === this.user._id) {
|
||||
if (!parsed[m.to]) {
|
||||
parsed[m.to] = {
|
||||
udoc: { ...udict[m.to], gravatar: misc.gravatar(udict[m.to].gravatar) },
|
||||
messages: [],
|
||||
};
|
||||
}
|
||||
parsed[m.to].messages.push(m);
|
||||
} else {
|
||||
if (!parsed[m.from]) {
|
||||
parsed[m.from] = {
|
||||
udoc: { ...udict[m.from], gravatar: misc.gravatar(udict[m.from].gravatar) },
|
||||
messages: [],
|
||||
};
|
||||
}
|
||||
parsed[m.from].messages.push(m);
|
||||
}
|
||||
}
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['home_messages', null],
|
||||
];
|
||||
this.response.body = { messages: mdocs, udict, path };
|
||||
this.response.body = { messages, udict, path };
|
||||
this.response.template = 'home_messages.html';
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ class HomeworkMainHandler extends HomeworkHandler {
|
||||
const tdocs = await contest.getMulti(domainId, {}, document.TYPE_HOMEWORK).toArray();
|
||||
const calendar = [];
|
||||
for (const tdoc of tdocs) {
|
||||
console.log(tdoc);
|
||||
const cal = { ...tdoc };
|
||||
const cal = { ...tdoc, url: `/homework/${tdoc.docId}` };
|
||||
if (contest.isHomeworkExtended(tdoc) || contest.isDone(tdoc)) {
|
||||
cal.endAt = tdoc.endAt;
|
||||
cal.penaltySince = tdoc.penaltySince;
|
||||
@@ -37,7 +36,11 @@ class HomeworkMainHandler extends HomeworkHandler {
|
||||
}
|
||||
calendar.push(cal);
|
||||
}
|
||||
this.response.body = { tdocs, calendar };
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['homework_main', null],
|
||||
];
|
||||
this.response.body = { tdocs, calendar, path };
|
||||
this.response.template = 'homework_main.html';
|
||||
}
|
||||
}
|
||||
@@ -76,6 +79,7 @@ class HomeworkDetailHandler extends HomeworkHandler {
|
||||
uids.push(tdoc.owner);
|
||||
const udict = await user.getList(domainId, uids);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['homework_main', '/homework'],
|
||||
[tdoc.title, null, true],
|
||||
];
|
||||
@@ -113,6 +117,7 @@ class HomeworkDetailProblemHandler extends HomeworkHandler {
|
||||
}
|
||||
if (!this.tdoc.pids.includes(pid)) throw new ProblemNotFoundError(domainId, pid, tid);
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['homework_main', '/homework'],
|
||||
[this.tdoc.title, `/homework/${tid}`, true],
|
||||
[this.pdoc.title, null, true],
|
||||
@@ -136,6 +141,7 @@ class HomeworkDetailProblemSubmitHandler extends HomeworkDetailProblemHandler {
|
||||
.sort('_id', -1).limit(10).toArray()
|
||||
: [];
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['homework_main', '/homework'],
|
||||
[this.tdoc.title, `/homework/${tid}`, true],
|
||||
[this.pdoc.title, `/homework/${tid}/p/${pid}`, true],
|
||||
@@ -162,6 +168,7 @@ class HomeworkDetailProblemSubmitHandler extends HomeworkDetailProblemHandler {
|
||||
rid, pid, false, 0, document.TYPE_HOMEWORK);
|
||||
this.response.body = { tid, rid };
|
||||
if (this.canShowRecord(this.tdoc)) this.response.redirect = `/record/${rid}`;
|
||||
else this.response.redirect = `/homework/${tid}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +177,8 @@ class HomeworkCreateHandler extends HomeworkHandler {
|
||||
const beginAt = new Date().delta({ day: 1 });
|
||||
const penaltySince = beginAt.delta({ day: 7 });
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['homework_main', '/homework'],
|
||||
['homework_create', null],
|
||||
];
|
||||
this.response.template = 'homework_edit.html';
|
||||
@@ -221,6 +230,7 @@ class HomeworkEditHandler extends HomeworkHandler {
|
||||
(tdoc.endAt.getTime() - tdoc.penaltySince.getTime()) / 36000 / 24,
|
||||
) / 100;
|
||||
const path = [
|
||||
['Hydro', '/'],
|
||||
['homework_main', '/homework'],
|
||||
[tdoc.title, `/homework/${tid}`, true],
|
||||
['homework_edit', null],
|
||||
@@ -353,6 +363,7 @@ async function apply() {
|
||||
{ type: 'total_time', value: _('Total Time (Seconds)') },
|
||||
);
|
||||
}
|
||||
columns.push({ type: 'total_time_str', value: _('Total Time') });
|
||||
for (const index in tdoc.pids) {
|
||||
const pid = tdoc.pids[index];
|
||||
if (isExport) {
|
||||
@@ -383,14 +394,13 @@ async function apply() {
|
||||
}
|
||||
}
|
||||
const rows = [columns];
|
||||
for (const rank in rankedTsdocs) {
|
||||
const tsdoc = rankedTsdocs[rank];
|
||||
for (const [rank, tsdoc] of rankedTsdocs) {
|
||||
const tsddict = {};
|
||||
for (const item of tsdoc.journal || []) {
|
||||
tsddict[item.pid] = item;
|
||||
}
|
||||
const row = [
|
||||
{ type: 'string', value: rank + 1 },
|
||||
{ type: 'string', value: rank },
|
||||
{
|
||||
type: 'user',
|
||||
value: udict[tsdoc.uid].uname,
|
||||
@@ -411,7 +421,7 @@ async function apply() {
|
||||
const colScore = (tsddict[pid] || {}).penaltyScore || '-';
|
||||
const colOriginalScore = (tsddict[pid] || {}).score || '-';
|
||||
const colTime = (tsddict[pid] || {}).time || '-';
|
||||
const colTimeStr = colTime !== '-' ? misc.formatSeconds(colTime) : '-';
|
||||
const colTimeStr = colTime !== '-' ? misc.formatSeconds(colTime || 0) : '-';
|
||||
if (isExport) {
|
||||
row.push(
|
||||
{ type: 'string', value: colScore },
|
||||
@@ -431,7 +441,7 @@ async function apply() {
|
||||
}
|
||||
return rows;
|
||||
},
|
||||
rank: (tdocs) => ranked(tdocs, (a, b) => a.score === b.score),
|
||||
rank: (tsdocs) => ranked(tsdocs, (a, b) => a.score === b.score),
|
||||
};
|
||||
Route('/homework', HomeworkMainHandler, PERM_VIEW_HOMEWORK);
|
||||
Route('/homework/create', HomeworkCreateHandler, PERM_CREATE_HOMEWORK);
|
||||
|
||||
+37
-20
@@ -1,7 +1,5 @@
|
||||
const {
|
||||
PERM_READ_RECORD_CODE, PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD,
|
||||
PERM_REJUDGE, PERM_VIEW_PROBLEM_HIDDEN,
|
||||
} = require('../permission');
|
||||
const { PERM_READ_RECORD_CODE, PERM_REJUDGE, PERM_VIEW_PROBLEM_HIDDEN } = require('../permission');
|
||||
const { PermissionError } = require('../error');
|
||||
const problem = require('../model/problem');
|
||||
const record = require('../model/record');
|
||||
const contest = require('../model/contest');
|
||||
@@ -20,7 +18,12 @@ class RecordListHandler extends RecordHandler {
|
||||
}) {
|
||||
this.response.template = 'record_main.html';
|
||||
const q = { tid };
|
||||
if (uname_or_uid) q.$or = [{ unameLower: uname_or_uid.toLowerCase() }, { _id: parseInt(uname_or_uid) }];
|
||||
if (uname_or_uid) {
|
||||
q.$or = [
|
||||
{ unameLower: uname_or_uid.toLowerCase() },
|
||||
{ _id: parseInt(uname_or_uid) },
|
||||
];
|
||||
}
|
||||
const rdocs = await record.getMany(domainId, q, { _id: -1 }, page, await system.get('RECORD_PER_PAGE'));
|
||||
const [udict, pdict] = await Promise.all([
|
||||
user.getList(domainId, rdocs.map((rdoc) => rdoc.uid)),
|
||||
@@ -73,16 +76,30 @@ class RecordRejudgeHandler extends Handler {
|
||||
}
|
||||
}
|
||||
|
||||
class RecordConnectionHandler extends ConnectionHandler {
|
||||
async prepare({ domainId }) {
|
||||
const RecordConnectionHandler = contest.ContestHandlerMixin(ConnectionHandler);
|
||||
|
||||
class RecordMainConnectionHandler extends RecordConnectionHandler {
|
||||
async prepare({ domainId, tid }) {
|
||||
this.domainId = domainId;
|
||||
if (tid) {
|
||||
const tdoc = await contest.get(domainId, tid, -1);
|
||||
if (this.canShowRecord(tdoc)) this.tid = tid;
|
||||
else {
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
bus.subscribe(['record_change'], this.onRecordChange);
|
||||
}
|
||||
|
||||
async message(msg) {
|
||||
for (const rid of msg.rids) {
|
||||
const rdoc = await record.get(this.domainId, rid); // eslint-disable-line no-await-in-loop
|
||||
await this.onRecordChange({ value: rdoc }); // eslint-disable-line no-await-in-loop
|
||||
const rdocs = await record.getMany(
|
||||
this.domainId,
|
||||
{ _id: { $in: msg.rids } },
|
||||
{ _id: -1 }, 1, 100,
|
||||
);
|
||||
for (const rdoc of rdocs) {
|
||||
this.onRecordChange({ value: rdoc });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +124,7 @@ class RecordDetailConnectionHandler extends contest.ContestHandlerMixin(Connecti
|
||||
async prepare({ domainId, rid }) {
|
||||
const rdoc = await record.get(domainId, rid);
|
||||
if (rdoc.tid) {
|
||||
const tdoc = await contest.get(domainId, rdoc.tid);
|
||||
const tdoc = await contest.get(domainId, rdoc.tid, -1);
|
||||
if (!this.canShowRecord(tdoc)) {
|
||||
this.close();
|
||||
return;
|
||||
@@ -133,21 +150,21 @@ class RecordDetailConnectionHandler extends contest.ContestHandlerMixin(Connecti
|
||||
}
|
||||
|
||||
async function apply() {
|
||||
Route('/r', module.exports.RecordListHandler);
|
||||
Route('/r/:rid', module.exports.RecordDetailHandler);
|
||||
Route('/r/:rid/rejudge', module.exports.RecordRejudgeHandler);
|
||||
Route('/record', module.exports.RecordListHandler);
|
||||
Route('/record/:rid', module.exports.RecordDetailHandler);
|
||||
Route('/record/:rid/rejudge', module.exports.RecordRejudgeHandler);
|
||||
Connection('/record-conn', module.exports.RecordConnectionHandler);
|
||||
Connection('/record-detail-conn', module.exports.RecordDetailConnectionHandler);
|
||||
Route('/r', RecordListHandler);
|
||||
Route('/r/:rid', RecordDetailHandler);
|
||||
Route('/r/:rid/rejudge', RecordRejudgeHandler);
|
||||
Route('/record', RecordListHandler);
|
||||
Route('/record/:rid', RecordDetailHandler);
|
||||
Route('/record/:rid/rejudge', RecordRejudgeHandler);
|
||||
Connection('/record-conn', RecordMainConnectionHandler);
|
||||
Connection('/record-detail-conn', RecordDetailConnectionHandler);
|
||||
}
|
||||
|
||||
global.Hydro.handler.record = module.exports = {
|
||||
RecordListHandler,
|
||||
RecordDetailHandler,
|
||||
RecordRejudgeHandler,
|
||||
RecordConnectionHandler,
|
||||
RecordMainConnectionHandler,
|
||||
RecordDetailConnectionHandler,
|
||||
apply,
|
||||
};
|
||||
Reference in new issue
Block a user