From 933558521062191e854c45a25bc3cbc11350fcc7 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 29 Aug 2023 20:54:06 +0800 Subject: [PATCH 1/8] fix: V2EX Route Exclude Duplicate Posts (#13144) * update: V2EX Route Exclude Duplicate Posts * use ctx.query.limit * refactor: migrate to v2 --------- Co-authored-by: pull[bot] <39814207+pull[bot]@users.noreply.github.com> --- lib/router.js | 6 ++--- lib/routes/v2ex/post.js | 39 ------------------------------- lib/v2/v2ex/maintainer.js | 5 ++++ lib/v2/v2ex/post.js | 35 +++++++++++++++++++++++++++ lib/v2/v2ex/radar.js | 35 +++++++++++++++++++++++++++ lib/v2/v2ex/router.js | 5 ++++ lib/{routes => v2}/v2ex/tab.js | 38 ++++++++++++++---------------- lib/{routes => v2}/v2ex/topics.js | 2 +- 8 files changed, 101 insertions(+), 64 deletions(-) delete mode 100644 lib/routes/v2ex/post.js create mode 100644 lib/v2/v2ex/maintainer.js create mode 100644 lib/v2/v2ex/post.js create mode 100644 lib/v2/v2ex/radar.js create mode 100644 lib/v2/v2ex/router.js rename lib/{routes => v2}/v2ex/tab.js (62%) rename lib/{routes => v2}/v2ex/topics.js (96%) diff --git a/lib/router.js b/lib/router.js index 8f859a2b69d801..e61ec26abce1bc 100644 --- a/lib/router.js +++ b/lib/router.js @@ -77,9 +77,9 @@ router.get('/huya/live/:id', lazyloadRouteHandler('./routes/huya/live')); router.get('/showroom/room/:id', lazyloadRouteHandler('./routes/showroom/room')); // v2ex -router.get('/v2ex/topics/:type', lazyloadRouteHandler('./routes/v2ex/topics')); -router.get('/v2ex/post/:postid', lazyloadRouteHandler('./routes/v2ex/post')); -router.get('/v2ex/tab/:tabid', lazyloadRouteHandler('./routes/v2ex/tab')); +// router.get('/v2ex/topics/:type', lazyloadRouteHandler('./routes/v2ex/topics')); +// router.get('/v2ex/post/:postid', lazyloadRouteHandler('./routes/v2ex/post')); +// router.get('/v2ex/tab/:tabid', lazyloadRouteHandler('./routes/v2ex/tab')); // f-droid router.get('/fdroid/apprelease/:app', lazyloadRouteHandler('./routes/fdroid/apprelease')); diff --git a/lib/routes/v2ex/post.js b/lib/routes/v2ex/post.js deleted file mode 100644 index 5b4d26c4d723af..00000000000000 --- a/lib/routes/v2ex/post.js +++ /dev/null @@ -1,39 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); - -module.exports = async (ctx) => { - const postid = ctx.params.postid; - const pageUrl = `https://www.v2ex.com/t/${postid}`; - - const response = await got({ - method: 'get', - url: pageUrl, - }); - - const $ = cheerio.load(response.data); - const list = $('[id^="r_"]').get(); - - ctx.state.data = { - title: `V2EX-${$('.header h1').text()}`, - link: pageUrl, - description: $('.topic_content').text(), - item: list - .map((item) => { - const post = $(item); - const reply_content = post.find('.reply_content').first(); - const no = post.find('.no').first(); - - return { - title: `#${no.text()} ${reply_content.text()}`, - description: reply_content.html(), - guid: post.attr('id'), - link: `${pageUrl}#${post.attr('id')}`, - author: post.find('.dark').first().text(), - pubDate: parseDate(post.find('.ago').attr('title')), - }; - }) - .reverse(), - allowEmpty: true, - }; -}; diff --git a/lib/v2/v2ex/maintainer.js b/lib/v2/v2ex/maintainer.js new file mode 100644 index 00000000000000..01c685653ac57d --- /dev/null +++ b/lib/v2/v2ex/maintainer.js @@ -0,0 +1,5 @@ +module.exports = { + '/post/:postid': ['kt286'], + '/tab/:tabid': ['liyefox'], + '/topics/:type': ['WhiteWorld'], +}; diff --git a/lib/v2/v2ex/post.js b/lib/v2/v2ex/post.js new file mode 100644 index 00000000000000..b933692cfbf113 --- /dev/null +++ b/lib/v2/v2ex/post.js @@ -0,0 +1,35 @@ +const got = require('@/utils/got'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const { postid } = ctx.params; + const pageUrl = `https://www.v2ex.com/t/${postid}`; + + const { data: topicResponse } = await got('https://www.v2ex.com/api/topics/show.json', { + searchParams: { + id: postid, + }, + }); + + const { data: replies } = await got('https://www.v2ex.com/api/replies/show.json', { + searchParams: { + topic_id: postid, + }, + }); + + const topic = topicResponse[0]; + + ctx.state.data = { + title: `V2EX-${topic.title}`, + link: pageUrl, + description: topic.content, + item: replies.map((item, index) => ({ + title: `#${index + 1} ${item.content}`, + description: item.content_rendered, + link: `${pageUrl}#r_${item.id}`, + author: item.member.username, + pubDate: parseDate(item.created, 'X'), + })), + allowEmpty: true, + }; +}; diff --git a/lib/v2/v2ex/radar.js b/lib/v2/v2ex/radar.js new file mode 100644 index 00000000000000..f3a9d43bbfcdf6 --- /dev/null +++ b/lib/v2/v2ex/radar.js @@ -0,0 +1,35 @@ +module.exports = { + 'v2ex.com': { + _name: 'V2EX', + '.': [ + { + title: '最热 / 最新主题', + docs: 'https://docs.rsshub.app/routes/v2ex', + source: ['/'], + target: (_, url) => { + const { searchParams } = new URL(url); + if (searchParams.get('tab') === 'all' || searchParams.get('tab') === 'hot') { + return `/v2ex/topics/${searchParams.get('tab')?.replace('all', 'latest')}`; + } + }, + }, + { + title: '帖子', + docs: 'https://docs.rsshub.app/routes/v2ex', + source: ['/t/:postid'], + target: '/v2ex/post/:postid', + }, + { + title: '标签', + docs: 'https://docs.rsshub.app/routes/v2ex', + source: ['/'], + target: (_, url) => { + const { searchParams } = new URL(url); + if (searchParams.get('tab') && searchParams.get('tab') !== 'all' && searchParams.get('tab') !== 'hot') { + return `/v2ex/tab/${searchParams.get('tab')}`; + } + }, + }, + ], + }, +}; diff --git a/lib/v2/v2ex/router.js b/lib/v2/v2ex/router.js new file mode 100644 index 00000000000000..c17828c761aec2 --- /dev/null +++ b/lib/v2/v2ex/router.js @@ -0,0 +1,5 @@ +module.exports = (router) => { + router.get('/post/:postid', require('./post')); + router.get('/tab/:tabid', require('./tab')); + router.get('/topics/:type', require('./topics')); +}; diff --git a/lib/routes/v2ex/tab.js b/lib/v2/v2ex/tab.js similarity index 62% rename from lib/routes/v2ex/tab.js rename to lib/v2/v2ex/tab.js index 140eca922d4750..71e141dc32eabe 100644 --- a/lib/routes/v2ex/tab.js +++ b/lib/v2/v2ex/tab.js @@ -13,24 +13,21 @@ module.exports = async (ctx) => { const $ = cheerio.load(response.data); const links = $('span.item_title > a') - .map((i, link) => `${host}${$(link).attr('href')}`) - .slice(0, 10) - .get(); + .toArray() + .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 10) + .map((link) => `${host}${$(link).attr('href').replace(/#.*$/, '')}`); + const items = await Promise.all( - links.map(async (pageUrl) => { - const cacheKey = `v2ex-${pageUrl}`; - const cacheValue = await ctx.cache.get(cacheKey); - let post = {}; - if (cacheValue) { - post = cacheValue; - } else { + links.map((link) => + ctx.cache.tryGet(`v2ex-${link}`, async () => { const response = await got({ method: 'get', - url: pageUrl, + url: link, }); + const $ = cheerio.load(response.data); - const list = $('[id^="r_"]').get(); - const reply_content = list + const list = $('[id^="r_"]').toArray(); + const replyContent = list .map((item) => { const post = $(item); const content = post.find('.reply_content').html(); @@ -39,18 +36,17 @@ module.exports = async (ctx) => { return `

#${no}: ${author}
${content}

`; }) .join(''); - post = { + + return { title: $('.header h1').text(), - link: pageUrl, - guid: pageUrl, - description: $('div.topic_content').html() + `
${reply_content}
`, + link, + description: `${$('div.topic_content').html()}
${replyContent}
`, author: $('div.header > small > a').text(), }; - ctx.cache.set(cacheKey, post); - } - return Promise.resolve(post); - }) + }) + ) ); + ctx.state.data = { title: `V2EX-${tabid}`, link: pageUrl, diff --git a/lib/routes/v2ex/topics.js b/lib/v2/v2ex/topics.js similarity index 96% rename from lib/routes/v2ex/topics.js rename to lib/v2/v2ex/topics.js index db3097d9c15531..28062030b8d85f 100644 --- a/lib/routes/v2ex/topics.js +++ b/lib/v2/v2ex/topics.js @@ -2,7 +2,7 @@ const got = require('@/utils/got'); const { parseDate } = require('@/utils/parse-date'); module.exports = async (ctx) => { - const type = ctx.params.type; + const { type } = ctx.params; const { data } = await got(`https://www.v2ex.com/api/topics/${type}.json`); From a6e935630819cf2f46296e39af592023c1a98be3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 21:09:52 +0800 Subject: [PATCH 2/8] chore(deps): bump @sentry/node from 7.64.0 to 7.65.0 (#13148) * chore(deps): bump @sentry/node from 7.64.0 to 7.65.0 Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.64.0 to 7.65.0. - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/7.64.0...7.65.0) --- updated-dependencies: - dependency-name: "@sentry/node" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 44 ++++++++++++++++++++++---------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 2a0310ae3c3de2..eac75938dc1b53 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@koa/router": "12.0.0", "@notionhq/client": "2.2.12", "@postlight/parser": "2.2.3", - "@sentry/node": "7.64.0", + "@sentry/node": "7.65.0", "aes-js": "3.1.2", "art-template": "4.13.2", "bbcodejs": "0.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e71cc742c6a551..aa82f2a7d5c38f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ dependencies: specifier: 2.2.3 version: 2.2.3 '@sentry/node': - specifier: 7.64.0 - version: 7.64.0 + specifier: 7.65.0 + version: 7.65.0 aes-js: specifier: 3.1.2 version: 3.1.2 @@ -1153,33 +1153,33 @@ packages: selderee: 0.11.0 dev: false - /@sentry-internal/tracing@7.64.0: - resolution: {integrity: sha512-1XE8W6ki7hHyBvX9hfirnGkKDBKNq3bDJyXS86E0bYVDl94nvbRM9BD9DHsCFetqYkVm1yDGEK+6aUVs4CztoQ==} + /@sentry-internal/tracing@7.65.0: + resolution: {integrity: sha512-TEYkiq5vKr1Y79YIu+UYr1sO3vEMttQOBsOZLziDbqiC7TvKUARBR4W5XWfb9qBVDeon87EFNKluW0/+7rzYWw==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.64.0 - '@sentry/types': 7.64.0 - '@sentry/utils': 7.64.0 + '@sentry/core': 7.65.0 + '@sentry/types': 7.65.0 + '@sentry/utils': 7.65.0 tslib: 2.6.2 dev: false - /@sentry/core@7.64.0: - resolution: {integrity: sha512-IzmEyl5sNG7NyEFiyFHEHC+sizsZp9MEw1+RJRLX6U5RITvcsEgcajSkHQFafaBPzRrcxZMdm47Cwhl212LXcw==} + /@sentry/core@7.65.0: + resolution: {integrity: sha512-EwZABW8CtAbRGXV69FqeCqcNApA+Jbq308dko0W+MFdFe+9t2RGubUkpPxpJcbWy/dN2j4LiuENu1T7nWn0ZAQ==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.64.0 - '@sentry/utils': 7.64.0 + '@sentry/types': 7.65.0 + '@sentry/utils': 7.65.0 tslib: 2.6.2 dev: false - /@sentry/node@7.64.0: - resolution: {integrity: sha512-wRi0uTnp1WSa83X2yLD49tV9QPzGh5e42IKdIDBiQ7lV9JhLILlyb34BZY1pq6p4dp35yDasDrP3C7ubn7wo6A==} + /@sentry/node@7.65.0: + resolution: {integrity: sha512-zRCHOO7vIQukgFdEib3X7nP7HA9Uyc/o4QMtBnAREaYKzERGRnArvaB3Na0bXsuLVCOELoCAlrzFH3apmgxBQw==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.64.0 - '@sentry/core': 7.64.0 - '@sentry/types': 7.64.0 - '@sentry/utils': 7.64.0 + '@sentry-internal/tracing': 7.65.0 + '@sentry/core': 7.65.0 + '@sentry/types': 7.65.0 + '@sentry/utils': 7.65.0 cookie: 0.4.2 https-proxy-agent: 5.0.1 lru_map: 0.3.3 @@ -1188,16 +1188,16 @@ packages: - supports-color dev: false - /@sentry/types@7.64.0: - resolution: {integrity: sha512-LqjQprWXjUFRmzIlUjyA+KL+38elgIYmAeoDrdyNVh8MK5IC1W2Lh1Q87b4yOiZeMiIhIVNBd7Ecoh2rodGrGA==} + /@sentry/types@7.65.0: + resolution: {integrity: sha512-YYq7IDLLhpSBTmHoyWFtq/5ZDaEJ01r7xGuhB0aSIq33cm2I7im/B3ipzoOP/ukGZSIhuYVW9t531xZEO0+6og==} engines: {node: '>=8'} dev: false - /@sentry/utils@7.64.0: - resolution: {integrity: sha512-HRlM1INzK66Gt+F4vCItiwGKAng4gqzCR4C5marsL3qv6SrKH98dQnCGYgXluSWaaa56h97FRQu7TxCk6jkSvQ==} + /@sentry/utils@7.65.0: + resolution: {integrity: sha512-2JEBf4jzRSClhp+LJpX/E3QgHEeKvXqFMeNhmwQ07qqd6szhfH2ckYFj4gXk6YiGGY4Act3C6oxLfdZovG71bw==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.64.0 + '@sentry/types': 7.65.0 tslib: 2.6.2 dev: false From 560480cfc39ec2bc70a3bf1b96b680553e197753 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 21:56:39 +0800 Subject: [PATCH 3/8] chore(deps): bump puppeteer from 21.1.0 to 21.1.1 (#13149) * chore(deps): bump puppeteer from 21.1.0 to 21.1.1 Bumps [puppeteer](https://github.com/puppeteer/puppeteer) from 21.1.0 to 21.1.1. - [Release notes](https://github.com/puppeteer/puppeteer/releases) - [Changelog](https://github.com/puppeteer/puppeteer/blob/main/release-please-config.json) - [Commits](https://github.com/puppeteer/puppeteer/compare/puppeteer-v21.1.0...puppeteer-v21.1.1) --- updated-dependencies: - dependency-name: puppeteer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index eac75938dc1b53..96b1b96ea98471 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "pidusage": "3.0.2", "plist": "3.1.0", "proxy-chain": "2.3.0", - "puppeteer": "21.1.0", + "puppeteer": "21.1.1", "puppeteer-extra": "3.3.6", "puppeteer-extra-plugin-stealth": "2.11.2", "puppeteer-extra-plugin-user-data-dir": "2.4.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa82f2a7d5c38f..f1b793cdd8e218 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -138,11 +138,11 @@ dependencies: specifier: 2.3.0 version: 2.3.0 puppeteer: - specifier: 21.1.0 - version: 21.1.0 + specifier: 21.1.1 + version: 21.1.1 puppeteer-extra: specifier: 3.3.6 - version: 3.3.6(puppeteer@21.1.0) + version: 3.3.6(puppeteer@21.1.1) puppeteer-extra-plugin-stealth: specifier: 2.11.2 version: 2.11.2(puppeteer-extra@3.3.6) @@ -2138,8 +2138,8 @@ packages: engines: {node: '>=10'} dev: true - /chromium-bidi@0.4.20(devtools-protocol@0.0.1159816): - resolution: {integrity: sha512-ruHgVZFEv00mAQMz1tQjfjdG63jiPWrQPF6HLlX2ucqLqVTJoWngeBEKHaJ6n1swV/HSvgnBNbtTRIlcVyW3Fw==} + /chromium-bidi@0.4.22(devtools-protocol@0.0.1159816): + resolution: {integrity: sha512-wR7Y9Ioez+cNXT4ZP7VNM1HRTljpNnMSLw4/RnwhhZUP4yCU7kIQND00YiktuHekch68jklGPK1q9Jkb29+fQg==} peerDependencies: devtools-protocol: '*' dependencies: @@ -6153,12 +6153,12 @@ packages: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} - /puppeteer-core@21.1.0: - resolution: {integrity: sha512-ggfTj09jo81Y6M4DyNj80GrY6Pip+AtDUgGljqoSzP6FG5nz5Aju6Cs/X147fLgkJ4UKTb736U6cDp0ssLzN5Q==} + /puppeteer-core@21.1.1: + resolution: {integrity: sha512-Tlcajcf44zwfa9Sbwv3T8BtaNMJ69wtpHIxwl2NOBTyTK3D1wppQovXTjfw0TDOm3a16eCfQ+5BMi3vRQ4kuAQ==} engines: {node: '>=16.3.0'} dependencies: '@puppeteer/browsers': 1.7.0 - chromium-bidi: 0.4.20(devtools-protocol@0.0.1159816) + chromium-bidi: 0.4.22(devtools-protocol@0.0.1159816) cross-fetch: 4.0.0 debug: 4.3.4 devtools-protocol: 0.0.1159816 @@ -6183,7 +6183,7 @@ packages: optional: true dependencies: debug: 4.3.4 - puppeteer-extra: 3.3.6(puppeteer@21.1.0) + puppeteer-extra: 3.3.6(puppeteer@21.1.1) puppeteer-extra-plugin: 3.2.3(puppeteer-extra@3.3.6) puppeteer-extra-plugin-user-preferences: 2.4.1(puppeteer-extra@3.3.6) transitivePeerDependencies: @@ -6204,7 +6204,7 @@ packages: dependencies: debug: 4.3.4 fs-extra: 10.1.0 - puppeteer-extra: 3.3.6(puppeteer@21.1.0) + puppeteer-extra: 3.3.6(puppeteer@21.1.1) puppeteer-extra-plugin: 3.2.3(puppeteer-extra@3.3.6) rimraf: 3.0.2 transitivePeerDependencies: @@ -6225,7 +6225,7 @@ packages: dependencies: debug: 4.3.4 deepmerge: 4.3.1 - puppeteer-extra: 3.3.6(puppeteer@21.1.0) + puppeteer-extra: 3.3.6(puppeteer@21.1.1) puppeteer-extra-plugin: 3.2.3(puppeteer-extra@3.3.6) puppeteer-extra-plugin-user-data-dir: 2.4.1(puppeteer-extra@3.3.6) transitivePeerDependencies: @@ -6247,12 +6247,12 @@ packages: '@types/debug': 4.1.8 debug: 4.3.4 merge-deep: 3.0.3 - puppeteer-extra: 3.3.6(puppeteer@21.1.0) + puppeteer-extra: 3.3.6(puppeteer@21.1.1) transitivePeerDependencies: - supports-color dev: false - /puppeteer-extra@3.3.6(puppeteer@21.1.0): + /puppeteer-extra@3.3.6(puppeteer@21.1.1): resolution: {integrity: sha512-rsLBE/6mMxAjlLd06LuGacrukP2bqbzKCLzV1vrhHFavqQE/taQ2UXv3H5P0Ls7nsrASa+6x3bDbXHpqMwq+7A==} engines: {node: '>=8'} peerDependencies: @@ -6270,19 +6270,19 @@ packages: '@types/debug': 4.1.8 debug: 4.3.4 deepmerge: 4.3.1 - puppeteer: 21.1.0 + puppeteer: 21.1.1 transitivePeerDependencies: - supports-color dev: false - /puppeteer@21.1.0: - resolution: {integrity: sha512-x0KfxVd7Hsefq8nzH1AAdSnYw5HEKI4QPeexBmx7nO29jDoEKNE+75G8zQ0E57ZOny/vAZZptCFdD3A7PkeESQ==} + /puppeteer@21.1.1: + resolution: {integrity: sha512-2TLntjGA4qLrI9/8N0UK/5OoZJ2Ue7QgphN2SD+RsaHiha12AEiVyMGsB+i6LY1IoPAtEgYIjblQ7lw3kWDNRw==} engines: {node: '>=16.3.0'} requiresBuild: true dependencies: '@puppeteer/browsers': 1.7.0 cosmiconfig: 8.2.0 - puppeteer-core: 21.1.0 + puppeteer-core: 21.1.1 transitivePeerDependencies: - bufferutil - encoding From ea22ebcb3dea24a91e3e4ed6c858bc05163e1421 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 06:50:36 +0800 Subject: [PATCH 4/8] chore(deps-dev): bump prettier from 3.0.2 to 3.0.3 (#13158) * chore(deps-dev): bump prettier from 3.0.2 to 3.0.3 Bumps [prettier](https://github.com/prettier/prettier) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * chore: fix pnpm install --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 96b1b96ea98471..bbf50fb495c447 100644 --- a/package.json +++ b/package.json @@ -165,7 +165,7 @@ "mockdate": "3.0.5", "nock": "13.3.3", "nodemon": "3.0.1", - "prettier": "3.0.2", + "prettier": "3.0.3", "remark": "13.0.0", "remark-frontmatter": "3.0.0", "remark-gfm": "1.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1b793cdd8e218..a194f669eff6e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -219,7 +219,7 @@ devDependencies: version: 16.0.2(eslint@8.48.0) eslint-plugin-prettier: specifier: 5.0.0 - version: 5.0.0(eslint-config-prettier@9.0.0)(eslint@8.48.0)(prettier@3.0.2) + version: 5.0.0(eslint-config-prettier@9.0.0)(eslint@8.48.0)(prettier@3.0.3) eslint-plugin-yml: specifier: 1.8.0 version: 1.8.0(eslint@8.48.0) @@ -248,8 +248,8 @@ devDependencies: specifier: 3.0.1 version: 3.0.1 prettier: - specifier: 3.0.2 - version: 3.0.2 + specifier: 3.0.3 + version: 3.0.3 remark: specifier: 13.0.0 version: 13.0.0 @@ -267,7 +267,7 @@ devDependencies: version: 9.0.0 remark-preset-prettier: specifier: 0.5.1 - version: 0.5.1(prettier@3.0.2) + version: 0.5.1(prettier@3.0.3) remark-stringify: specifier: 9.0.1 version: 9.0.1 @@ -2927,7 +2927,7 @@ packages: semver: 7.5.4 dev: true - /eslint-plugin-prettier@5.0.0(eslint-config-prettier@9.0.0)(eslint@8.48.0)(prettier@3.0.2): + /eslint-plugin-prettier@5.0.0(eslint-config-prettier@9.0.0)(eslint@8.48.0)(prettier@3.0.3): resolution: {integrity: sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -2943,7 +2943,7 @@ packages: dependencies: eslint: 8.48.0 eslint-config-prettier: 9.0.0(eslint@8.48.0) - prettier: 3.0.2 + prettier: 3.0.3 prettier-linter-helpers: 1.0.0 synckit: 0.8.5 dev: true @@ -6075,8 +6075,8 @@ packages: fast-diff: 1.3.0 dev: true - /prettier@3.0.2: - resolution: {integrity: sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==} + /prettier@3.0.3: + resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} engines: {node: '>=14'} hasBin: true dev: true @@ -6441,13 +6441,13 @@ packages: - supports-color dev: true - /remark-preset-prettier@0.5.1(prettier@3.0.2): + /remark-preset-prettier@0.5.1(prettier@3.0.3): resolution: {integrity: sha512-cJx49HCHwA/3EWjIDiRTWPBBpGSkJlXOpcjdqcT6rGFFE+gjCrGSbNdgBQiLbBqXippZFD0OrI4bOWsWhulKrw==} engines: {node: '>=12'} peerDependencies: prettier: '>=1.0.0' dependencies: - prettier: 3.0.2 + prettier: 3.0.3 dev: true /remark-stringify@9.0.1: From d5b1bebe8736244bb71d8beb64ae6a64edec9112 Mon Sep 17 00:00:00 2001 From: Andvari <31068367+dzx-dzx@users.noreply.github.com> Date: Wed, 30 Aug 2023 19:57:00 +0800 Subject: [PATCH 5/8] fix(route): Fix Discourse link (#13167) --- lib/v2/discourse/notifications.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/v2/discourse/notifications.js b/lib/v2/discourse/notifications.js index b781f3d048c7a5..45c35f1161c757 100644 --- a/lib/v2/discourse/notifications.js +++ b/lib/v2/discourse/notifications.js @@ -7,7 +7,7 @@ module.exports = async (ctx) => { const response = await got(`${link}/notifications.json`, { headers: { 'User-Api-Key': key } }).json(); const items = response.notifications.map((e) => ({ title: e.fancy_title ?? e.data.badge_name, - link: `${link}/${e.data.hasOwnProperty('badge_id') ? `badges/${e.data.badge_id}/${e.data.badge_slug}?username=${e.data.username}` : `${e.topic_id}/${e.post_number}`}`, + link: `${link}/${e.data.hasOwnProperty('badge_id') ? `badges/${e.data.badge_id}/${e.data.badge_slug}?username=${e.data.username}` : `t/topic/${e.topic_id}/${e.post_number}`}`, pubDate: new Date(e.created_at), author: e.data.display_username ?? e.data.username, category: `notification_type:${e.notification_type}`, From 05bb835014a19798e65223ec19eb31b0905c3c9d Mon Sep 17 00:00:00 2001 From: Yuxuan Lu Date: Wed, 30 Aug 2023 23:03:47 +0800 Subject: [PATCH 6/8] feat(route): Add ICBC; Fix BOC Date & trimming space (#13138) * Add ICBC; Fix BOC Date & trimming space * use http instead of https * Update website/docs/routes/other.md * Update lib/routes/boc/whpj.js * refactor: migrate to v2 --------- --- lib/router.js | 2 +- lib/v2/boc/maintainer.js | 3 + lib/v2/boc/radar.js | 13 +++ lib/v2/boc/router.js | 3 + lib/{routes => v2}/boc/whpj.js | 16 ++-- lib/v2/icbc/maintainer.js | 3 + lib/v2/icbc/radar.js | 13 +++ lib/v2/icbc/router.js | 3 + lib/v2/icbc/whpj.js | 57 +++++++++++++ website/docs/routes/other.md | 148 ++++++++++++++++++--------------- 10 files changed, 184 insertions(+), 77 deletions(-) create mode 100644 lib/v2/boc/maintainer.js create mode 100644 lib/v2/boc/radar.js create mode 100644 lib/v2/boc/router.js rename lib/{routes => v2}/boc/whpj.js (88%) create mode 100644 lib/v2/icbc/maintainer.js create mode 100644 lib/v2/icbc/radar.js create mode 100644 lib/v2/icbc/router.js create mode 100644 lib/v2/icbc/whpj.js diff --git a/lib/router.js b/lib/router.js index e61ec26abce1bc..76f2a5b44f9187 100644 --- a/lib/router.js +++ b/lib/router.js @@ -908,7 +908,7 @@ router.get('/paidai/bbs', lazyloadRouteHandler('./routes/paidai/bbs')); router.get('/paidai/news', lazyloadRouteHandler('./routes/paidai/news')); // 中国银行 -router.get('/boc/whpj/:format?', lazyloadRouteHandler('./routes/boc/whpj')); +// router.get('/boc/whpj/:format?', lazyloadRouteHandler('./routes/boc/whpj')); // 漫画db router.get('/manhuadb/comics/:id', lazyloadRouteHandler('./routes/manhuadb/comics')); diff --git a/lib/v2/boc/maintainer.js b/lib/v2/boc/maintainer.js new file mode 100644 index 00000000000000..34630d35f0e018 --- /dev/null +++ b/lib/v2/boc/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/whpj/:format?': ['LogicJake', 'HenryQW'], +}; diff --git a/lib/v2/boc/radar.js b/lib/v2/boc/radar.js new file mode 100644 index 00000000000000..1fe2e8d851760c --- /dev/null +++ b/lib/v2/boc/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'boc.cn': { + _name: '中国银行', + '.': [ + { + title: '外汇牌价', + docs: 'https://docs.rsshub.app/routes/others#zhong-guo-yin-hang', + source: ['/sourcedb/whpj', '/'], + target: '/boc/whpj', + }, + ], + }, +}; diff --git a/lib/v2/boc/router.js b/lib/v2/boc/router.js new file mode 100644 index 00000000000000..cbc502fe41a76f --- /dev/null +++ b/lib/v2/boc/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/whpj/:format?', require('./whpj')); +}; diff --git a/lib/routes/boc/whpj.js b/lib/v2/boc/whpj.js similarity index 88% rename from lib/routes/boc/whpj.js rename to lib/v2/boc/whpj.js index edeaa885eb5cd6..44708d8a9fd850 100644 --- a/lib/routes/boc/whpj.js +++ b/lib/v2/boc/whpj.js @@ -2,8 +2,8 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); module.exports = async (ctx) => { - const link = 'http://www.boc.cn/sourcedb/whpj/'; - const response = await got.get(link); + const link = 'https://www.boc.cn/sourcedb/whpj/'; + const response = await got(link); const $ = cheerio.load(response.data); const format = ctx.params.format; @@ -40,11 +40,12 @@ module.exports = async (ctx) => { const out = $('div.publish table tbody tr') .slice(2) + .toArray() .map(function () { const zh_name = $(this).find('td:nth-child(1)').text(); const en_name = en_names[zh_name] || ''; - const name = `${zh_name} ${en_name} `; - const date = `${$(this).find('td:nth-child(7)').text()} ${$(this).find('td:nth-child(8)').text()}`; + const name = `${zh_name} ${en_name}`; + const date = $(this).find('td:nth-child(7)').text(); const xhmr = `现汇买入价:${$(this).find('td:nth-child(2)').text()}`; @@ -77,7 +78,7 @@ module.exports = async (ctx) => { case 'xcmc': return `${name} ${xcmc}`; default: - return name + content; + return `${name} ${content}`; } }; @@ -85,11 +86,10 @@ module.exports = async (ctx) => { title: formatTitle(), description: content.replace(/\s/g, '
'), pubDate: new Date(date).toUTCString(), - guid: name + date, + guid: `${name} ${content}`, }; return info; - }) - .get(); + }); ctx.state.data = { title: '中国银行外汇牌价', diff --git a/lib/v2/icbc/maintainer.js b/lib/v2/icbc/maintainer.js new file mode 100644 index 00000000000000..73ec9a37a53a27 --- /dev/null +++ b/lib/v2/icbc/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/whpj/:format?': ['leoleoasd'], +}; diff --git a/lib/v2/icbc/radar.js b/lib/v2/icbc/radar.js new file mode 100644 index 00000000000000..81641ba6155a0b --- /dev/null +++ b/lib/v2/icbc/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'icbc.com.cn': { + _name: '中国工商银行', + '.': [ + { + title: '外汇牌价', + docs: 'https://docs.rsshub.app/other#zhong-guo-gong-shang-yin-hang', + source: ['/column/1438058341489590354.html'], + target: '/icbc/whpj', + }, + ], + }, +}; diff --git a/lib/v2/icbc/router.js b/lib/v2/icbc/router.js new file mode 100644 index 00000000000000..cbc502fe41a76f --- /dev/null +++ b/lib/v2/icbc/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/whpj/:format?', require('./whpj')); +}; diff --git a/lib/v2/icbc/whpj.js b/lib/v2/icbc/whpj.js new file mode 100644 index 00000000000000..68386d2529a64c --- /dev/null +++ b/lib/v2/icbc/whpj.js @@ -0,0 +1,57 @@ +const got = require('@/utils/got'); + +module.exports = async (ctx) => { + // yes, insecure + // their openssl version isn't safe anyway (https://stackoverflow.com/questions/75763525/curl-35-error0a000152ssl-routinesunsafe-legacy-renegotiation-disabled) + const { data } = await got('http://papi.icbc.com.cn/exchanges/ns/getLatest'); + const format = ctx.params.format; + + ctx.state.data = { + title: '中国工商银行外汇牌价', + link: 'https://www.icbc.com.cn/column/1438058341489590354.html', + item: data.data.map((item) => { + const name = `${item.currencyCHName} ${item.currencyENName}`; + + const xhmr = `现汇买入价:${item.foreignBuy}`; + + const xcmr = `现钞买入价:${item.cashBuy}`; + + const xhmc = `现汇卖出价:${item.foreignSell}`; + + const xcmc = `现钞卖出价:${item.cashSell}`; + + const zs = `参考价:${item.reference}`; + + const content = `${xhmr} ${xcmr} ${xhmc} ${xcmc} ${zs}`; + + const formatTitle = () => { + switch (format) { + case 'short': + return name; + case 'xh': + return `${name} ${xhmr} ${xhmc}`; + case 'xc': + return `${name} ${xcmr} ${xcmc}`; + case 'zs': + return `${name} ${zs}`; + case 'xhmr': + return `${name} ${xhmr}`; + case 'xhmc': + return `${name} ${xhmc}`; + case 'xcmr': + return `${name} ${xcmr}`; + case 'xcmc': + return `${name} ${xcmc}`; + default: + return `${name} ${content}`; + } + }; + return { + title: formatTitle(), + pubDate: new Date(`${item.publishDate} ${item.publishTime}`), + description: content.replace(/\s/g, '
'), + guid: `${name} ${item.publishDate} ${item.publishTime}`, + }; + }), + }; +}; diff --git a/website/docs/routes/other.md b/website/docs/routes/other.md index 7019b71b854996..5f7ec11fc5637b 100644 --- a/website/docs/routes/other.md +++ b/website/docs/routes/other.md @@ -39,7 +39,7 @@ Copy the URL of the 591 filter housing page and remove the front part " | 中国/大陆 | 대한민국 | Europe | United States | Russia | Global | -| --------- | -------- | ------ | ------------- | ------ | ------ | -| cn | kr | eu | us | ru | en | +|-----------|------|--------|---------------|--------|--------| +| cn | kr | eu | us | ru | en | @@ -89,8 +89,8 @@ See [#app-store-mac-app-store](/routes/program-update#app-store-mac-app-store) | 대한민국 | Europe | United States | Russia | Global | -| -------- | ------ | ------------- | ------ | ------ | -| kr | eu | us | ru | en | +|------|--------|---------------|--------|--------| +| kr | eu | us | ru | en | @@ -182,7 +182,7 @@ Official Website: [https://www.ssm.gov.mo/apps1/PreventWuhanInfection/en.aspx](h | Chinese | English | Portuguese | -| ------- | ------- | ---------- | +|---------|---------|------------| | ch | en | pt | ### Singapore Ministry of Health - Past Updates on 2019-nCov Local Situation in Singapore {#corona-virus-disease-2019-singapore-ministry-of-health---past-updates-on-2019-ncov-local-situation-in-singapore} @@ -276,7 +276,7 @@ Official Website: | All | Circuits | Workshop | Craft | Cooking | Living | Outside | Teachers | -| --- | -------- | -------- | ----- | ------- | ------ | ------- | -------- | +|-----|----------|----------|-------|---------|--------|---------|----------| | | circuits | workshop | craft | cooking | living | outside | teachers | @@ -300,7 +300,7 @@ Official Website: | Japanese | English | -| -------- | ------- | +|----------|---------| | ja | en | @@ -312,7 +312,7 @@ Official Website: | Story | Recipes | Tips and Techniques | -| ----- | ------- | ------------------- | +|-------|---------|---------------------| | story | recipes | tips-and-techniques | @@ -340,13 +340,13 @@ RSS source in the original site is outdated. #### `job_types` list | Full Time | Part Time | Contractor | All | -| --------- | --------- | ---------- | --- | +|-----------|-----------|------------|-----| | F | P | C | all | #### `exp_levels` list | Intership | Entry Level | Associate | Mid-Senior Level | Director | All | -| --------- | ----------- | --------- | ---------------- | -------- | --- | +|-----------|-------------|-----------|------------------|----------|-----| | 1 | 2 | 3 | 4 | 5 | all | For example: @@ -366,13 +366,13 @@ For example: 另外,可以通过添加额外的以下 query 参数来输出满足特定要求的工作职位: -| 参数 | 描述 | 举例 | 默认值 | -| ---------- | ------------------------------------------------- | ------------------------------------------------------- | ------- | -| `geo` | geo 编码 | 102890883(中国)、102772228(上海)、103873152(北京) | 空 | -| `remote` | 是否只显示远程工作 | `true/false` | `false` | -| `location` | 工作地点 | `china/shanghai/beijing` | 空 | -| `relevant` | 排序方式 (true: 按相关性排序,false: 按日期排序) | `true/false` | `false` | -| `period` | 发布时间 | `1/7/30` | 空 | +| 参数 | 描述 | 举例 | 默认值 | +|------------|-----------------------------------------------|-------------------------------------------------|---------| +| `geo` | geo 编码 | 102890883(中国)、102772228(上海)、103873152(北京) | 空 | +| `remote` | 是否只显示远程工作 | `true/false` | `false` | +| `location` | 工作地点 | `china/shanghai/beijing` | 空 | +| `relevant` | 排序方式 (true: 按相关性排序,false: 按日期排序) | `true/false` | `false` | +| `period` | 发布时间 | `1/7/30` | 空 | 例如: [`/linkedin/cn/jobs/Software?location=shanghai&period=1`](https://rsshub.app/linkedin/cn/jobs/Software?location=shanghai&period=1): 查找所有在上海的今日发布的所有 Software 工作 @@ -451,7 +451,7 @@ For example: | Physics | Chemistry | Physiology or Medicine | Literature | Peace | Economic Science | -| ------- | --------- | ---------------------- | ---------- | ----- | ----------------- | +|---------|-----------|------------------------|------------|-------|-------------------| | physics | chemistry | physiology-or-medicine | literature | peace | economic-sciences | @@ -525,7 +525,7 @@ please refer to the [Notion API documentation](https://developers.notion.com/ref | Channel | feedId | -| ------- | ------------------------ | +|---------|--------------------------| | Github | 5718e53e7a84fb1901e059cc | @@ -558,7 +558,7 @@ please refer to the [Notion API documentation](https://developers.notion.com/ref | All Jobs | Development | Design | Operation | Product | Other | Marketing | Sales | -| :------: | :---------: | :----: | :-------: | :-----: | :---: | :-------: | :---: | +|:--------:|:-----------:|:------:|:---------:|:-------:|:-----:|:---------:|:-----:| | all | development | design | operation | product | other | marketing | sales | @@ -577,30 +577,30 @@ Pass URL and transformation rules to convert HTML/JSON into RSS. Specify options (in the format of query string) in parameter `routeParams` parameter to extract data from HTML. -| Key | Meaning | Accepted Values | Default | -| -------------- | -------------------------------------------------- | --------------- | ----------------------- | -| `title` | The title of the RSS | `string` | Extract from `` | -| `item` | The HTML elements as `item` using CSS selector | `string` | html | -| `itemTitle` | The HTML elements as `title` in `item` using CSS selector | `string` | `item` element | -| `itemTitleAttr` | The attributes of `title` element as title | `string` | Element text | -| `itemLink` | The HTML elements as `link` in `item` using CSS selector | `string` | `item` element | -| `itemLinkAttr` | The attributes of `link` element as link | `string` | `href` | -| `itemDesc` | The HTML elements as `descrption` in `item` using CSS selector | `string` | `item` element | -| `itemDescAttr` | The attributes of `descrption` element as description | `string` | Element html | +| Key | Meaning | Accepted Values | Default | +|-----------------|----------------------------------------------------------------|-----------------|------------------------| +| `title` | The title of the RSS | `string` | Extract from `<title>` | +| `item` | The HTML elements as `item` using CSS selector | `string` | html | +| `itemTitle` | The HTML elements as `title` in `item` using CSS selector | `string` | `item` element | +| `itemTitleAttr` | The attributes of `title` element as title | `string` | Element text | +| `itemLink` | The HTML elements as `link` in `item` using CSS selector | `string` | `item` element | +| `itemLinkAttr` | The attributes of `link` element as link | `string` | `href` | +| `itemDesc` | The HTML elements as `descrption` in `item` using CSS selector | `string` | `item` element | +| `itemDescAttr` | The attributes of `descrption` element as description | `string` | Element html | <Route author="ttttmr" example="/rsshub/transform/html/https%3A%2F%2Fwechat2rss.xlab.app%2Fposts%2Flist%2F/item=div%5Bclass%3D%27post%2Dcontent%27%5D%20p%20a" path="/rsshub/transform/html/:url/:routeParams" paramsDesc={['`encodeURIComponent`ed URL address', 'Transformation rules, requires URL encode']} selfhost="1"> Parameters parsing in the above example: -| Parameter | Value | -| ------------ | ----------------------------------------- | -| `url` | `https://wechat2rss.xlab.app/posts/list/` | -| `routeParams`| `item=div[class='post-content'] p a` | +| Parameter | Value | +|---------------|-------------------------------------------| +| `url` | `https://wechat2rss.xlab.app/posts/list/` | +| `routeParams` | `item=div[class='post-content'] p a` | Parsing of `routeParams` parameter: | Parameter | Value | -| --------- | ------------------------------- | +|-----------|---------------------------------| | `item` | `div[class='post-content'] p a` | </Route> @@ -610,7 +610,7 @@ Parsing of `routeParams` parameter: Specify options (in the format of query string) in parameter `routeParams` parameter to extract data from JSON. | Key | Meaning | Accepted Values | Default | -| ---------- | ---------------------------------------- | --------------- | ------------------------------------------ | +|-------------|------------------------------------------|-----------------|--------------------------------------------| | `title` | The title of the RSS | `string` | Extracted from home page of current domain | | `item` | The JSON Path as `item` element | `string` | Entire JSON response | | `itemTitle` | The JSON Path as `title` in `item` | `string` | None | @@ -627,19 +627,19 @@ JSON Path only supports format like `a.b.c`. if you need to access arrays, like Parameters parsing in the above example: -| Parameter | Value | -| ------------- | ----------------------------------------------- | -| `url` | `https://api.github.com/repos/ginuerzh/gost/releases` | +| Parameter | Value | +|---------------|--------------------------------------------------------------------------| +| `url` | `https://api.github.com/repos/ginuerzh/gost/releases` | | `routeParams` | `title=Gost releases&itemTitle=tag_name&itemLink=html_url&itemDesc=body` | Parsing of `routeParams` parameter: -| Parameter | Value | -| ------------ | ---------------- | -| `title` | `Gost releases` | -| `itemTitle` | `tag_name` | -| `itemLink` | `html_url` | -| `itemDesc` | `body` | +| Parameter | Value | +|-------------|-----------------| +| `title` | `Gost releases` | +| `itemTitle` | `tag_name` | +| `itemLink` | `html_url` | +| `itemDesc` | `body` | </Route> @@ -686,7 +686,7 @@ type 为 all 时,category 参数不支持 cost 和 free ::: | 全部 | 祖源分析 | 付费 | 遗传性疾病 | 药物指南 | 免费 | 运动基因 | 营养代谢 | 心理特质 | 健康风险 | 皮肤特性 | 遗传特征 | -| ---- | -------- | ---- | ---------- | -------- | ---- | -------- | ---------- | ---------- | -------- | -------- | -------- | +|------|----------|------|------------|----------|------|----------|------------|------------|----------|----------|----------| | all | ancestry | cost | disease | drug | free | genefit | metabolism | psychology | risk | skin | traits | </Route> @@ -712,7 +712,7 @@ Top category can be found in [category Page](https://zh.wikihow.com/Special:Cate Type | All | Recommend | -| --- | --------- | +|-----|-----------| | all | rec | </Route> @@ -756,13 +756,13 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate 分类 | 推荐 | 最热 | -| ---- | ---- | +|------|------| | rec | hot | 目录类型 | 所有 | 绘画 | 视频 | 写作 | 游戏 | 音乐 | 播客 | 摄影 | 技术 | Vtuber | 舞蹈 | 体育 | 旅游 | 美食 | 时尚 | 数码 | 动画 | 其他 | -| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ------ | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +|----|----|----|----|----|----|----|----|----|--------|----|----|----|----|----|----|----|----| | 所有 | 绘画 | 视频 | 写作 | 游戏 | 音乐 | 播客 | 摄影 | 技术 | Vtuber | 舞蹈 | 体育 | 旅游 | 美食 | 时尚 | 数码 | 动画 | 其他 | </Route> @@ -778,7 +778,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="KeiLongW" example="/macau-bolsas" path="/macau-bolsas/:lang?" paramsDesc={['語言']} > | 中文 | 葡文 | -| ---- | ---- | +|------|------| | ch | pt | </Route> @@ -790,7 +790,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="xyqfer" example="/baidu/top" path="/baidu/top/:board?" paramsDesc={['榜单,默认为 `realtime`']} radar="1"> | 热搜榜 | 小说榜 | 电影榜 | 电视剧榜 | 汽车榜 | 游戏榜 | -| -------- | ------ | ------ | -------- | ------ | ------ | +|----------|--------|--------|----------|--------|--------| | realtime | novel | movie | teleplay | car | game | </Route> @@ -840,7 +840,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate `annotation` 字段为添加哪些附加信息。可从以下表格中选择值后按顺序拼接。例如如果需要注释和赏析,则为`zhushang`。 | 翻译 | 注释 | 赏析 | -| ---- | ---- | ----- | +|------|------|-------| | yi | zhu | shang | </Route> @@ -858,7 +858,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="Derekmini markmingjie" example="/csc/notice/lxtz" path="/csc/notice/:type?" paramsDesc={['分类, 默认为 `lxtz`']} radar="1" rssbud="1"> | 遴选通知 | 综合项目专栏 | 常见问题解答 | 录取公告 | 新闻资讯 | 新闻公告 | -| -------- | ------------ | ------------ | -------- | -------- | -------- | +|----------|--------------|--------------|----------|----------|----------| | lxtz | xmzl | wtjd | lqgg | xwzx | xwgg | </Route> @@ -908,7 +908,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="xapool" example="/aqicn/beijing/pm25,pm10" path="/aqicn/:city/:pollution?" paramsDesc={['城市拼音或地区 ID,详见[aqicn.org](http://aqicn.org/city/)', '可选择显示更详细的空气污染成分']}/> | 参数 | 污染成分 | -| ---- | -------- | +|------|----------| | pm25 | PM2.5 | | pm10 | PM10 | | o3 | O3 | @@ -1012,13 +1012,13 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate 表盘型号 | 小米手环 4 | 华米 GTR 47mm | 华米智能手表青春版 | -| ---------- | ------------- | ------------------ | +|------------|---------------|--------------------| | mi4 | gtr47 | gvlite | 列表类型 | 最新上传 | 最多下载 | 编辑推荐 | -| -------- | -------- | ---------- | +|----------|----------|------------| | 0 | 1 | recommends | </Route> @@ -1052,15 +1052,15 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="qiwihui" example="/qtfyfl/guoji" path="/qtfyfl/:category" paramsDesc={['分类,可在 URL 中找到']}> | 最新文章 | 福利社 | 求出处 | 套图集 | 门事件 | 内涵图 | 电影下载 | 影视资讯 | -| -------- | ------- | --------- | ------- | ---------- | -------- | -------------- | -------- | +|----------|---------|-----------|---------|------------|----------|----------------|----------| | latest | fulishe | qiuchuchu | taotuji | menshijian | neihantu | dianyingxiazai | yingshi | | 电视剧下载 | 动漫下载 | 电影彩蛋 | 影视剧情 | 涨姿势 | 娱乐 | 明星八卦 | 音乐歌曲 | -| ---------- | -------- | -------- | -------- | ---------- | ---- | -------- | -------- | +|------------|----------|----------|----------|------------|------|----------|----------| | dianshiju | dongman | caidan | juqing | zhangzishi | yule | mingxing | music | | 游戏 | 电脑软件 | 实时热点 | 心灵鸡汤 | 符号大全 | 国际新闻 | 科技苑 | 其他 | -| ----- | -------- | ------------ | -------- | -------- | -------- | ------ | ----- | +|-------|----------|--------------|----------|----------|----------|--------|-------| | games | software | shishiredian | xljt | fhdq | xljt | tech | other | </Route> @@ -1072,7 +1072,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="LogicJake" example="/babykingdom/19/view" path="/babykingdom/:id/:order?" paramsDesc={['板块id,可在 URL 中找到', '排序方式']}> | 发帖时间 | 回复 / 查看 | 查看 | 最后发表 | 热门 | -| -------- | ----------- | ---- | -------- | ---- | +|----------|-------------|------|----------|------| | dateline | reply | view | lastpost | heat | </Route> @@ -1102,7 +1102,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="Cubernet" example="/sckjt/news" path="/sckjt/news/:type?" paramsDesc={['默认为`tz`']}> | 通知 | 公示公告 | -| ---- | -------- | +|------|----------| | tz | gs | </Route> @@ -1178,7 +1178,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="vhxubo" example="/ku" path="/ku/:name?" paramsDesc={['默认为 `yuedu`']}> | 阅读 | 异次元 | 海阔 | -| ----- | -------- | ------ | +|-------|----------|--------| | yuedu | yiciyuan | haikuo | </Route> @@ -1192,7 +1192,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate 类型 | 全部文章 | 永久免费 | 限时折扣 | 限时免费 | PC | Mac | Android | UWP | -| -------- | -------- | -------- | -------- | -- | --- | ------- | --- | +|----------|----------|----------|----------|----|-----|---------|-----| | all | 311 | 309 | 310 | 8 | 50 | 17 | 312 | </Route> @@ -1216,7 +1216,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate 所属类别 | 专题知识服务 | 知识分析 | 知识工具 | 综合性知识服务 | 全部类别 | -| ------------ | -------- | -------- | -------------- | -------- | +|--------------|----------|----------|----------------|----------| | 2 | 3 | 4 | 1 | 0 | 领域 @@ -1230,6 +1230,18 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="nczitzk" example="/cktest/policy" path="/cktest/policy"/> +## 中国工商银行 {#zhong-guo-gong-shang-yin-hang} + +### 外汇牌价 {#zhong-guo-gong-shang-yin-hang-wai-hui-pai-jia} + +<Route author="leoleoasd" example="/icbc/whpj/zs?filter_title=%E8%8B%B1%E9%95%91" path="/icbc/whpj/:format?" paramsDesc={['输出的标题格式,默认为标题 + 所有价格。短格式仅包含货币名称。']}> + +| 短格式 | 参考价 | 现汇买卖 | 现钞买卖 | 现汇买入 | 现汇卖出 | 现钞买入 | 现钞卖出 | +|--------|--------|----------|----------|----------|----------|----------|----------| +| short | zs | xh | xc | xhmr | xhmc | xcmr | xcmc | + +</Route> + ## 中国光大银行 {#zhong-guo-guang-da-yin-hang} ### 外汇牌价 {#zhong-guo-guang-da-yin-hang-wai-hui-pai-jia} @@ -1243,7 +1255,7 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate <Route author="linbuxiao" example="/cebbank/quotation/history/usd" path="/cebbank/quotation/history/:type" paramsDesc={['货币的缩写,见下表']}> | 美元 | 英镑 | 港币 | 瑞士法郎 | 瑞典克郎 | 丹麦克郎 | 挪威克郎 | 日元 | 加拿大元 | 澳大利亚元 | 新加坡元 | 欧元 | 澳门元 | 泰国铢 | 新西兰元 | 韩圆 | -| ---- | ---- | ---- | -------- | -------- | -------- | -------- | ---- | -------- | ---------- | -------- | ---- | ------ | ------ | -------- | ---- | +|------|------|------|----------|----------|----------|----------|------|----------|------------|----------|------|--------|--------|----------|------| | usd | gbp | hkd | chf | sek | dkk | nok | jpy | cad | aud | sgd | eur | mop | thb | nzd | krw | </Route> @@ -1256,12 +1268,12 @@ Refer to [the list of supported currencies](https://wise.com/tools/exchange-rate ## 中国银行 {#zhong-guo-yin-hang} -### 中国银行外汇牌价 {#zhong-guo-yin-hang-zhong-guo-yin-hang-wai-hui-pai-jia} +### 外汇牌价 {#zhong-guo-yin-hang-wai-hui-pai-jia} <Route author="LogicJake HenryQW" example="/boc/whpj/zs?filter_title=%E8%8B%B1%E9%95%91" path="/boc/whpj/:format?" paramsDesc={['输出的标题格式,默认为标题 + 所有价格。短格式仅包含货币名称。']}> | 短格式 | 中行折算价 | 现汇买卖 | 现钞买卖 | 现汇买入 | 现汇卖出 | 现钞买入 | 现钞卖出 | -| ------ | ---------- | -------- | -------- | -------- | -------- | -------- | -------- | +|--------|------------|----------|----------|----------|----------|----------|----------| | short | zs | xh | xc | xhmr | xhmc | xcmr | xcmc | </Route> From 64839f022bb00fe278adb7080b9bc7146be1fee5 Mon Sep 17 00:00:00 2001 From: Andvari <31068367+dzx-dzx@users.noreply.github.com> Date: Wed, 30 Aug 2023 23:55:20 +0800 Subject: [PATCH 7/8] fix(route): add `Spotlight News` into CNA list. (#13160) * fix(route): add `Spotlight News` into CNA list. * refactor: migrate to v2 --------- --- lib/router.js | 2 +- lib/{routes => v2}/cna/index.js | 22 ++++++++++++---------- lib/v2/cna/maintainer.js | 3 +++ lib/v2/cna/radar.js | 13 +++++++++++++ lib/v2/cna/router.js | 3 +++ website/docs/routes/traditional-media.md | 24 ++++++++++++------------ 6 files changed, 44 insertions(+), 23 deletions(-) rename lib/{routes => v2}/cna/index.js (67%) create mode 100644 lib/v2/cna/maintainer.js create mode 100644 lib/v2/cna/radar.js create mode 100644 lib/v2/cna/router.js diff --git a/lib/router.js b/lib/router.js index 76f2a5b44f9187..d1f5dda1ab6038 100644 --- a/lib/router.js +++ b/lib/router.js @@ -2039,7 +2039,7 @@ router.get('/anki/changes', lazyloadRouteHandler('./routes/anki/changes')); router.get('/abc/:id?', lazyloadRouteHandler('./routes/abc')); // 台湾中央通讯社 -router.get('/cna/:id?', lazyloadRouteHandler('./routes/cna/index')); +// router.get('/cna/:id?', lazyloadRouteHandler('./routes/cna/index')); // 华为心声社区 router.get('/huawei/xinsheng/:caty?/:order?/:keyword?', lazyloadRouteHandler('./routes/huawei/xinsheng/index')); diff --git a/lib/routes/cna/index.js b/lib/v2/cna/index.js similarity index 67% rename from lib/routes/cna/index.js rename to lib/v2/cna/index.js index 36b12d8538fdbb..d33fb28ef0f63d 100644 --- a/lib/routes/cna/index.js +++ b/lib/v2/cna/index.js @@ -1,15 +1,17 @@ const got = require('@/utils/got'); const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); module.exports = async (ctx) => { - ctx.params.id = ctx.params.id || 'aall'; + const id = ctx.params.id || 'aall'; let rootUrl; - if (/^\d+$/.test(ctx.params.id)) { - rootUrl = `https://www.cna.com.tw/topic/newstopic/${ctx.params.id}.aspx`; + if (/^\d+$/.test(id)) { + rootUrl = `https://www.cna.com.tw/topic/newstopic/${id}.aspx`; } else { - rootUrl = `https://www.cna.com.tw/list/${ctx.params.id}.aspx`; + rootUrl = `https://www.cna.com.tw/list/${id}.aspx`; } const response = await got({ method: 'get', @@ -17,17 +19,17 @@ module.exports = async (ctx) => { }); const $ = cheerio.load(response.data); - const list = $('#jsMainList li a div h2') - .slice(0, 10) - .map((_, item) => { + const list = $('.mainList li a div h2') + .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 10) + .toArray() + .map((item) => { item = $(item); return { title: item.text(), link: item.parents('a').attr('href'), - pubDate: new Date(item.next().text() + ' GMT+8').toUTCString(), + pubDate: timezone(parseDate(item.next().text()), +8), }; - }) - .get(); + }); const items = await Promise.all( list.map((item) => diff --git a/lib/v2/cna/maintainer.js b/lib/v2/cna/maintainer.js new file mode 100644 index 00000000000000..77e7f46e2f9997 --- /dev/null +++ b/lib/v2/cna/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:id?': ['nczitzk'], +}; diff --git a/lib/v2/cna/radar.js b/lib/v2/cna/radar.js new file mode 100644 index 00000000000000..92cec6d1b42db5 --- /dev/null +++ b/lib/v2/cna/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'cna.com.tw': { + _name: '中央通訊社', + '.': [ + { + title: '分类', + docs: 'https://docs.rsshub.app/routes/traditional-media#zhong-yang-tong-xun-she', + source: ['/list/:id', '/topic/newstopic/:id'], + target: (params) => `/cna/${params.id.replace('.aspx', '')}`, + }, + ], + }, +}; diff --git a/lib/v2/cna/router.js b/lib/v2/cna/router.js new file mode 100644 index 00000000000000..a5d65c468f4c46 --- /dev/null +++ b/lib/v2/cna/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:id?', require('./')); +}; diff --git a/website/docs/routes/traditional-media.md b/website/docs/routes/traditional-media.md index 409b1d23544a80..3aa4b9d8f1386c 100644 --- a/website/docs/routes/traditional-media.md +++ b/website/docs/routes/traditional-media.md @@ -2339,18 +2339,6 @@ category 对应的关键词有 </Route> -## 台湾中央通讯社 {#tai-wan-zhong-yang-tong-xun-she} - -### 分类 {#tai-wan-zhong-yang-tong-xun-she-fen-lei} - -<Route author="nczitzk" example="/cna/aall" path="/cna/:id?" paramsDesc={['分类 id 或新闻专题 id。分类 id 见下表,新闻专题 id 為 https://www.cna.com.tw/list/newstopic.aspx 中,連結的數字部份。此參數默认为 aall']}> - -| 即時 | 政治 | 國際 | 兩岸 | 產經 | 證券 | 科技 | 生活 | 社會 | 地方 | 文化 | 運動 | 娛樂 | -| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | -| aall | aipl | aopl | acn | aie | asc | ait | ahel | asoc | aloc | acul | aspt | amov | - -</Route> - ## 天下雜誌 {#tian-xia-za-zhi} ### 最新上線 {#tian-xia-za-zhi-zui-xin-shang-xian} @@ -2772,6 +2760,18 @@ category 对应的关键词有 </Route> +## 中央通讯社 {#zhong-yang-tong-xun-she} + +### 分类 {#zhong-yang-tong-xun-she-fen-lei} + +<Route author="nczitzk" example="/cna/aall" path="/cna/:id?" paramsDesc={['分类 id 或新闻专题 id。分类 id 见下表,新闻专题 id 為 https://www.cna.com.tw/list/newstopic.aspx 中,連結的數字部份。此參數默认为 aall']}> + +| 即時 | 政治 | 國際 | 兩岸 | 產經 | 證券 | 科技 | 生活 | 社會 | 地方 | 文化 | 運動 | 娛樂 | +| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| aall | aipl | aopl | acn | aie | asc | ait | ahel | asoc | aloc | acul | aspt | amov | + +</Route> + ## 组织人事报 {#zu-zhi-ren-shi-bao} ### 电子报 {#zu-zhi-ren-shi-bao-dian-zi-bao} From 121763bb6d2c434bc41b0e36146fb85a3ce51f29 Mon Sep 17 00:00:00 2001 From: JimenezLi <75196426+JimenezLi@users.noreply.github.com> Date: Thu, 31 Aug 2023 00:18:48 +0800 Subject: [PATCH 8/8] feat(core): add logger timestamp (#13165) * feat(core): add logger timestamp * Update website/docs/install/README.md --------- --- lib/config.js | 1 + lib/utils/logger.js | 16 ++++++++++++++-- website/docs/install/README.md | 2 ++ .../current/install/README.md | 2 ++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/config.js b/lib/config.js index 4e76cf06d8118f..d435c4e50e0dd4 100644 --- a/lib/config.js +++ b/lib/config.js @@ -94,6 +94,7 @@ const calculateValue = () => { debugInfo: envs.DEBUG_INFO || 'true', loggerLevel: envs.LOGGER_LEVEL || 'info', noLogfiles: envs.NO_LOGFILES, + showLoggerTimestamp: envs.SHOW_LOGGER_TIMESTAMP, sentry: { dsn: envs.SENTRY, routeTimeout: parseInt(envs.SENTRY_ROUTE_TIMEOUT) || 30000, diff --git a/lib/utils/logger.js b/lib/utils/logger.js index 6b9136ccc39ae7..c92e4f13dfe644 100644 --- a/lib/utils/logger.js +++ b/lib/utils/logger.js @@ -14,7 +14,16 @@ if (!config.noLogfiles) { } const logger = winston.createLogger({ level: config.loggerLevel, - format: winston.format.json(), + format: winston.format.combine( + winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }), + winston.format.printf((info) => + JSON.stringify({ + timestamp: info.timestamp, + level: info.level, + message: info.message, + }) + ) + ), transports, }); @@ -25,7 +34,10 @@ const logger = winston.createLogger({ if (!config.isPackage) { logger.add( new winston.transports.Console({ - format: winston.format.combine(winston.format.colorize(), winston.format.simple()), + format: winston.format.printf((info) => { + const infoLevel = winston.format.colorize().colorize(info.level, config.showLoggerTimestamp ? `[${info.timestamp}] ${info.level}` : info.level); + return `${infoLevel}: ${info.message}`; + }), silent: process.env.NODE_ENV === 'test', }) ); diff --git a/website/docs/install/README.md b/website/docs/install/README.md index ea25ad0e7e2d6c..d45c831d237c33 100644 --- a/website/docs/install/README.md +++ b/website/docs/install/README.md @@ -677,6 +677,8 @@ See the relation between access key/code and white/blacklisting. `NO_LOGFILES`: disable logging to log files, default to `false` +`SHOW_LOGGER_TIMESTAMP`: Show timestamp in log, default to `false` + `SENTRY`: [Sentry](https://sentry.io) dsn, used for error tracking `SENTRY_ROUTE_TIMEOUT`: Report Sentry if route execution takes more than this milliseconds, default to `3000` diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md index 6244cdb0af95f6..fb04235912a261 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/install/README.md @@ -672,6 +672,8 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 `NO_LOGFILES`: 是否禁用日志文件输出,默认 `false` +`SHOW_LOGGER_TIMESTAMP`: 在控制台输出中显示日志时间戳,默认 `false` + `SENTRY`: [Sentry](https://sentry.io) dsn,用于错误追踪 `SENTRY_ROUTE_TIMEOUT`: 路由耗时超过此毫秒值上报 Sentry,默认 `3000`