diff --git a/docs/en/programming.md b/docs/en/programming.md index 4e673aabd5..a8c203aee4 100644 --- a/docs/en/programming.md +++ b/docs/en/programming.md @@ -137,26 +137,21 @@ For instance, the `/github/topics/framework/l=php&o=desc&s=stars` route will gen ### Section - + -Website: https://news.ycombinator.com/ +Section -| Section | section | -| ------- | ----------------------------------- | -| index | https://news.ycombinator.com/ | -| new | https://news.ycombinator.com/newest | -| past | https://news.ycombinator.com/front | -| ask | https://news.ycombinator.com/ask | -| show | https://news.ycombinator.com/show | -| jobs | https://news.ycombinator.com/jobs | -| best | https://news.ycombinator.com/best | +| homepage | new | past | comments | ask | show | jobs | best | +| ------------------------------------- | --------------------------------------------- | ------------------------------------------- | ------------------------------------------------------- | --------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| [index](https://news.ycombinator.com) | [newest](https://news.ycombinator.com/newest) | [front](https://news.ycombinator.com/front) | [newcomments](https://news.ycombinator.com/newcomments) | [ask](https://news.ycombinator.com/ask) | [show](https://news.ycombinator.com/show) | [jobs](https://news.ycombinator.com/jobs) | [best](https://news.ycombinator.com/best) | -> Official RSS:https://news.ycombinator.com/rss is same as `index` section +Items link to -| Link type | type | -| --------- | ------------------------------ | -| story | Deault, link to shared address | -| comments | Link to Hacker News address | +| Source addresses shared by users | Comments on Hacker News | +| -------------------------------- | ----------------------- | +| sources | comments | + +> Default RSS by the website: , same as `index` section, should be the first choice. diff --git a/docs/programming.md b/docs/programming.md index 50f85a24cf..c66e9accec 100644 --- a/docs/programming.md +++ b/docs/programming.md @@ -219,28 +219,23 @@ GitHub 官方也提供了一些 RSS: ## Hacker News -### 分类 +### 分区 - + -网站地址: +内容分区 -| 内容分区 | section | -| -------- | ------------------------------------- | -| index | | -| new | | -| past | | -| ask | | -| show | | -| jobs | | -| best | | +| homepage | new | past | comments | ask | show | jobs | best | +| ------------------------------------- | --------------------------------------------- | ------------------------------------------- | ------------------------------------------------------- | --------------------------------------- | ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| [index](https://news.ycombinator.com) | [newest](https://news.ycombinator.com/newest) | [front](https://news.ycombinator.com/front) | [newcomments](https://news.ycombinator.com/newcomments) | [ask](https://news.ycombinator.com/ask) | [show](https://news.ycombinator.com/show) | [jobs](https://news.ycombinator.com/jobs) | [best](https://news.ycombinator.com/best) | -> 网站有默认的 RSS: 内容同 index,应优先考虑 +条目指向链接类型 -| 链接类型 | type | -| -------- | ----------------------------- | -| story | 默认值,链向用户分享的地址 | -| comments | 链向 Hacker News 上的讨论页面 | +| 用户分享的来源地址 | Hacker News 上的讨论页面 | +| ------------------ | ------------------------ | +| sources | comments | + +> 网站有默认的 RSS: 内容同 homepage,应优先考虑。 diff --git a/lib/router.js b/lib/router.js index 1a14d00ca4..4bd248abfe 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1434,7 +1434,7 @@ router.get('/aisixiang/ranking/:type?/:range?', lazyloadRouteHandler('./routes/a router.get('/aisixiang/thinktank/:name/:type?', lazyloadRouteHandler('./routes/aisixiang/thinktank')); // Hacker News -router.get('/hackernews/:section/:type?', lazyloadRouteHandler('./routes/hackernews/story')); +// router.get('/hackernews/:section/:type?', lazyloadRouteHandler('./routes/hackernews/story')); // LeetCode router.get('/leetcode/articles', lazyloadRouteHandler('./routes/leetcode/articles')); diff --git a/lib/routes/hackernews/story.js b/lib/routes/hackernews/story.js deleted file mode 100644 index 178390ccc9..0000000000 --- a/lib/routes/hackernews/story.js +++ /dev/null @@ -1,60 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); - -const host = 'https://news.ycombinator.com'; -const paths = { - index: '/', - new: '/newest', - past: '/front', - ask: '/ask', - show: '/show', - jobs: '/jobs', - best: '/best', -}; - -module.exports = async (ctx) => { - const section = ctx.params.section; - const showStory = ctx.params.type !== 'comments'; - const path = paths[section]; - const url = `${host}${path}`; - const response = await got.get(url); - const $ = cheerio.load(response.data); - - const items = $('a.storylink') - .map(function () { - return { - title: $(this).text(), - link: $(this).attr('href'), - author: 'Hacker News', - description: '', - }; - }) - .get(); - - $('a.hnuser').each(function (i) { - items[i].author = $(this).text(); - }); - - $('tr.athing').each(function (i) { - const commURL = `${host}/item?id=` + $(this).attr('id'); - const item = items[i]; - - if (showStory) { - item.description = `Comments: ${commURL} `; - } else { - item.description = `Link: ${item.title} `; - item.link = commURL; - } - }); - - let title = `Hacker News: ${section}`; - if (!showStory) { - title += '/comments'; - } - - ctx.state.data = { - title, - link: url, - item: items, - }; -}; diff --git a/lib/v2/hackernews/index.js b/lib/v2/hackernews/index.js new file mode 100644 index 0000000000..22154293dd --- /dev/null +++ b/lib/v2/hackernews/index.js @@ -0,0 +1,97 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const section = ctx.params.section ?? 'index'; + const type = ctx.params.type ?? 'sources'; + + const rootUrl = 'https://news.ycombinator.com'; + const currentUrl = `${rootUrl}${section === 'index' ? '' : `/${section}`}`; + + const response = await got({ + method: 'get', + url: currentUrl, + }); + + const $ = cheerio.load(response.data); + + const list = $('.athing') + .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 30) + .map((_, thing) => { + thing = $(thing); + + const item = {}; + + item.guid = thing.attr('id'); + item.title = thing.find('.titlelink').text(); + item.category = thing.find('.sitestr').text(); + item.author = thing.next().find('.hnuser').text(); + item.pubDate = parseDate(thing.next().attr('title')); + + item.link = `${rootUrl}/item?id=${item.guid}`; + item.origin = thing.find('.titlelink').attr('href'); + + item.comments = thing.next().find('a').last().text().split(' comment')[0]; + item.guid = type === 'sources' ? item.guid : `${item.guid}${item.comments === 'discuss' ? '' : `-${item.comments}`}`; + + item.description = `Comments on Hacker News | Source`; + + return item; + }) + .get(); + + const items = await Promise.all( + list.map((item) => + ctx.cache.tryGet(item.guid, async () => { + if (item.comments !== 'discuss' && type !== 'sources') { + const detailResponse = await got({ + method: 'get', + url: item.link, + }); + + const content = cheerio.load(detailResponse.data); + + content('.reply').remove(); + + item.description = ''; + + content('.comtr').each(function () { + const author = content(this).find('.hnuser'); + const comment = content(this).find('.commtext'); + + item.description += + `
${author.text()}` + + `  ` + + `${content(this).find('.age').attr('title')}
`; + + const commentText = comment.clone(); + + commentText.find('p').remove(); + commentText.html(`

