diff --git a/docs/en/programming.md b/docs/en/programming.md index 82348427dc..1d7c0e3a49 100644 --- a/docs/en/programming.md +++ b/docs/en/programming.md @@ -213,7 +213,7 @@ For instance, the `/github/topics/framework/l=php&o=desc&s=stars` route will gen ### Issue / Pull Request comments - + ### Wiki History diff --git a/docs/programming.md b/docs/programming.md index 614eafbc0e..647e3bae03 100644 --- a/docs/programming.md +++ b/docs/programming.md @@ -308,7 +308,7 @@ GitHub 官方也提供了一些 RSS: ### Issue / Pull Request 评论 - + ### Wiki 历史 diff --git a/lib/v2/github/comments.js b/lib/v2/github/comments.js index 41e9a24859..0378305b57 100644 --- a/lib/v2/github/comments.js +++ b/lib/v2/github/comments.js @@ -3,12 +3,16 @@ const { parseDate } = require('@/utils/parse-date'); const md = require('markdown-it')({ html: true, }); +const rootUrl = 'https://github.com'; const apiUrl = 'https://api.github.com'; const config = require('@/config').value; const typeDict = { issue: { title: 'Issue', }, + issues: { + title: 'Issue', + }, pull: { title: 'Pull request', }, @@ -17,8 +21,8 @@ const typeDict = { module.exports = async (ctx) => { const user = ctx.params.user; const repo = ctx.params.repo; - const number = isNaN(parseInt(ctx.params.number)) ? 1 : parseInt(ctx.params.number); - const limit = ctx.query.limit ? parseInt(ctx.params.limit) : 100; + const number = ctx.params.number && isNaN(parseInt(ctx.params.number)) ? 1 : parseInt(ctx.params.number); + const limit = ctx.query.limit ? parseInt(ctx.query.limit) : 100; const headers = config.github && config.github.access_token ? { @@ -29,6 +33,64 @@ module.exports = async (ctx) => { Accept: 'application/vnd.github.v3+json', }; + if (isNaN(number)) { + await allIssues(ctx, user, repo, limit, headers); + } else { + await singleIssue(ctx, user, repo, number, limit, headers); + } +}; + +async function allIssues(ctx, user, repo, limit, headers) { + const response = await got(`${apiUrl}/repos/${user}/${repo}/issues/comments`, { + headers, + searchParams: { + sort: "updated", + direction: "desc", + per_page: limit, + } + }); + + const timeline = response.data; + + const items = timeline.map((item) => { + const actor = item.actor?.login ?? item.user?.login ?? 'ghost'; + const issueUrlParts = item.issue_url.split("/"); + const issue = issueUrlParts[issueUrlParts.length - 1]; + const urlParts = item.html_url.split("/"); + const issueType = typeDict[urlParts[urlParts.length - 2]].title; + + return { + title: `${actor} commented on ${user}/${repo}: ${issueType} #${issue}`, + author: actor, + pubDate: parseDate(item.created_at), + link: item.html_url, + description: item.body ? md.render(item.body) : null, + }; + }); + + const rateLimit = { + limit: parseInt(response.headers['x-ratelimit-limit']), + remaining: parseInt(response.headers['x-ratelimit-remaining']), + reset: parseDate(parseInt(response.headers['x-ratelimit-reset']) * 1000), + resoure: response.headers['x-ratelimit-resource'], + used: parseInt(response.headers['x-ratelimit-used']), + }; + + ctx.state.data = { + title: `${user}/${repo}: Issue & Pull request comments`, + link: `${rootUrl}/${user}/${repo}`, + item: items, + }; + + ctx.state.json = { + title: `${user}/${repo}: Issue & Pull request comments`, + link: `${rootUrl}/${user}/${repo}`, + item: items, + rateLimit, + }; +} + +async function singleIssue(ctx, user, repo, number, limit, headers) { const response = await got(`${apiUrl}/repos/${user}/${repo}/issues/${number}`, { headers, }); @@ -124,4 +186,4 @@ module.exports = async (ctx) => { used: parseInt(response.headers['x-ratelimit-used']), }, }; -}; +} diff --git a/lib/v2/github/maintainer.js b/lib/v2/github/maintainer.js index 9874c65813..0cdc6b716f 100644 --- a/lib/v2/github/maintainer.js +++ b/lib/v2/github/maintainer.js @@ -1,6 +1,6 @@ module.exports = { '/branches/:user/:repo': ['max-arnold'], - '/comments/:user/:repo/:number': ['TonyRL'], + '/comments/:user/:repo/:number?': ['TonyRL', 'FliegendeWurst'], '/contributors/:user/:repo/:order?/:anon?': ['zoenglinghou'], '/file/:user/:repo/:branch/:filepath+': ['zengxs'], '/gist/:gistId': ['TonyRL'], diff --git a/lib/v2/github/radar.js b/lib/v2/github/radar.js index 0f9848f481..46f9488e9d 100644 --- a/lib/v2/github/radar.js +++ b/lib/v2/github/radar.js @@ -14,6 +14,12 @@ module.exports = { source: ['/:user/:repo/:type/:number'], target: '/github/comments/:user/:repo/:number', }, + { + title: 'Issue & Pull Request comments', + docs: 'https://docs.rsshub.app/programming.html#github', + source: ['/:user/:repo/:type'], + target: '/github/comments/:user/:repo', + }, { title: '仓库 Contributors', docs: 'https://docs.rsshub.app/programming.html#github', diff --git a/lib/v2/github/router.js b/lib/v2/github/router.js index 3c16200c3c..7b8f52b4a2 100644 --- a/lib/v2/github/router.js +++ b/lib/v2/github/router.js @@ -1,7 +1,7 @@ module.exports = function (router) { router.get('/branches/:user/:repo', require('./branches')); router.get('/comments/:user/:repo/:type/:number', require('./comments')); // deprecated - router.get('/comments/:user/:repo/:number', require('./comments')); + router.get('/comments/:user/:repo/:number?', require('./comments')); router.get('/contributors/:user/:repo/:order?/:anon?', require('./contributors')); router.get('/file/:user/:repo/:branch/:filepath+', require('./file')); router.get('/gist/:gistId', require('./gist'));