import {Types} from 'mongoose'; import {User} from 'discord.js'; import {logger} from '../logger'; import {Session, sessionModel} from '../models/sessions'; import {Problem, problemModel} from '../models/problems'; import {Contest, contestModel} from '../models/contests'; export async function clearContests(): Promise{ await contestModel.deleteMany({}); } export async function clearProblems(): Promise{ await problemModel.deleteMany({}); } export async function clearSessions(): Promise{ await sessionModel.deleteMany({}); } export async function clearContest(channelId: string): Promise{ await contestModel.deleteOne({channelId: channelId}); } export async function createContest(channelId: string, startTime: number): Promise{ const contest = await contestModel.findOne({channelId: channelId}); if(contest){ contest.startTime = startTime; await contest.save(); return false; } const newContest = new contestModel({ channelId: channelId, startTime: startTime, problems: [], }); await newContest.save(); return true; } export async function updateProblem( user: User, problemId: string, channelId: string, action: string, time: number): Promise{ // find problem let contest = await contestModel.findOne( {channelId: channelId}, {problems: 1, _id: {"$toString": "$_id"}}, ).populate({path: 'problems', select: 'problemId _id'}); if(contest === null){ logger.error(`contest didn't start`); throw Error(); } if(contest.problems.every(p => p.problemId != problemId)){ const newProblem = await new problemModel( {problemId: problemId}, {}, {new: true} ).save(); await contestModel.updateOne( {channelId: channelId}, {$push: {problems: newProblem}}, {new: true} ); } contest = await contestModel.findOne( {channelId: channelId}, ).populate({path: 'problems', select: 'problemId _id'}); const problem = (contest as Contest).problems.find( p => p.problemId == problemId); // update switch(action){ case 'wa':{ await problemModel.findByIdAndUpdate( (problem as Problem)._id, {$push: {wa: time}}, {new: true} ); }break; case 'ac':{ await problemModel.findByIdAndUpdate( (problem as Problem)._id, {$set: {ac: time}}, {new: true} ); }break; } } export async function putCode( user: User, problemId: string, channelId: string, time: number, estimate: number): Promise{ // find problem let contest = await contestModel.findOne( {channelId: channelId}, {problems: 1, _id: {"$toString": "$_id"}}, ).populate({path: 'problems', select: 'problemId _id'}); if(contest === null){ logger.error(`contest didn't start`); throw Error(); } if(contest.problems.every(p => p.problemId != problemId)){ const newProblem = await new problemModel( {problemId: problemId}, {}, {new: true} ).save(); await contestModel.updateOne( {channelId: channelId}, {$push: {problems: newProblem}}, {new: true} ); } contest = await contestModel.findOne( {channelId: channelId}, ).populate({path: 'problems', select: 'problemId _id'}); const problem = (contest as Contest).problems.find( p => p.problemId == problemId); // update const newSession = await new sessionModel( {name: user.username, start: time, end: estimate}, {}, {new: true, upsert: true} ).save(); await problemModel.findByIdAndUpdate( (problem as Problem)._id, {$push: {code: newSession}}, {new: true} ); return newSession._id.toString(); } export async function putRead( user: User, problemId: string, channelId: string, time: number, estimate: number): Promise{ // find problem let contest = await contestModel.findOne( {channelId: channelId}, {problems: 1, _id: {"$toString": "$_id"}}, ).populate({path: 'problems', select: 'problemId _id'}); if(contest === null){ logger.error(`contest didn't start`); throw Error(); } if(contest.problems.every(p => p.problemId != problemId)){ const newProblem = await new problemModel( {problemId: problemId}, {}, {new: true} ).save(); await contestModel.updateOne( {channelId: channelId}, {$push: {problems: newProblem}}, {new: true} ); } contest = await contestModel.findOne( {channelId: channelId}, ).populate({path: 'problems', select: 'problemId _id'}); const problem = (contest as Contest).problems.find( p => p.problemId == problemId); // update const newSession = await new sessionModel( {name: user.username, start: time, end: estimate}, {}, {new: true, upsert: true} ).save(); await problemModel.findByIdAndUpdate( (problem as Problem)._id, {$push: {read: newSession}}, {new: true} ); return newSession._id.toString(); } export async function updateSession(sessionId: string, key: string, time: number): Promise{ const session = await sessionModel.findOne({_id: sessionId}); if(session === null){ logger.error(`Session ${sessionId} not found.`); return false; } switch(key){ case 'start':{ await sessionModel.updateOne( {_id: sessionId}, {start: time} ); }break; case 'end':{ await sessionModel.updateOne( {_id: sessionId}, {end: time} ); }break; } return true; } export async function getContest(channelId: string): Promise{ return await contestModel.findOne({channelId: channelId}).populate( {path: 'problems', select: 'problemId _id'} ); } export async function getProblem(id: Types.ObjectId): Promise{ return await problemModel.findById(id).populate( {path: 'read code', select: 'name start end _id'} ); } export async function getSession(id: Types.ObjectId): Promise{ return await sessionModel.findById(id).populate('name start end _id'); } export async function getAllSession(): Promise{ return await sessionModel.find({}); } export async function getAllProblem(): Promise{ return await problemModel.find({}); } export async function getAllContest(): Promise{ return await contestModel.find({}); }