Skip to content

Commit

Permalink
add handler
Browse files Browse the repository at this point in the history
  • Loading branch information
pandadtdyy committed Oct 11, 2023
1 parent 4c52342 commit 030c8e7
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 15 deletions.
30 changes: 22 additions & 8 deletions packages/hydrooj/src/handler/contest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { pick } from 'lodash';
import moment from 'moment-timezone';
import { ObjectId } from 'mongodb';
import {
Counter, sortFiles, streamToBuffer, Time,
Counter, sortFiles, streamToBuffer, Time, yaml,
} from '@hydrooj/utils/lib/utils';
import {
BadRequestError, ContestNotAttendedError, ContestNotEndedError, ContestNotFoundError, ContestNotLiveError,
Expand Down Expand Up @@ -666,13 +666,13 @@ export class ContestUserHandler extends ContestManagementBaseHandler {

export class ContestBalloonHandler extends ContestManagementBaseHandler {
@param('tid', Types.ObjectId)
@param('unsent', Types.Boolean)
async get(domainId: string, tid: ObjectId, unsent = false) {
@param('todo', Types.Boolean)
async get(domainId: string, tid: ObjectId, todo = false) {
const bdocs = await contest.getMultiBalloon(domainId, tid, {
...unsent ? { sent: { $exists: false } } : {},
...todo ? { sent: { $exists: false } } : {},
...(!this.tdoc.lockAt || !(this.user.own(this.tdoc) || this.user.hasPerm(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD)))
? {} : { rid: { $lt: this.tdoc.lockAt } },
}).toArray();
}).sort({ bid: -1 }).toArray();
const uids = [...bdocs.map((i) => i.uid), ...bdocs.filter((i) => i.sent).map((i) => i.sent)];
const udict = await user.getListForRender(domainId, uids);
this.response.body = { bdocs, udict };
Expand All @@ -681,9 +681,23 @@ export class ContestBalloonHandler extends ContestManagementBaseHandler {
}

@param('tid', Types.ObjectId)
@param('balloons', Types.ArrayOf(Types.ObjectId))
async postSendBalloon(domainId: string, tid: ObjectId, balloons: ObjectId[]) {
await Promise.all(balloons.map((bid) => contest.updateBalloon(domainId, tid, bid, { sent: this.user._id, sentAt: new Date() })));
@param('color', Types.Content)
async postSetColor(domainId: string, tid: ObjectId, color: string) {
const config = yaml.load(color);
if (typeof config !== 'object') throw new ValidationError('color');
const balloon = {};
this.tdoc.pids.forEach((pid) => {
if (!config[pid]) throw new ValidationError('color');
balloon[pid] = config[pid.toString()];
});
await contest.edit(domainId, tid, { balloon });
this.back();
}

@param('tid', Types.ObjectId)
@param('balloon', Types.PositiveInt)
async postDone(domainId: string, tid: ObjectId, bid: number) {
await contest.updateBalloon(domainId, tid, bid, { sent: this.user._id, sentAt: new Date() });
this.back();
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/hydrooj/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ export interface ContestBalloonDoc {
_id: ObjectId;
domainId: string;
tid: ObjectId;
bid: number;
pid: number;
uid: number;
first?: boolean;
Expand Down
28 changes: 21 additions & 7 deletions packages/hydrooj/src/model/contest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ export async function updateStatus(
) {
const tdoc = await get(domainId, tid);
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (status === STATUS.STATUS_ACCEPTED && updated && tdoc.balloon) addBalloon(domainId, tid, uid, rid, pid);
if (tdoc.balloon && status === STATUS.STATUS_ACCEPTED && updated) await addBalloon(domainId, tid, uid, rid, pid);
return await _updateStatus(tdoc, uid, rid, pid, status, score, subtasks);
}

Expand Down Expand Up @@ -763,19 +763,28 @@ export async function addBalloon(domainId: string, tid: ObjectId, uid: number, r
});
if (balloon) return null;
const bdcount = await collBalloon.countDocuments({ domainId, tid, pid });
const bdoc = {
_id: new ObjectId(), domainId, tid, pid, uid, rid, ...(!bdcount ? { first: true } : {}),
const [bdoc] = await collBalloon.find({}).sort({ bid: -1 }).limit(1).toArray();
const bid = (bdoc?.bid || 0) + 1;
const newBdoc = {
_id: new ObjectId(), domainId, tid, bid, pid, uid, rid, ...(!bdcount ? { first: true } : {}),
};
bus.broadcast('contest/balloon', domainId, tid, bdoc);
return await collBalloon.insertOne(bdoc);
try {
await collBalloon.insertOne(newBdoc);
bus.broadcast('contest/balloon', domainId, tid, newBdoc);
} catch (e) {
if (e.code === 11000) {
return await addBalloon(domainId, tid, uid, rid, pid);
}
}
return bid;
}

export function getMultiBalloon(domainId: string, tid: ObjectId, query: any = {}) {
return collBalloon.find({ domainId, tid, ...query });
}

export async function updateBalloon(domainId: string, tid: ObjectId, bid: ObjectId, $set: any) {
return await collBalloon.findOneAndUpdate({ domainId, tid, _id: bid }, { $set });
export async function updateBalloon(domainId: string, tid: ObjectId, bid: number, $set: any) {
return await collBalloon.findOneAndUpdate({ domainId, tid, bid }, { $set });
}

export function isNew(tdoc: Tdoc, days = 1) {
Expand Down Expand Up @@ -919,6 +928,11 @@ export const statusText = (tdoc: Tdoc, tsdoc?: any) => (
? 'Live...'
: 'Done');

bus.on('ready', () => db.ensureIndexes(
collBalloon,
{ key: { domainId: 1, tid: 1, bid: 1 }, name: 'balloon', unique: true },
));

global.Hydro.model.contest = {
RULES,
add,
Expand Down

0 comments on commit 030c8e7

Please sign in to comment.