mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: 保留比赛题目顺序
This commit is contained in:
1 parent
41219ef147
commit
6dfeede6d6
5 files changed
+25
-26
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydrooj",
|
"name": "hydrooj",
|
||||||
"version": "2.26.11",
|
"version": "2.26.12",
|
||||||
"bin": "bin/hydrooj.js",
|
"bin": "bin/hydrooj.js",
|
||||||
"main": "dist/loader.js",
|
"main": "dist/loader.js",
|
||||||
"typings": "dist/loader.d.ts",
|
"typings": "dist/loader.d.ts",
|
||||||
|
|||||||
@@ -214,10 +214,11 @@ class ContestEditHandler extends Handler {
|
|||||||
domainId: string, beginAtDate: string, beginAtTime: string, duration: number,
|
domainId: string, beginAtDate: string, beginAtTime: string, duration: number,
|
||||||
title: string, content: string, rule: string, _pids: string, rated = false,
|
title: string, content: string, rule: string, _pids: string, rated = false,
|
||||||
) {
|
) {
|
||||||
let pids = _pids.replace(/,/g, ',').split(',').map((i) => {
|
const pids = _pids.replace(/,/g, ',').split(',').map((i) => {
|
||||||
if (isSafeInteger(parseInt(i, 10))) return parseInt(i, 10);
|
if (isSafeInteger(parseInt(i, 10))) return parseInt(i, 10);
|
||||||
return i;
|
return i;
|
||||||
});
|
});
|
||||||
|
await problem.getList(domainId, pids, this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN), false);
|
||||||
const beginAtMoment = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone);
|
const beginAtMoment = moment.tz(`${beginAtDate} ${beginAtTime}`, this.user.timeZone);
|
||||||
if (!beginAtMoment.isValid()) {
|
if (!beginAtMoment.isValid()) {
|
||||||
throw new ValidationError('beginAtDate', 'beginAtTime');
|
throw new ValidationError('beginAtDate', 'beginAtTime');
|
||||||
@@ -225,7 +226,6 @@ class ContestEditHandler extends Handler {
|
|||||||
const endAt = beginAtMoment.clone().add(duration, 'hours').toDate();
|
const endAt = beginAtMoment.clone().add(duration, 'hours').toDate();
|
||||||
if (beginAtMoment.isSameOrAfter(endAt)) throw new ValidationError('duration');
|
if (beginAtMoment.isSameOrAfter(endAt)) throw new ValidationError('duration');
|
||||||
const beginAt = beginAtMoment.toDate();
|
const beginAt = beginAtMoment.toDate();
|
||||||
pids = await contest.verifyProblems(domainId, pids);
|
|
||||||
await contest.edit(domainId, this.tdoc.docId, {
|
await contest.edit(domainId, this.tdoc.docId, {
|
||||||
title, content, rule, beginAt, endAt, pids, rated,
|
title, content, rule, beginAt, endAt, pids, rated,
|
||||||
});
|
});
|
||||||
@@ -429,7 +429,7 @@ class ContestCreateHandler extends Handler {
|
|||||||
domainId: string, beginAtDate: string, beginAtTime: string, duration: number,
|
domainId: string, beginAtDate: string, beginAtTime: string, duration: number,
|
||||||
title: string, content: string, rule: string, _pids: string, rated = false,
|
title: string, content: string, rule: string, _pids: string, rated = false,
|
||||||
) {
|
) {
|
||||||
let pids = _pids.replace(/,/g, ',').split(',').map((i) => {
|
const pids = _pids.replace(/,/g, ',').split(',').map((i) => {
|
||||||
if (isSafeInteger(parseInt(i, 10))) return parseInt(i, 10);
|
if (isSafeInteger(parseInt(i, 10))) return parseInt(i, 10);
|
||||||
return i;
|
return i;
|
||||||
});
|
});
|
||||||
@@ -438,7 +438,7 @@ class ContestCreateHandler extends Handler {
|
|||||||
throw new ValidationError('beginAtDate', 'beginAtTime');
|
throw new ValidationError('beginAtDate', 'beginAtTime');
|
||||||
}
|
}
|
||||||
const endAt = beginAt.clone().add(duration, 'hours');
|
const endAt = beginAt.clone().add(duration, 'hours');
|
||||||
pids = await contest.verifyProblems(domainId, pids);
|
await problem.getList(domainId, pids, this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN), false);
|
||||||
const tid = await contest.add(
|
const tid = await contest.add(
|
||||||
domainId, title, content,
|
domainId, title, content,
|
||||||
this.user._id, rule, beginAt.toDate(), endAt.toDate(), pids, rated,
|
this.user._id, rule, beginAt.toDate(), endAt.toDate(), pids, rated,
|
||||||
|
|||||||
@@ -257,9 +257,9 @@ class HomeworkCreateHandler extends Handler {
|
|||||||
const endAt = penaltySince.clone().add(extensionDays, 'days');
|
const endAt = penaltySince.clone().add(extensionDays, 'days');
|
||||||
if (beginAt.isSameOrAfter(penaltySince)) throw new ValidationError('endAtDate', 'endAtTime');
|
if (beginAt.isSameOrAfter(penaltySince)) throw new ValidationError('endAtDate', 'endAtTime');
|
||||||
if (penaltySince.isAfter(endAt)) throw new ValidationError('extensionDays');
|
if (penaltySince.isAfter(endAt)) throw new ValidationError('extensionDays');
|
||||||
const verified = await contest.verifyProblems(domainId, pids);
|
await problem.getList(domainId, pids, this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN), false);
|
||||||
const tid = await contest.add(domainId, title, content, this.user._id,
|
const tid = await contest.add(domainId, title, content, this.user._id,
|
||||||
'homework', beginAt.toDate(), endAt.toDate(), verified, rated,
|
'homework', beginAt.toDate(), endAt.toDate(), pids, rated,
|
||||||
{ penaltySince: penaltySince.toDate(), penaltyRules }, document.TYPE_HOMEWORK);
|
{ penaltySince: penaltySince.toDate(), penaltyRules }, document.TYPE_HOMEWORK);
|
||||||
this.response.body = { tid };
|
this.response.body = { tid };
|
||||||
this.response.redirect = this.url('homework_detail', { tid });
|
this.response.redirect = this.url('homework_detail', { tid });
|
||||||
@@ -334,17 +334,17 @@ class HomeworkEditHandler extends Handler {
|
|||||||
}
|
}
|
||||||
let endAt = penaltySince.clone().add(extensionDays, 'days');
|
let endAt = penaltySince.clone().add(extensionDays, 'days');
|
||||||
if (beginAt.isSameOrAfter(penaltySince)) throw new ValidationError('endAtDate', 'endAtTime');
|
if (beginAt.isSameOrAfter(penaltySince)) throw new ValidationError('endAtDate', 'endAtTime');
|
||||||
const verified = await contest.verifyProblems(domainId, pids);
|
await problem.getList(domainId, pids, this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN), false);
|
||||||
beginAt = beginAt.toDate();
|
beginAt = beginAt.toDate();
|
||||||
endAt = endAt.toDate();
|
endAt = endAt.toDate();
|
||||||
penaltySince = penaltySince.toDate();
|
penaltySince = penaltySince.toDate();
|
||||||
await contest.edit(domainId, tid, {
|
await contest.edit(domainId, tid, {
|
||||||
title, content, beginAt, endAt, pids: verified, penaltySince, penaltyRules, rated,
|
title, content, beginAt, endAt, pids, penaltySince, penaltyRules, rated,
|
||||||
}, document.TYPE_HOMEWORK);
|
}, document.TYPE_HOMEWORK);
|
||||||
if (tdoc.beginAt !== beginAt
|
if (tdoc.beginAt !== beginAt
|
||||||
|| tdoc.endAt !== endAt
|
|| tdoc.endAt !== endAt
|
||||||
|| tdoc.penaltySince !== penaltySince
|
|| tdoc.penaltySince !== penaltySince
|
||||||
|| tdoc.pids.sort().join(' ') !== verified.sort().join(' ')) {
|
|| tdoc.pids.sort().join(' ') !== pids.sort().join(' ')) {
|
||||||
await contest.recalcStatus(domainId, tdoc.docId, document.TYPE_HOMEWORK);
|
await contest.recalcStatus(domainId, tdoc.docId, document.TYPE_HOMEWORK);
|
||||||
}
|
}
|
||||||
this.response.body = { tid };
|
this.response.body = { tid };
|
||||||
|
|||||||
@@ -569,22 +569,15 @@ export async function getScoreboard(
|
|||||||
const tdoc = await get(domainId, tid, docType);
|
const tdoc = await get(domainId, tid, docType);
|
||||||
if (!canShowScoreboard.call(this, tdoc)) throw new ContestScoreboardHiddenError(tid);
|
if (!canShowScoreboard.call(this, tdoc)) throw new ContestScoreboardHiddenError(tid);
|
||||||
if (!canShowRecord.call(this, tdoc)) throw new ContestScoreboardHiddenError(tid);
|
if (!canShowRecord.call(this, tdoc)) throw new ContestScoreboardHiddenError(tid);
|
||||||
const tsdocs = await getMultiStatus(domainId, { docId: tid }, docType).sort(RULES[tdoc.rule].statusSort);
|
const tsdocsCursor = getMultiStatus(domainId, { docId: tid }, docType).sort(RULES[tdoc.rule].statusSort);
|
||||||
const pdict = await problem.getList(domainId, tdoc.pids, true);
|
const pdict = await problem.getList(domainId, tdoc.pids, true);
|
||||||
const [rows, udict, nPages] = await RULES[tdoc.rule].scoreboard(
|
const [rows, udict, nPages] = await RULES[tdoc.rule].scoreboard(
|
||||||
isExport, this.translate.bind(this),
|
isExport, this.translate.bind(this),
|
||||||
tdoc, pdict, tsdocs, page,
|
tdoc, pdict, tsdocsCursor, page,
|
||||||
);
|
);
|
||||||
return [tdoc, rows, udict, pdict, nPages];
|
return [tdoc, rows, udict, pdict, nPages];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function verifyProblems(domainId: string, pids: Array<number | string>) {
|
|
||||||
const pdict = await problem.getList(domainId, pids, true);
|
|
||||||
const _pids: Set<number> = new Set();
|
|
||||||
for (const i in pdict) _pids.add(pdict[i].docId);
|
|
||||||
return Array.from(_pids);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const statusText = (tdoc: Tdoc) => (
|
export const statusText = (tdoc: Tdoc) => (
|
||||||
isNew(tdoc)
|
isNew(tdoc)
|
||||||
? 'New'
|
? 'New'
|
||||||
@@ -621,7 +614,6 @@ global.Hydro.model.contest = {
|
|||||||
canShowScoreboard,
|
canShowScoreboard,
|
||||||
canViewHiddenScoreboard,
|
canViewHiddenScoreboard,
|
||||||
getScoreboard,
|
getScoreboard,
|
||||||
verifyProblems,
|
|
||||||
isNew,
|
isNew,
|
||||||
isUpcoming,
|
isUpcoming,
|
||||||
isNotStarted,
|
isNotStarted,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { escapeRegExp } from 'lodash';
|
|||||||
import { ItemBucketMetadata } from 'minio';
|
import { ItemBucketMetadata } from 'minio';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import type { Readable } from 'stream';
|
import type { Readable } from 'stream';
|
||||||
|
import TaskModel from './task';
|
||||||
import storage from '../service/storage';
|
import storage from '../service/storage';
|
||||||
import * as bus from '../service/bus';
|
import * as bus from '../service/bus';
|
||||||
import db from '../service/db';
|
import db from '../service/db';
|
||||||
@@ -76,19 +77,25 @@ export class StorageModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clean() {
|
async function cleanFiles() {
|
||||||
let res = await StorageModel.coll.findOneAndDelete({ autoDelete: { $lte: new Date() } });
|
let res = await StorageModel.coll.findOneAndDelete({ autoDelete: { $lte: new Date() } });
|
||||||
while (res.value) {
|
while (res.value) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
// await storage.del(res.value._id);
|
await storage.del(res.value._id);
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
res = await StorageModel.coll.findOneAndDelete({ autoDelete: { $lte: new Date() } });
|
res = await StorageModel.coll.findOneAndDelete({ autoDelete: { $lte: new Date() } });
|
||||||
}
|
}
|
||||||
setTimeout(clean, 10000);
|
|
||||||
}
|
}
|
||||||
bus.on('app/started', () => {
|
TaskModel.Worker.addHandler('storage.prune', cleanFiles);
|
||||||
clean();
|
bus.once('app/started', async () => {
|
||||||
return StorageModel.coll.createIndex({ path: 1 }, { unique: true });
|
if (!await TaskModel.count({ type: 'schedule', subType: 'storage.prune' })) {
|
||||||
|
await TaskModel.add({
|
||||||
|
type: 'schedule',
|
||||||
|
subType: 'storage.prune',
|
||||||
|
executeAfter: moment().minute(0).second(0).millisecond(0).toDate(),
|
||||||
|
interval: [1, 'hour'],
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
global.Hydro.model.storage = StorageModel;
|
global.Hydro.model.storage = StorageModel;
|
||||||
|
|||||||
Reference in new issue
Block a user