Skeletal implementation of Codechef contests

Signed-off-by: adithyagenie <adithyagenie@gmail.com>
This commit is contained in:
adithyagenie 2024-06-12 22:57:27 +05:30
parent c474f9239d
commit deca1f0045
Signed by: adithyagenie
GPG key ID: C66E41599E458D96
7 changed files with 102 additions and 65 deletions

View file

View file

@ -1,24 +1,7 @@
import { PastContestsResponse } from "./interface"; import { PastContestsResponse } from "./interface";
import { gracefulShutdown, RecurrenceRule, scheduleJob } from "node-schedule";
import { reminderContestLC } from "../bot/commands/contestRem";
function getNextBiweeklyDate(): Date {
const now = new Date();
now.setUTCFullYear(2024, 5, 8);
now.setUTCHours(14, 30, 0, 0);
for (let i = 0; i < 500; i++) { export async function fetchLCContests() {
now.setDate(now.getDate() + 14);
if (now > new Date()) {
break;
}
}
return now;
}
export async function scheduleLCContests() {
await gracefulShutdown();
const query = { const query = {
operationName: "mostRecentPastContest", operationName: "mostRecentPastContest",
variables: {}, variables: {},
@ -50,51 +33,11 @@ export async function scheduleLCContests() {
return {key: o.titleSlug, name: o.title}; return {key: o.titleSlug, name: o.title};
}); });
contestNames.sort(); contestNames.sort();
return contestNames;
const biweekly = contestNames.filter(o =>
o.key.match(/^biweekly-contest-(\d+)$/)
);
const weekly = contestNames.filter(o =>
o.key.match(/^weekly-contest-(\d+)$/)
);
if (biweekly.length > 0) {
biweekly.sort((a, b) => a > b ? - 1 : 1);
const matches = biweekly[0].key.match(/^biweekly-contest-(\d+)$/);
const newnum = matches ? parseInt(matches[1]) + 1 : -1;
const newkey = weekly[0].key.replace((newnum - 1).toString(), newnum.toString());
const newname = weekly[0].name.replace((newnum - 1).toString(), newnum.toString());
const date = getNextBiweeklyDate();
date.setMinutes(date.getMinutes() - 10);
scheduleJob(`${newname}`, date, async function (newname: string, newkey: string) {
await reminderContestLC(newname, newkey)
}.bind(null, newname, newkey));
} }
else {
if (weekly.length > 0) { throw new Error("Can't access LeetCode API :(");
weekly.sort((a, b) => a > b ? - 1 : 1);
const matches = weekly[0].key.match(/^weekly-contest-(\d+)$/);
const newnum = matches ? parseInt(matches[1]) + 1 : -1;
const newkey = weekly[0].key.replace((newnum - 1).toString(), newnum.toString());
const newname = weekly[0].name.replace((newnum - 1).toString(), newnum.toString());
const weeklyJob = new RecurrenceRule();
weeklyJob.dayOfWeek = 0;
weeklyJob.hour = 2;
weeklyJob.minute = 20;
weeklyJob.second = 0;
weeklyJob.tz = "Etc/UTC";
scheduleJob(`${newname}`, weeklyJob, async function (newname: string, newkey: string) {
await reminderContestLC(newname, newkey)
}.bind(null, newname, newkey));
} }
}
console.log("Scheduled reminders for LeetCode contests!");
} }
// {"operationName":"mostRecentPastContest","variables":{},"query":"query mostRecentPastContest {\n pastContests(pageNo: 1, numPerPage: 1) {\n data {\n title\n titleSlug\n questions {\n titleSlug\n __typename\n }\n __typename\n }\n __typename\n }\n}\n"} // {"operationName":"mostRecentPastContest","variables":{},"query":"query mostRecentPastContest {\n pastContests(pageNo: 1, numPerPage: 1) {\n data {\n title\n titleSlug\n questions {\n titleSlug\n __typename\n }\n __typename\n }\n __typename\n }\n}\n"}

View file

