From 17de3a13a8c44a035b5ec6ad4ace76ce4cb0dae3 Mon Sep 17 00:00:00 2001 From: Linghao Zhang Date: Fri, 20 Mar 2020 15:08:36 +0800 Subject: [PATCH 1/4] Add github contributors done: "New" contributors, ordered by commit number ascended todo: Optional "top" contributors --- assets/radar-rules.js | 6 +++ docs/en/programming.md | 4 ++ docs/programming.md | 4 ++ lib/router.js | 2 + lib/routes/github/contributors.js | 85 +++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 lib/routes/github/contributors.js diff --git a/assets/radar-rules.js b/assets/radar-rules.js index a66587686a..ff82fb4846 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -227,6 +227,12 @@ source: '/:user', target: '/github/starred_repos/:user', }, + { + title: '仓库 Contributors', + docs: 'https://docs.rsshub.app/programming.html#github', + source: ['/:user/:repo/graphs/contributors', '/:user/:repo'], + target: '/github/contributors/:user/:repo', + }, ], }, 'zhihu.com': { diff --git a/docs/en/programming.md b/docs/en/programming.md index d8890c8904..005d0539dc 100644 --- a/docs/en/programming.md +++ b/docs/en/programming.md @@ -77,6 +77,10 @@ GitHub provides some official RSS feeds: +### Repo Contributors + + + ## GitLab ### Explore diff --git a/docs/programming.md b/docs/programming.md index 4b8a08c58b..3a9f60c993 100644 --- a/docs/programming.md +++ b/docs/programming.md @@ -127,6 +127,10 @@ GitHub 官方也提供了一些 RSS: +### 仓库 Contirbutors + + + ## GitLab ### Explore diff --git a/lib/router.js b/lib/router.js index 1051724506..ffdd62e26e 100644 --- a/lib/router.js +++ b/lib/router.js @@ -275,6 +275,8 @@ router.get('/github/search/:query/:sort?/:order?', require('./routes/github/sear router.get('/github/branches/:user/:repo', require('./routes/github/branches')); router.get('/github/file/:user/:repo/:branch/:filepath+', require('./routes/github/file')); router.get('/github/starred_repos/:user', require('./routes/github/starred_repos')); +router.get('/github/contributors/:user/:repo/:anon?', require('./routes/github/contributors')); + // f-droid router.get('/fdroid/apprelease/:app', require('./routes/fdroid/apprelease')); diff --git a/lib/routes/github/contributors.js b/lib/routes/github/contributors.js new file mode 100644 index 0000000000..dfbff149e8 --- /dev/null +++ b/lib/routes/github/contributors.js @@ -0,0 +1,85 @@ +const got = require('@/utils/got'); +const config = require('@/config').value; + +module.exports = async (ctx) => { + const user = ctx.params.user; + const repo = ctx.params.repo; + const anon = ctx.params.anon; + + const host = `https://github.com/${user}/${repo}`; + const url = `https://api.github.com/repos/${user}/${repo}/contributors?` + (anon ? 'anon=1' : ''); + + const headers = {}; + if (config.github && config.github.access_token) { + headers.Authorization = `token ${config.github.access_token}`; + } + + const response = await got({ + method: 'get', + url, + headers, + }); + let data = response.data; + + try { + const last_page_link = response.headers.link.split(',').find(function(elem) { + return elem.includes('"last"'); + }); + const url_base = last_page_link.match(/<(.*)page=\d*/)[1]; + const page_count = Number(last_page_link.match(/page=(\d*)/)[1]); + + for (let page = 2; page <= page_count; page++) { + // eslint-disable-next-line no-await-in-loop + const response = await got({ + method: 'get', + url: `${url_base}page=${page}`, + headers, + }); + data = data.concat(response.data); + } + } catch (err) { + if (!(err instanceof TypeError)) { + throw err; + } + } + + let title; + let description; + let link; + let guid; + + const items = []; + let index = 0; + + data.forEach(function(item) { + const time = new Date(); + time.setMinutes(time.getMinutes() - data.length + index); + index++; + + if (item.type === 'Anonymous') { + title = `Contributor: ${item.name}`; + description = `

Anonymous contributor

Name: ${item.name}

E-mail: ${item.email}

Contributions: ${item.contributions}

`; + link = ''; + guid = `anon-${item.name}`; + } else { + title = `Contributor: ${item.login}`; + description = `

${item.login}

Contributions: ${item.contributions}

`; + link = item.html_url; + guid = item.id; + } + + items.push({ + title: title, + description: description, + guid: guid, + link: link, + pubDate: time, + }); + }), + (ctx.state.data = { + title: `${user}/${repo} Contributors`, + link: `${host}/graphs/contributors`, + description: `New contributors for ${user}/${repo}`, + item: items, + }); +}; From c4a13afcabc544c3810319ecb4ea324012c5538d Mon Sep 17 00:00:00 2001 From: Linghao Zhang Date: Sat, 21 Mar 2020 16:26:17 +0800 Subject: [PATCH 2/4] Github contributors add sort order --- docs/en/programming.md | 58 +++++++++++++++---------------- docs/programming.md | 2 +- lib/router.js | 2 +- lib/routes/github/contributors.js | 3 +- 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/docs/en/programming.md b/docs/en/programming.md index 005d0539dc..48bb5e65f4 100644 --- a/docs/en/programming.md +++ b/docs/en/programming.md @@ -19,35 +19,35 @@ GitHub provides some official RSS feeds: ### User Repo - + ### Trending - + ### Repo Issues - + ### Repo Pull Requests - + ### User Followers - + ### Repo Stars - + ### Repo Branches - + ### Files Commits - + | User name | Repo name | Branch name | File path | | --------- | --------- | ----------- | --------------- | @@ -60,11 +60,11 @@ GitHub provides some official RSS feeds: > > > > Such as: replace `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/router%2ejs` to `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/router%2ejs.rss` - + ### Search Result - + | Sort options | sort | | ---------------- | --------- | @@ -75,29 +75,29 @@ GitHub provides some official RSS feeds: ### User Starred Repositories - + ### Repo Contributors - + ## GitLab ### Explore - + | Trending | Most stars | All | | -------- | ---------- | --- | | trending | starred | all | - + ## Hacker News ### Section - + Website: https://news.ycombinator.com/ @@ -118,7 +118,7 @@ Website: https://news.ycombinator.com/ | story | Deault, link to shared address | | comments | Link to Hacker News address | - + ## Hex-Rays @@ -131,45 +131,45 @@ Website: https://news.ycombinator.com/ ### Discussion - + | hot | recent | new | top | active | | ------- | --------------- | --------------- | ---------- | ------------- | | Hotness | Recent Comments | Recently Posted | Most Votes | Most Comments | - + ### Competitions - + | 空 | featured | research | recruitment | gettingStarted | masters | playground | analytics | | -------------- | -------- | -------- | ----------- | --------------- | ------- | ---------- | --------- | | All Categories | Featured | Research | Recruitment | Getting started | Masters | Playground | Analytics | - + ## LeetCode ### Articles - + ### Submission - + ## Linux Patchwork ### Patch Comments - + ## LWN.net ### Security alerts - + | Distribution | Identification | | :--------------- | :----------------- | @@ -187,7 +187,7 @@ Website: https://news.ycombinator.com/ | SUSE | `SUSE` | | Ubuntu | `Ubuntu` | - + ## project-zero issues @@ -199,18 +199,16 @@ Website: https://news.ycombinator.com/ ### Scala Blog - -part parmater can be found in the url of blog - + ## Visual Studio Code Marketplace ### Visual Studio Code Plugins Marketplace - + | Featured | Trending Weekly | Trending Monthly | Trending Daily | Most Popular | Recently Added | | -------- | --------------- | ---------------- | -------------- | ------------ | -------------- | | featured | trending | trending_m | trending_d | popular | new | - + diff --git a/docs/programming.md b/docs/programming.md index 3a9f60c993..25bd7f29b1 100644 --- a/docs/programming.md +++ b/docs/programming.md @@ -129,7 +129,7 @@ GitHub 官方也提供了一些 RSS: ### 仓库 Contirbutors - + ## GitLab diff --git a/lib/router.js b/lib/router.js index ffdd62e26e..5e4ba6b184 100644 --- a/lib/router.js +++ b/lib/router.js @@ -275,7 +275,7 @@ router.get('/github/search/:query/:sort?/:order?', require('./routes/github/sear router.get('/github/branches/:user/:repo', require('./routes/github/branches')); router.get('/github/file/:user/:repo/:branch/:filepath+', require('./routes/github/file')); router.get('/github/starred_repos/:user', require('./routes/github/starred_repos')); -router.get('/github/contributors/:user/:repo/:anon?', require('./routes/github/contributors')); +router.get('/github/contributors/:user/:repo/:order?/:anon?', require('./routes/github/contributors')); // f-droid router.get('/fdroid/apprelease/:app', require('./routes/fdroid/apprelease')); diff --git a/lib/routes/github/contributors.js b/lib/routes/github/contributors.js index dfbff149e8..071b730ef3 100644 --- a/lib/routes/github/contributors.js +++ b/lib/routes/github/contributors.js @@ -4,6 +4,7 @@ const config = require('@/config').value; module.exports = async (ctx) => { const user = ctx.params.user; const repo = ctx.params.repo; + const order = ctx.params.order; const anon = ctx.params.anon; const host = `https://github.com/${user}/${repo}`; @@ -53,7 +54,7 @@ module.exports = async (ctx) => { data.forEach(function(item) { const time = new Date(); - time.setMinutes(time.getMinutes() - data.length + index); + time.setMinutes(time.getMinutes() + (order === 'asc' ? -data.length + index : -index)); index++; if (item.type === 'Anonymous') { From 42bd6fa2cfd1376d39b206b310efc56a3e234806 Mon Sep 17 00:00:00 2001 From: Linghao Zhang Date: Thu, 2 Apr 2020 11:05:59 +0800 Subject: [PATCH 3/4] Use promise instead --- docs/en/programming.md | 74 +++++++++++++++---------------- lib/routes/github/contributors.js | 36 ++++++++++----- 2 files changed, 61 insertions(+), 49 deletions(-) diff --git a/docs/en/programming.md b/docs/en/programming.md index 48bb5e65f4..4436f75065 100644 --- a/docs/en/programming.md +++ b/docs/en/programming.md @@ -1,5 +1,5 @@ --- -pageClass: routes +pageClass: RouteEns --- # Programming @@ -19,52 +19,52 @@ GitHub provides some official RSS feeds: ### User Repo - + ### Trending - + ### Repo Issues - + ### Repo Pull Requests - + ### User Followers - + ### Repo Stars - + ### Repo Branches - + ### Files Commits - + -| User name | Repo name | Branch name | File path | -| --------- | --------- | ----------- | --------------- | -| `DIYgod` | `RSSHub` | `master` | `lib/router.js` | +| User name | Repo name | Branch name | File path | +| --------- | --------- | ----------- | ----------------- | +| `DIYgod` | `RSSHub` | `master` | `lib/RouteEnr.js` | > - If there are special characters such as `/` in the **branch name**, they need to be encoded with urlencode, usually `/` needs to be replaced with `%2f` > - If there are special characters in the **file path**, you need to use urlencode to encode them, but the file path can be recognized normally `/` characters > - If the **file path** ends with `.rss`, `.atom`, `.json`, you need to replace the `.` in the suffix with `%2e` -> > Reeder will make an error when subscribing to `% 2erss` or similar suffixes. At this time, add`.rss` after the route to subscribe +> > Reeder will make an error when subscribing to `% 2erss` or similar suffixes. At this time, add`.rss` after the RouteEn to subscribe > > -> > Such as: replace `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/router%2ejs` to `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/router%2ejs.rss` +> > Such as: replace `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/RouteEnr%2ejs` to `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/RouteEnr%2ejs.rss` - + ### Search Result - + | Sort options | sort | | ---------------- | --------- | @@ -75,29 +75,29 @@ GitHub provides some official RSS feeds: ### User Starred Repositories - + ### Repo Contributors - + ## GitLab ### Explore - + | Trending | Most stars | All | | -------- | ---------- | --- | | trending | starred | all | - + ## Hacker News ### Section - + Website: https://news.ycombinator.com/ @@ -118,58 +118,58 @@ Website: https://news.ycombinator.com/ | story | Deault, link to shared address | | comments | Link to Hacker News address | - + ## Hex-Rays ### Hex-Rays News - - + + ## Kaggle ### Discussion - + | hot | recent | new | top | active | | ------- | --------------- | --------------- | ---------- | ------------- | | Hotness | Recent Comments | Recently Posted | Most Votes | Most Comments | - + ### Competitions - + | 空 | featured | research | recruitment | gettingStarted | masters | playground | analytics | | -------------- | -------- | -------- | ----------- | --------------- | ------- | ---------- | --------- | | All Categories | Featured | Research | Recruitment | Getting started | Masters | Playground | Analytics | - + ## LeetCode ### Articles - + ### Submission - + ## Linux Patchwork ### Patch Comments - + ## LWN.net ### Security alerts - + | Distribution | Identification | | :--------------- | :----------------- | @@ -187,28 +187,28 @@ Website: https://news.ycombinator.com/ | SUSE | `SUSE` | | Ubuntu | `Ubuntu` | - + ## project-zero issues ### issues - + ## Scala ### Scala Blog - + ## Visual Studio Code Marketplace ### Visual Studio Code Plugins Marketplace - + | Featured | Trending Weekly | Trending Monthly | Trending Daily | Most Popular | Recently Added | | -------- | --------------- | ---------------- | -------------- | ------------ | -------------- | | featured | trending | trending_m | trending_d | popular | new | - + diff --git a/lib/routes/github/contributors.js b/lib/routes/github/contributors.js index 071b730ef3..6d84bf7d2a 100644 --- a/lib/routes/github/contributors.js +++ b/lib/routes/github/contributors.js @@ -2,19 +2,18 @@ const got = require('@/utils/got'); const config = require('@/config').value; module.exports = async (ctx) => { - const user = ctx.params.user; - const repo = ctx.params.repo; - const order = ctx.params.order; - const anon = ctx.params.anon; + const { user, repo, order, anon } = ctx.params; const host = `https://github.com/${user}/${repo}`; const url = `https://api.github.com/repos/${user}/${repo}/contributors?` + (anon ? 'anon=1' : ''); + // Use token if available const headers = {}; if (config.github && config.github.access_token) { headers.Authorization = `token ${config.github.access_token}`; } + // First page const response = await got({ method: 'get', url, @@ -23,40 +22,53 @@ module.exports = async (ctx) => { let data = response.data; try { + // Get total page number const last_page_link = response.headers.link.split(',').find(function(elem) { return elem.includes('"last"'); }); const url_base = last_page_link.match(/<(.*)page=\d*/)[1]; const page_count = Number(last_page_link.match(/page=(\d*)/)[1]); - for (let page = 2; page <= page_count; page++) { - // eslint-disable-next-line no-await-in-loop + const generate_array = (n) => [...Array(n - 1)].map((_, index) => index + 2); + const page_array = generate_array(page_count); + + // Get everypage + const tasks = page_array.map(async (page) => { const response = await got({ method: 'get', url: `${url_base}page=${page}`, headers, }); data = data.concat(response.data); - } + }); + await Promise.all(tasks); } catch (err) { + // If only one page + + // Other errors if (!(err instanceof TypeError)) { throw err; } } - let title; - let description; - let link; - let guid; + // Sort by commits + data.sort((a, b) => a.contributions - b.contributions); + if (order !== 'asc') { + data.reverse(); + } + + let title, description, link, guid; const items = []; let index = 0; + // Generate RSS data.forEach(function(item) { const time = new Date(); - time.setMinutes(time.getMinutes() + (order === 'asc' ? -data.length + index : -index)); + time.setMinutes(time.getMinutes() - index); index++; + // Distiguished between acounts if (item.type === 'Anonymous') { title = `Contributor: ${item.name}`; description = `

Anonymous contributor

Name: ${item.name}

E-mail: ${item.email}

Contributions: ${item.contributions}

`; From 026f9dce3aa2902531fcf4b682315fec3b06e6b7 Mon Sep 17 00:00:00 2001 From: Linghao Zhang Date: Fri, 3 Apr 2020 15:23:59 +0800 Subject: [PATCH 4/4] Fixing unnecessary changes due to my neglect --- docs/en/programming.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/en/programming.md b/docs/en/programming.md index 4436f75065..4b3d273fa1 100644 --- a/docs/en/programming.md +++ b/docs/en/programming.md @@ -1,5 +1,5 @@ --- -pageClass: RouteEns +pageClass: routes --- # Programming @@ -47,18 +47,18 @@ GitHub provides some official RSS feeds: ### Files Commits - + -| User name | Repo name | Branch name | File path | -| --------- | --------- | ----------- | ----------------- | -| `DIYgod` | `RSSHub` | `master` | `lib/RouteEnr.js` | +| User name | Repo name | Branch name | File path | +| --------- | --------- | ----------- | --------------- | +| `DIYgod` | `RSSHub` | `master` | `lib/router.js` | > - If there are special characters such as `/` in the **branch name**, they need to be encoded with urlencode, usually `/` needs to be replaced with `%2f` > - If there are special characters in the **file path**, you need to use urlencode to encode them, but the file path can be recognized normally `/` characters > - If the **file path** ends with `.rss`, `.atom`, `.json`, you need to replace the `.` in the suffix with `%2e` -> > Reeder will make an error when subscribing to `% 2erss` or similar suffixes. At this time, add`.rss` after the RouteEn to subscribe +> > Reeder will make an error when subscribing to `% 2erss` or similar suffixes. At this time, add`.rss` after the route to subscribe > > -> > Such as: replace `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/RouteEnr%2ejs` to `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/RouteEnr%2ejs.rss` +> > Such as: replace `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/router%2ejs` to `https://rsshub.app/github/file/DIYgod/RSSHub/master/lib/router%2ejs.rss` @@ -124,8 +124,8 @@ Website: https://news.ycombinator.com/ ### Hex-Rays News - - + + ## Kaggle @@ -193,13 +193,14 @@ Website: https://news.ycombinator.com/ ### issues - + ## Scala ### Scala Blog - + + ## Visual Studio Code Marketplace