|
| 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 | +// } |
0 commit comments