diff --git a/README b/README.md similarity index 100% rename from README rename to README.md diff --git a/src/api/lcFetch.ts b/src/api/lcFetch.ts index cb44bf3..00f9466 100644 --- a/src/api/lcFetch.ts +++ b/src/api/lcFetch.ts @@ -1,24 +1,7 @@ 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++) { - now.setDate(now.getDate() + 14); - if (now > new Date()) { - break; - } - } - - return now; -} - -export async function scheduleLCContests() { - await gracefulShutdown(); +export async function fetchLCContests() { const query = { operationName: "mostRecentPastContest", variables: {}, @@ -50,51 +33,11 @@ export async function scheduleLCContests() { return {key: o.titleSlug, name: o.title}; }); contestNames.sort(); - - 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)); - } + return contestNames; + } + else { + throw new Error("Can't access LeetCode API :("); } - 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"} \ No newline at end of file diff --git a/src/bot/commands/contestRem.ts b/src/bot/commands/contestRem.ts index 228b3cd..1403de4 100644 --- a/src/bot/commands/contestRem.ts +++ b/src/bot/commands/contestRem.ts @@ -1,8 +1,13 @@ import { bot } from "../bot"; -import { scheduleLCContests } from "../../api/lcFetch"; export async function reminderContestLC(contestName: string, contestKey: string): Promise { await bot.api.sendMessage(parseInt(process.env.CHAT_ID as string), `LeetCode ${contestName} is in ~10 minutes.\n Attend the contest here: https://leetcode.com/contest/${contestKey}/`); +} + +export async function reminderContestCodeChef(): Promise { + 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/`); } \ No newline at end of file diff --git a/src/helpers/ccSchedule.ts b/src/helpers/ccSchedule.ts new file mode 100644 index 0000000..a378076 --- /dev/null +++ b/src/helpers/ccSchedule.ts @@ -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!") +} \ No newline at end of file diff --git a/src/helpers/lcSchedule.ts b/src/helpers/lcSchedule.ts new file mode 100644 index 0000000..e60c0d8 --- /dev/null +++ b/src/helpers/lcSchedule.ts @@ -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!"); +} \ No newline at end of file diff --git a/src/helpers/scheduler.ts b/src/helpers/scheduler.ts new file mode 100644 index 0000000..9c9c879 --- /dev/null +++ b/src/helpers/scheduler.ts @@ -0,0 +1,7 @@ +import { lcSchedule } from "./lcSchedule"; +import { ccSchedule } from "./ccSchedule"; + +export async function contestScheduler() { + await lcSchedule(); + ccSchedule(); +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 18a8699..da7e27d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,12 +4,12 @@ config(); import { FastifyInstance } from "fastify"; import { startserver } from "./api/server"; import { botInit } from "./bot/bot"; -import { scheduleLCContests } from "./api/lcFetch"; +import { contestScheduler } from "./helpers/scheduler"; export let server: FastifyInstance; startserver().then((s) => { server = s; }); -scheduleLCContests().catch(e => console.error(e)); +contestScheduler().catch(e => console.error(e)); botInit().catch(e => console.error(e)); \ No newline at end of file