mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
move to document
This commit is contained in:
5 files changed
+57
-81
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { exec } from 'child_process';
|
||||
import { inspect } from 'util';
|
||||
import * as yaml from 'js-yaml';
|
||||
import { omit } from 'lodash';
|
||||
import { omit, pick } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { Filter, ObjectId } from 'mongodb';
|
||||
import Schema from 'schemastery';
|
||||
@@ -367,7 +367,7 @@ class SystemUserPrivHandler extends SystemHandler {
|
||||
class SystemRejudgeHandler extends SystemHandler {
|
||||
async get() {
|
||||
this.response.body = {
|
||||
rrdocs: await record.getMultiRejudgeTask({}),
|
||||
rrdocs: await record.getMultiRejudgeTask(undefined, {}),
|
||||
apply: true,
|
||||
status: NORMAL_STATUS.filter((i: STATUS) => ![STATUS.STATUS_COMPILE_ERROR, STATUS.STATUS_ACCEPTED].includes(i)).join(','),
|
||||
};
|
||||
@@ -440,7 +440,7 @@ class SystemRejudgeHandler extends SystemHandler {
|
||||
highPriority,
|
||||
apply: _apply,
|
||||
recordLength: rdocs.length,
|
||||
rrdocs: await record.getMultiRejudgeTask({}),
|
||||
rrdocs: await record.getMultiRejudgeTask(undefined, {}),
|
||||
};
|
||||
this.response.template = 'manage_rejudge.html';
|
||||
return;
|
||||
@@ -448,10 +448,19 @@ class SystemRejudgeHandler extends SystemHandler {
|
||||
const rid = await record.addRejudgeTask(domainId, {
|
||||
owner: this.user._id,
|
||||
apply: _apply,
|
||||
rids: rdocs.map((i) => i._id),
|
||||
});
|
||||
const priority = await record.submissionPriority(this.user._id, -10000 - rdocs.length * 5 - 50);
|
||||
await record.reset(domainId, rdocs.map((rdoc) => rdoc._id), true);
|
||||
const priority = await record.submissionPriority(this.user._id, (highPriority ? 0 : -10000) - rdocs.length * 5 - 50);
|
||||
if (_apply) await record.reset(domainId, rdocs.map((rdoc) => rdoc._id), true);
|
||||
else {
|
||||
await record.collHistory.insertMany(rdocs.map((rdoc) => ({
|
||||
...pick(rdoc, [
|
||||
'compilerTexts', 'judgeTexts', 'testCases', 'subtasks',
|
||||
'score', 'time', 'memory', 'status', 'judgeAt', 'judger',
|
||||
]),
|
||||
rid: rdoc._id,
|
||||
_id: new ObjectId(),
|
||||
})));
|
||||
}
|
||||
await Promise.all([
|
||||
record.judge(domainId, rdocs.filter((i) => i.contest).map((i) => i._id), priority, { detail: false },
|
||||
{ rejudge: _apply ? true : 'controlled' }),
|
||||
@@ -465,9 +474,10 @@ class SystemRejudgeHandler extends SystemHandler {
|
||||
class SystemRejudgeDetailHandler extends SystemHandler {
|
||||
@param('rid', Types.ObjectId)
|
||||
async get(domainId: string, rid: ObjectId) {
|
||||
const rrdoc = await record.getRejudgeTask(rid);
|
||||
const rrdoc = await record.getRejudgeTask(domainId, rid);
|
||||
const rdocs = await record.getMulti(domainId, { _id: { $in: rrdoc.rids } }).toArray();
|
||||
if (!rrdoc) throw new RecordNotFoundError(domainId, rid);
|
||||
this.response.body = { rrdoc };
|
||||
this.response.body = { rrdoc, rdocs };
|
||||
this.response.template = 'manage_rejudge_detail.html';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,18 +228,24 @@ export interface RecordStatDoc {
|
||||
lang: string;
|
||||
}
|
||||
|
||||
export interface RecordRejudgeDoc {
|
||||
_id: ObjectId;
|
||||
domainId: string;
|
||||
owner: number;
|
||||
export interface RecordRejudgeDoc extends Document {
|
||||
content: string;
|
||||
docId: ObjectId;
|
||||
docType: document['TYPE_REJUDGE'];
|
||||
apply: boolean;
|
||||
finishAt?: Date;
|
||||
rids: ObjectId[];
|
||||
changes?: {
|
||||
rid: ObjectId;
|
||||
old: number;
|
||||
new: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface RecordRejudgeResultDoc {
|
||||
_id: ObjectId;
|
||||
rrid: ObjectId;
|
||||
rid: ObjectId;
|
||||
oldRev: ObjectId;
|
||||
newRev: ObjectId;
|
||||
oldStatus: number;
|
||||
newStatus: number;
|
||||
oldScore: number;
|
||||
newScore: number;
|
||||
}
|
||||
|
||||
export interface ScoreboardNode {
|
||||
@@ -548,7 +554,7 @@ declare module './service/db' {
|
||||
'record': RecordDoc;
|
||||
'record.stat': RecordStatDoc;
|
||||
'record.history': RecordHistoryDoc;
|
||||
'record.rejudge': RecordRejudgeDoc;
|
||||
'record.rejudge': RecordRejudgeResultDoc;
|
||||
'document': any;
|
||||
'document.status': StatusDocBase & {
|
||||
[K in keyof DocStatusType]: { docType: K } & DocStatusType[K];
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Context } from '../context';
|
||||
import {
|
||||
Content, ContestClarificationDoc, DiscussionDoc,
|
||||
DiscussionReplyDoc, ProblemDoc, ProblemStatusDoc,
|
||||
Tdoc, TrainingDoc,
|
||||
RecordRejudgeDoc, Tdoc, TrainingDoc,
|
||||
} from '../interface';
|
||||
import bus from '../service/bus';
|
||||
import db from '../service/db';
|
||||
@@ -29,6 +29,7 @@ export const TYPE_DISCUSSION_REPLY = 22 as const;
|
||||
export const TYPE_CONTEST = 30 as const;
|
||||
export const TYPE_CONTEST_CLARIFICATION = 31 as const;
|
||||
export const TYPE_TRAINING = 40 as const;
|
||||
export const TYPE_REJUDGE = 50 as const;
|
||||
|
||||
export interface DocType {
|
||||
[TYPE_PROBLEM]: ProblemDoc;
|
||||
@@ -40,6 +41,7 @@ export interface DocType {
|
||||
[TYPE_CONTEST]: Tdoc;
|
||||
[TYPE_CONTEST_CLARIFICATION]: ContestClarificationDoc;
|
||||
[TYPE_TRAINING]: TrainingDoc;
|
||||
[TYPE_REJUDGE]: RecordRejudgeDoc;
|
||||
}
|
||||
|
||||
export interface DocStatusType {
|
||||
@@ -487,5 +489,6 @@ global.Hydro.model.document = {
|
||||
TYPE_PROBLEM,
|
||||
TYPE_PROBLEM_LIST,
|
||||
TYPE_PROBLEM_SOLUTION,
|
||||
TYPE_REJUDGE,
|
||||
TYPE_TRAINING,
|
||||
};
|
||||
@@ -13,6 +13,7 @@ import db from '../service/db';
|
||||
import { MaybeArray, NumberKeys } from '../typeutils';
|
||||
import { ArgMethod, buildProjection, Time } from '../utils';
|
||||
import { STATUS } from './builtin';
|
||||
import * as document from './document';
|
||||
import DomainModel from './domain';
|
||||
import problem from './problem';
|
||||
import task from './task';
|
||||
@@ -282,24 +283,27 @@ export default class RecordModel {
|
||||
return r;
|
||||
}
|
||||
|
||||
static async getMultiRejudgeTask(query: Filter<RecordRejudgeDoc>) {
|
||||
return RecordModel.collRejudge.find(query).toArray();
|
||||
static async getMultiRejudgeTask(domainId: string | undefined, query: Filter<RecordRejudgeDoc>) {
|
||||
return document.getMulti(domainId, document.TYPE_REJUDGE, query).toArray();
|
||||
}
|
||||
|
||||
static async getRejudgeTask(_id: ObjectId) {
|
||||
return RecordModel.collRejudge.findOne({ _id });
|
||||
static async getRejudgeTask(domainId: string, _id: ObjectId) {
|
||||
return document.get(domainId, document.TYPE_REJUDGE, _id);
|
||||
}
|
||||
|
||||
static async addRejudgeTask(domainId: string, doc: Pick<RecordRejudgeDoc, 'owner' | 'apply' | 'rids' | 'changes'>) {
|
||||
const res = await RecordModel.collRejudge.insertOne({ _id: new ObjectId(), domainId, ...doc });
|
||||
return res.insertedId;
|
||||
static async addRejudgeTask(domainId: string, doc: Partial<RecordRejudgeDoc>) {
|
||||
return await document.add(domainId, '', doc.owner, document.TYPE_REJUDGE, null, null, null, doc);
|
||||
}
|
||||
|
||||
static async pushRejudgeResult(rrid: ObjectId, result: { rid: ObjectId, old: number, new: number }) {
|
||||
static async pushRejudgeResult(rrid: ObjectId, newStatus: number, newScore: number, newRev) {
|
||||
await RecordModel.collRejudge.updateOne({ _id: rrid }, {
|
||||
$push: {
|
||||
changes: result,
|
||||
$set: {
|
||||
newStatus,
|
||||
newScore,
|
||||
newRev,
|
||||
},
|
||||
}, {
|
||||
upsert: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -349,6 +353,10 @@ export async function apply(ctx: Context) {
|
||||
RecordModel.collHistory,
|
||||
{ key: { rid: 1, _id: -1 }, name: 'basic' },
|
||||
),
|
||||
db.ensureIndexes(
|
||||
RecordModel.collRejudge,
|
||||
{ key: { domainId: 1, rrid: 1, rid: 1 }, name: 'basic' },
|
||||
),
|
||||
]);
|
||||
}
|
||||
global.Hydro.model.record = RecordModel;
|
||||
@@ -1,51 +0,0 @@
|
||||
import { Filter, ObjectId } from 'mongodb';
|
||||
import Schema from 'schemastery';
|
||||
import { Context } from '../context';
|
||||
import { RecordDoc } from '../interface';
|
||||
import { STATUS, STATUS_SHORT_TEXTS } from '../model/builtin';
|
||||
import record from '../model/record';
|
||||
|
||||
export const apply = (ctx: Context) => ctx.addScript(
|
||||
'rejudge', 'rejudge with filter',
|
||||
Schema.object({
|
||||
rrid: Schema.string(),
|
||||
domainId: Schema.string(),
|
||||
uid: Schema.number(),
|
||||
pid: Schema.number(),
|
||||
contest: Schema.string(),
|
||||
lang: Schema.string(),
|
||||
status: Schema.number(),
|
||||
apply: Schema.boolean(),
|
||||
}),
|
||||
async (arg, report) => {
|
||||
const q: Filter<RecordDoc> = { 'files.hack': { $exists: false } };
|
||||
for (const key of ['domainId', 'uid', 'pid', 'contest', 'lang', 'status']) {
|
||||
if (arg[key]) q[key] = arg[key];
|
||||
}
|
||||
q.contest ||= { $nin: [record.RECORD_GENERATE, record.RECORD_PRETEST] };
|
||||
q.status ||= { $ne: STATUS.STATUS_CANCELED };
|
||||
const rdocs = await record.getMulti(arg.domainId, q).project({ _id: 1, contest: 1, status: 1 }).toArray();
|
||||
const rdict = new Map(rdocs.map((rdoc) => [rdoc._id, rdoc.status]));
|
||||
report({ message: `Found ${rdocs.length} records` });
|
||||
ctx.on('record/change', async (rdoc: RecordDoc) => {
|
||||
if (rdict.has(rdoc._id)) {
|
||||
rdict.delete(rdoc._id);
|
||||
report({ message: `Rejudged ${rdoc._id}, ${STATUS_SHORT_TEXTS[rdict.get(rdoc._id)]} -> ${STATUS_SHORT_TEXTS[rdoc.status]}` });
|
||||
await record.pushRejudgeResult(new ObjectId(arg.rrid), { rid: rdoc._id, old: rdict.get(rdoc._id), new: rdoc.status });
|
||||
}
|
||||
});
|
||||
if (rdocs.length) {
|
||||
const priority = await record.submissionPriority(1, -10000 - rdocs.length * 5 - 50);
|
||||
if (arg.apply) {
|
||||
await record.reset(arg.domainId, rdocs.map((rdoc) => rdoc._id), true);
|
||||
}
|
||||
await Promise.all([
|
||||
record.judge(arg.domainId, rdocs.filter((i) => i.contest).map((i) => i._id),
|
||||
priority, { detail: false }, { rejudge: arg.apply ? true : 'controlled' }),
|
||||
record.judge(arg.domainId, rdocs.filter((i) => !i.contest).map((i) => i._id),
|
||||
priority, {}, { rejudge: arg.apply ? true : 'controlled' }),
|
||||
]);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user