Skeletal implementation of Codechef contests
Signed-off-by: adithyagenie <adithyagenie@gmail.com>
This commit is contained in:
parent
c474f9239d
commit
deca1f0045
7 changed files with 102 additions and 65 deletions
|
@ -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"}
|
|
@ -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
13
src/helpers/ccSchedule.ts
Normal 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
69
src/helpers/lcSchedule.ts
Normal 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
7
src/helpers/scheduler.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { lcSchedule } from "./lcSchedule";
|
||||||
|
import { ccSchedule } from "./ccSchedule";
|
||||||
|
|
||||||
|
export async function contestScheduler() {
|
||||||
|
await lcSchedule();
|
||||||
|
ccSchedule();
|
||||||
|
}
|
|
@ -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));
|
Loading…
Reference in a new issue