diff --git a/lib/v2/tfc-taiwan/index.js b/lib/v2/tfc-taiwan/index.js new file mode 100644 index 00000000000000..31bd0590e385b8 --- /dev/null +++ b/lib/v2/tfc-taiwan/index.js @@ -0,0 +1,36 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { baseUrl, parseList, parseItems } = require('./utils'); + +module.exports = async (ctx) => { + const requestPath = ctx.request.path; + const isTopic = requestPath.startsWith('/topic/'); + let link = baseUrl; + + if (isTopic) { + link += `/topic/${ctx.params.id}`; + } else if (requestPath === '/') { + link += `/articles/report`; + } else { + link += `/articles${requestPath}`; + } + + const { data: response } = await got(link); + const $ = cheerio.load(response); + + const list = $(`${isTopic ? '.view-grouping' : '.pane-clone-of-article'} .views-row-inner`) + .toArray() + .map((item) => parseList($(item))); + + const items = await parseItems(list, ctx.cache.tryGet); + + ctx.state.data = { + title: $('head title').text(), + description: $('head meta[name="description"]').attr('content'), + image: $('head meta[property="og:image"]').attr('content'), + logo: $('head link[rel="shortcut icon"]').attr('href'), + icon: $('head link[rel="shortcut icon"]').attr('href'), + link, + item: items, + }; +}; diff --git a/lib/v2/tfc-taiwan/maintainer.js b/lib/v2/tfc-taiwan/maintainer.js new file mode 100644 index 00000000000000..8880ce4c6de637 --- /dev/null +++ b/lib/v2/tfc-taiwan/maintainer.js @@ -0,0 +1,10 @@ +module.exports = { + '': ['TonyRL'], + '/': ['TonyRL'], + '/:type?': ['TonyRL'], // /info and /report + '/:type/:id+': ['TonyRL'], // /category/:id+ and /topic/:id + '/category/:id+': ['TonyRL'], + '/info': ['TonyRL'], + '/report': ['TonyRL'], + '/topic/:id': ['TonyRL'], +}; diff --git a/lib/v2/tfc-taiwan/radar.js b/lib/v2/tfc-taiwan/radar.js new file mode 100644 index 00000000000000..62e47ebe32cfa5 --- /dev/null +++ b/lib/v2/tfc-taiwan/radar.js @@ -0,0 +1,31 @@ +module.exports = { + 'tfc-taiwan.org.tw': { + _name: '台灣事實查核中心', + '.': [ + { + title: '專題', + docs: 'https://docs.rsshub.app/routes/other#tai-wan-shi-shi-cha-he-zhong-xin', + source: '/articles/category/:id+', + target: '/tfc-taiwan/category/:id', + }, + { + title: '最新相關資訊', + docs: 'https://docs.rsshub.app/routes/other#tai-wan-shi-shi-cha-he-zhong-xin', + source: ['/articles/info', '/'], + target: '/tfc-taiwan/info', + }, + { + title: '最新查核報告', + docs: 'https://docs.rsshub.app/routes/other#tai-wan-shi-shi-cha-he-zhong-xin', + source: ['/articles/report', '/'], + target: '/tfc-taiwan/report', + }, + { + title: '重點專區', + docs: 'https://docs.rsshub.app/routes/other#tai-wan-shi-shi-cha-he-zhong-xin', + source: '/topic/:id', + target: '/tfc-taiwan/topic/:id', + }, + ], + }, +}; diff --git a/lib/v2/tfc-taiwan/router.js b/lib/v2/tfc-taiwan/router.js new file mode 100644 index 00000000000000..0dc8040637e4be --- /dev/null +++ b/lib/v2/tfc-taiwan/router.js @@ -0,0 +1,7 @@ +module.exports = (router) => { + router.get('/', require('./index')); + router.get('/category/:id+', require('./index')); + router.get('/info', require('./index')); + router.get('/report', require('./index')); + router.get('/topic/:id', require('./index')); +}; diff --git a/lib/v2/tfc-taiwan/templates/article.art b/lib/v2/tfc-taiwan/templates/article.art new file mode 100644 index 00000000000000..56b78dc00c8157 --- /dev/null +++ b/lib/v2/tfc-taiwan/templates/article.art @@ -0,0 +1,7 @@ +{{ if headerImage }} +
+{{ /if }} + +{{ if content }} + {{@ content }} +{{ /if }} diff --git a/lib/v2/tfc-taiwan/utils.js b/lib/v2/tfc-taiwan/utils.js new file mode 100644 index 00000000000000..9cf6e49510acb1 --- /dev/null +++ b/lib/v2/tfc-taiwan/utils.js @@ -0,0 +1,56 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { join } = require('path'); +const { art } = require('@/utils/render'); +const asyncPool = require('tiny-async-pool'); +const { parseDate } = require('@/utils/parse-date'); + +const asyncPoolAll = async (...args) => { + const results = []; + for await (const result of asyncPool(...args)) { + results.push(result); + } + return results; +}; + +const baseUrl = 'https://tfc-taiwan.org.tw'; + +const parseList = (item) => { + const a = item.find('.entity-list-title a'); + return { + title: a.text(), + description: item.find('.entity-list-body').text(), + link: new URL(a.attr('href'), baseUrl).href, + pubDate: item.find('.post-date').length ? parseDate(item.find('.post-date').text(), 'YYYY-MM-DD') : undefined, + image: item.find('.entity-list-img img').attr('src').split('?')[0], + }; +}; + +const parseItems = (list, tryGet) => + asyncPoolAll(10, list, (item) => + tryGet(item.link, async () => { + const { data: response } = await got(item.link); + const $ = cheerio.load(response); + + $('.field-name-field-addthis, #fb-root, .fb-comments, .likecoin-embed, style[type="text/css"]').remove(); + + item.description = art(join(__dirname, 'templates/article.art'), { + headerImage: item.image, + content: $('#block-system-main .node-content').html(), + }); + + item.pubDate = $('meta[property="article:published_time"]').attr('content'); + item.updated = $('meta[property="article:modified_time"]').attr('content'); + item.category = $('.node-tags .field-item') + .toArray() + .map((item) => $(item).text()); + + return item; + }) + ); + +module.exports = { + baseUrl, + parseList, + parseItems, +}; diff --git a/website/docs/routes/other.md b/website/docs/routes/other.md index 6e7d262eceb921..9b0d1181a7969f 100644 --- a/website/docs/routes/other.md +++ b/website/docs/routes/other.md @@ -1116,6 +1116,28 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate +## 台灣事實查核中心 {#tai-wan-shi-shi-cha-he-zhong-xin} + +### 最新相關資訊 / 最新查核報告 {#tai-wan-shi-shi-cha-he-zhong-xin-zui-xin-xiang-guan-zi-xun-%2F-zui-xin-cha-he-bao-gao} + + + +| 最新相關資訊 | 最新查核報告 | +| ---------- | ---------- | +| info | report | + + + +### 專題 / 重點專區 {#tai-wan-shi-shi-cha-he-zhong-xin-zhuan-ti-%2F-zhong-dian-zhuan-qu} + + + +| 專題 | 重點專區 | +| -------- | ------- | +| category | topic | + + + ## 腾讯吐个槽 {#teng-xun-tu-ge-cao} ### 吐槽新帖 {#teng-xun-tu-ge-cao-tu-cao-xin-tie}