${commentText.text()}

`); + commentText.append( + comment + .find('p') + .toArray() + .map((p) => `

${content(p).html()}

`) + ); + + item.description += `
${commentText.html()}
`; + }); + } + + item.link = type === 'sources' ? item.origin : item.link; + + delete item.origin; + + return item; + }) + ) + ); + + ctx.state.data = { + title: $('title').text(), + link: currentUrl, + item: items, + }; +}; diff --git a/lib/v2/hackernews/maintainer.js b/lib/v2/hackernews/maintainer.js new file mode 100644 index 0000000000..fdf8e0d48f --- /dev/null +++ b/lib/v2/hackernews/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:section?/:type?': ['nczitzk'], +}; diff --git a/lib/v2/hackernews/radar.js b/lib/v2/hackernews/radar.js new file mode 100644 index 0000000000..201556934f --- /dev/null +++ b/lib/v2/hackernews/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'ycombinator.com': { + _name: 'Hacker News', + '.': [ + { + title: 'Section', + docs: 'https://docs.rsshub.app/programming.html#hacker-news', + source: ['/:section', '/'], + target: '/hackernews/:section?/:type?', + }, + ], + }, +}; diff --git a/lib/v2/hackernews/router.js b/lib/v2/hackernews/router.js new file mode 100644 index 0000000000..90278727ab --- /dev/null +++ b/lib/v2/hackernews/router.js @@ -0,0 +1,3 @@ +module.exports = function (router) { + router.get('/:section?/:type?', require('./index')); +};