forked from suyash-thakur/js-good-first-issues-finder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
133 lines (110 loc) · 3.64 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
const axios = require('axios');
const fs = require('fs');
const env = require('dotenv');
const Markdown = require('markdown-to-html').Markdown;
env.config();
const API_URL = 'https://api.github.com';
const TOKEN = process.env.API_KEY;
const MAX_ELAPSED_TIME = 2 * 60 * 1000;
const MAX_ISSUES_COUNT = 30;
const WAIT_TIME = 1000;
/**
* Get repositories from GitHub API.
* @param {number} page Page number
* @returns {Promise} Promise with repositories
*/
const getJavascriptRepos = async (page) => {
try {
const response = await axios.get(`${API_URL}/search/repositories`, {
headers: { Authorization: `token ${TOKEN}` },
params: { q: `good-first-issues:>2`, language: 'javascript', sort: 'updated', page },
});
return response.data.items.filter((repo) => repo.language === 'JavaScript');
} catch (error) {
console.error(`Failed to fetch repos from page ${page}: ${error.message}`);
return [];
}
};
/**
* Fetches issues from a repository
* @param {object} repo - The repository object
* @returns {array} - The issues array
*/
const getFilteredIssues = async (repo) => {
try {
const response = await axios.get(`${API_URL}/repos/${repo.full_name}/issues`, {
headers: { Authorization: `token ${TOKEN}` },
params: { state: 'open', labels: 'good first issue', sort: 'updated' },
});
const today = new Date();
const lastMonth = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
return response.data.filter(issue => {
const updatedAt = new Date(issue.updated_at);
return updatedAt > lastMonth;
});
} catch (error) {
console.error(`Failed to fetch issues for ${repo.full_name}: ${error.message}`);
return [];
}
};
const getGoodFirstIssues = async () => {
try {
let goodFirstIssues = [];
let page = 1;
let issuesCount = 0;
let elapsedTime = 0;
const start = Date.now();
while (elapsedTime < MAX_ELAPSED_TIME && issuesCount < MAX_ISSUES_COUNT) {
const repos = await getJavascriptRepos(page);
for (const repo of repos) {
console.log(`Fetching issues for ${repo.full_name}`);
const issues = await getFilteredIssues(repo);
if (issues.length > 0) {
goodFirstIssues.push({ repo: repo.full_name, issues });
issuesCount += issues.length;
}
}
page++;
elapsedTime = Date.now() - start;
await new Promise(resolve => setTimeout(resolve, WAIT_TIME));
}
let markdown = `# Good First Issues\n\nThis is a list of JavaScript repositories with good first issues for newcomers to open source. Contributions are welcome!\n\n`;
markdown += `This list gets updated every day at midnight.\n\n`;
for (const issue of goodFirstIssues) {
markdown += `## [${issue.repo}](${issue.issues[0].html_url.split('/issues')[0]})\n\n`;
for (const item of issue.issues) {
markdown += `- [${item.title}](${item.html_url})\n`;
}
markdown += '\n';
}
fs.writeFileSync('README.md', markdown);
} catch (error) {
console.error(`An error occurred: ${error.message}`);
process.exit();
}
};
const convertToHtml = async () => {
try {
const md = new Markdown();
md.render('README.md', {
title: 'Good Javascript First Issues',
highlight: true,
highlightTheme: 'github',
stylesheet: 'styles.css',
context: 'https://github.com',
}, function (err) {
if (err) {
throw err;
}
md.pipe(fs.createWriteStream('index.html'));
});
} catch (e) {
console.error('>>>' + e);
process.exit();
}
};
const main = async () => {
await getGoodFirstIssues();
await convertToHtml();
};
main();