@ -1,8 +1,13 @@
import { bot } from "../bot"; import { bot } from "../bot";
import { scheduleLCContests } from "../../api/lcFetch";
export async function reminderContestLC(contestName: string, contestKey: string): Promise<void> { export async function reminderContestLC(contestName: string, contestKey: string): Promise<void> {
await bot.api.sendMessage(parseInt(process.env.CHAT_ID as string), await bot.api.sendMessage(parseInt(process.env.CHAT_ID as string),
`LeetCode ${contestName} is in ~10 minutes.\n `LeetCode ${contestName} is in ~10 minutes.\n
Attend the contest here: https://leetcode.com/contest/${contestKey}/`); Attend the contest here: https://leetcode.com/contest/${contestKey}/`);
} }
export async function reminderContestCodeChef(): Promise<void> {
await bot.api.sendMessage(parseInt(process.env.CHAT_ID as string),
`CodeChef contest is in ~10 minutes.\n
Attend the contest here: https://www.codechef.com/contests/`);
}

13
src/helpers/ccSchedule.ts Normal file
View file

@ -0,0 +1,13 @@
import { reminderContestCodeChef } from "../bot/commands/contestRem";
import { RecurrenceRule, scheduleJob } from "node-schedule";
export function ccSchedule() {
const rule = new RecurrenceRule();
rule.dayOfWeek = 3;
rule.hour = 14;
rule.minute = 20;
rule.second = 0;
rule.tz = "Etc/UTC";
scheduleJob(`ccContest`, rule, reminderContestCodeChef);
console.log("CodeChef contests scheduled!")
}

69
src/helpers/lcSchedule.ts Normal file
View file

@ -0,0 +1,69 @@
import { gracefulShutdown, RecurrenceRule, scheduleJob } from "node-schedule";
import { reminderContestLC } from "../bot/commands/contestRem";
import { fetchLCContests } from "../api/lcFetch";
function getNextBiweeklyDate(): Date {
const now = new Date();
now.setUTCFullYear(2024, 5, 8);
now.setUTCHours(14, 30, 0, 0);
for (let i = 0; i < 500; i++) {
now.setDate(now.getDate() + 14);
if (now > new Date()) {
break;
}
}
return now;
}
export async function lcSchedule() {
await gracefulShutdown();
const contestNames = await fetchLCContests();
const biweekly = contestNames.filter(o =>
o.key.match(/^biweekly-contest-(\d+)$/)
);
const weekly = contestNames.filter(o =>
o.key.match(/^weekly-contest-(\d+)$/)
);
if (biweekly.length > 0) {
biweekly.sort((a, b) => a > b ? - 1 : 1);
const matches = biweekly[0].key.match(/^biweekly-contest-(\d+)$/);
const newnum = matches ? parseInt(matches[1]) + 1 : -1;
const newkey = weekly[0].key.replace((newnum - 1).toString(), newnum.toString());
const newname = weekly[0].name.replace((newnum - 1).toString(), newnum.toString());
const date = getNextBiweeklyDate();
date.setMinutes(date.getMinutes() - 10);
scheduleJob(`${newname}`, date, async function (newname: string, newkey: string) {
await reminderContestLC(newname, newkey)
}.bind(null, newname, newkey));
}
if (weekly.length > 0) {
weekly.sort((a, b) => a > b ? - 1 : 1);
const matches = weekly[0].key.match(/^weekly-contest-(\d+)$/);
const newnum = matches ? parseInt(matches[1]) + 1 : -1;
const newkey = weekly[0].key.replace((newnum - 1).toString(), newnum.toString());
const newname = weekly[0].name.replace((newnum - 1).toString(), newnum.toString());
const weeklyJob = new RecurrenceRule();
weeklyJob.dayOfWeek = 0;
weeklyJob.hour = 2;
weeklyJob.minute = 20;
weeklyJob.second = 0;
weeklyJob.tz = "Etc/UTC";
scheduleJob(`${newname}`, weeklyJob, async function (newname: string, newkey: string) {
await reminderContestLC(newname, newkey)
}.bind(null, newname, newkey));
}
console.log("Scheduled reminders for LeetCode contests!");
}

7
src/helpers/scheduler.ts Normal file
View file

@ -0,0 +1,7 @@
import { lcSchedule } from "./lcSchedule";
import { ccSchedule } from "./ccSchedule";
export async function contestScheduler() {
await lcSchedule();
ccSchedule();
}

View file

@ -4,12 +4,12 @@ config();
import { FastifyInstance } from "fastify"; import { FastifyInstance } from "fastify";
import { startserver } from "./api/server"; import { startserver } from "./api/server";
import { botInit } from "./bot/bot"; import { botInit } from "./bot/bot";
import { scheduleLCContests } from "./api/lcFetch"; import { contestScheduler } from "./helpers/scheduler";
export let server: FastifyInstance; export let server: FastifyInstance;
startserver().then((s) => { startserver().then((s) => {
server = s; server = s;
}); });
scheduleLCContests().catch(e => console.error(e)); contestScheduler().catch(e => console.error(e));
botInit().catch(e => console.error(e)); botInit().catch(e => console.error(e));