Skip to content

Commit 7ea2a1e

Browse files
committed
Added backend for leaderbaord
1 parent f996437 commit 7ea2a1e

File tree

6 files changed

+3709
-0
lines changed

6 files changed

+3709
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
env
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
const axios = require("axios");
2+
const fs = require("fs");
3+
require("dotenv").config();
4+
5+
const ORG_NAME = "recodehive";
6+
let leaderboard = {};
7+
8+
const timer = ms => new Promise(res => setTimeout(res, ms));
9+
10+
async function generateOrgLeaderboard() {
11+
try {
12+
let repos = await axios.get(
13+
`https://api.github.com/orgs/${ORG_NAME}/repos?per_page=100`,
14+
{
15+
headers: { Authorization: "token " + process.env.GIT_TOKEN }
16+
}
17+
);
18+
19+
for (let repo of repos.data) {
20+
let repoFullName = repo.full_name; // recodehive/repoName
21+
console.log(`Fetching PRs for ${repoFullName}`);
22+
23+
try {
24+
let response = await axios.get(
25+
`https://api.github.com/search/issues?q=repo:${repoFullName}+is:pr+is:merged&per_page=100`,
26+
{ headers: { Authorization: "token " + process.env.GIT_TOKEN } }
27+
);
28+
29+
let prs = response.data.items;
30+
31+
for (let pr of prs) {
32+
let user = pr.user;
33+
34+
if (!leaderboard[user.id]) {
35+
leaderboard[user.id] = {
36+
avatar_url: user.avatar_url,
37+
login: user.login,
38+
url: user.html_url,
39+
score: 0,
40+
// postManTag: false, // keep if needed
41+
pr_urls: []
42+
};
43+
}
44+
45+
if (!leaderboard[user.id].pr_urls.includes(pr.html_url)) {
46+
leaderboard[user.id].pr_urls.push(pr.html_url);
47+
leaderboard[user.id].score += 10; // scoring rule (static here)
48+
}
49+
}
50+
} catch (err) {
51+
console.log(`Error fetching PRs for ${repoFullName}`, err.message);
52+
}
53+
54+
// small delay to avoid hitting GitHub rate limits
55+
await timer(3000);
56+
}
57+
58+
// Convert to array, add rank + PR count
59+
let leaderboardArray = Object.values(leaderboard)
60+
.map(u => ({
61+
...u,
62+
no_of_prs: u.pr_urls.length
63+
}))
64+
.sort((a, b) => b.score - a.score)
65+
.map((u, i) => ({
66+
rank: i + 1,
67+
...u
68+
}));
69+
70+
let json = {
71+
leaderboard: leaderboardArray,
72+
success: true,
73+
updatedAt: +new Date(),
74+
generated: true,
75+
updatedTimestring: new Date().toLocaleString()
76+
};
77+
78+
fs.writeFileSync("org_leaderboard.json", JSON.stringify(json, null, 2));
79+
console.log("recodehive leaderboard generated!");
80+
} catch (error) {
81+
console.error("Failed to generate leaderboard:", error.message);
82+
}
83+
}
84+
85+
module.exports.generateOrgLeaderboard = generateOrgLeaderboard;
86+
87+
// if (require.main === module) {
88+
// generateOrgLeaderboard(); //Added to test the function directly
89+
// }
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const schedule = require('node-schedule');
2+
const { generateOrgLeaderboard } = require("../functions/org_leaderboard");
3+
4+
5+
6+
function updateOrgLeaderboardJob() {
7+
// Cron format: second, minute, hour, day of month, month, day of week
8+
// This runs every day at 00:00:00 (midnight)
9+
schedule.scheduleJob('0 0 0 * * *', async function () {
10+
console.log("========");
11+
console.log("Starting leaderboard update job...");
12+
console.log("========");
13+
14+
try {
15+
await generateOrgLeaderboard();
16+
console.log("Leaderboard updated successfully!");
17+
} catch (err) {
18+
console.error("Leaderboard update failed:", err.message);
19+
}
20+
});
21+
}
22+
23+
module.exports.updateOrgLeaderboardJob = updateOrgLeaderboardJob;

0 commit comments

Comments
 (0)