diff --git a/docs/README.md b/docs/README.md index 1aa531ff6..0aae2d5b2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2317,3 +2317,14 @@ category 对应的关键词有 > board 和 build 可在[这里](http://api.ineal.me/tss/status)查看 + +### 9To5 + + + +支持分站: +| Mac | Google | Toys | +| --- | ------ | ---- | +| Mac | Google | Toys | + + diff --git a/docs/en/README.md b/docs/en/README.md index 5fae59fce..7eba38825 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -398,3 +398,14 @@ Provides a better reading experience (full text articles) over the official one. Provides a better reading experience (full text articles) over the official one. + +### 9To5 + + + +Supported sub-sites: +| Mac | Google | Toys | +| --- | ------ | ---- | +| Mac | Google | Toys | + + diff --git a/router.js b/router.js index bd4bb6c13..97bc2afdd 100644 --- a/router.js +++ b/router.js @@ -807,4 +807,7 @@ router.get('/tssstatus/:board/:build', require('./routes/tssstatus')); router.get('/anime1/anime/:time/:name', require('./routes/anime1/anime')); router.get('/anime1/search/:keyword', require('./routes/anime1/search')); +// 9to5 +router.get('/9to5/:type', require('./routes/9to5/subsite')); + module.exports = router; diff --git a/routes/9to5/subsite.js b/routes/9to5/subsite.js new file mode 100644 index 000000000..ea624f5bf --- /dev/null +++ b/routes/9to5/subsite.js @@ -0,0 +1,62 @@ +const axios = require('../../utils/axios'); +const utils = require('./utils'); +const Parser = require('rss-parser'); +const parser = new Parser(); + +module.exports = async (ctx) => { + let feedUrl, + title = '9To5', + link, + description; + + switch (ctx.params.type) { + case 'mac': + feedUrl = 'https://9to5mac.com/feed'; + title += 'Mac'; + description = 'Apple News & Mac Rumors Breaking All Day'; + break; + + case 'google': + feedUrl = 'https://9to5google.com/feed'; + title += 'Google'; + description = 'Google, Pixel news, Android, Home, Chrome OS, apps, more'; + break; + + case 'toys': + feedUrl = 'https://9to5toys.com/feed'; + title += 'Toys'; + description = 'New Gear, reviews and deals'; + break; + + default: + break; + } + + const feed = await parser.parseURL(feedUrl); + + const items = await Promise.all( + feed.items.splice(0, 10).map(async (item) => { + const response = await axios({ + method: 'get', + url: item.link, + }); + const description = utils.ProcessFeed(response.data); + + const single = { + title: item.title, + description, + pubDate: item.pubDate, + link: item.link, + author: item['dc:creator'], + }; + return Promise.resolve(single); + }) + ); + + ctx.state.data = { + title, + link, + description, + item: items, + }; +}; diff --git a/routes/9to5/utils.js b/routes/9to5/utils.js new file mode 100644 index 000000000..846a5c95b --- /dev/null +++ b/routes/9to5/utils.js @@ -0,0 +1,31 @@ +const cheerio = require('cheerio'); + +const ProcessFeed = (data) => { + const $ = cheerio.load(data); + const content = $('div[itemprop="articleBody"]'); + + // remove useless DOMs + content + .find('hr') + .nextAll() + .remove(); + + content.find('hr, ins.adsbygoogle, script').each((i, e) => { + $(e).remove(); + }); + + content.find('div').each((i, e) => { + if ($(e)[0].attribs.class) { + const classes = $(e)[0].attribs.class; + if (classes.match(/th\w{8}\sth\w{8}/g)) { + $(e).remove(); + } + } + }); + + return content.html(); +}; + +module.exports = { + ProcessFeed, +};