From 94cb794993b64858bdf05515a38cbf2f68f4f74a Mon Sep 17 00:00:00 2001 From: Tony Date: Sat, 2 Mar 2024 22:41:47 +0800 Subject: [PATCH 01/12] fix(route): migrate nmc weatheralarm (#14624) --- lib/router.js | 2 +- lib/routes-deprecated/weatheralarm/index.js | 26 ----------- lib/routes/nmc/maintainer.js | 3 ++ lib/routes/nmc/radar.js | 13 ++++++ lib/routes/nmc/router.js | 3 ++ lib/routes/nmc/weatheralarm.js | 49 +++++++++++++++++++++ website/docs/routes/forecast.mdx | 2 +- 7 files changed, 70 insertions(+), 28 deletions(-) delete mode 100644 lib/routes-deprecated/weatheralarm/index.js create mode 100644 lib/routes/nmc/maintainer.js create mode 100644 lib/routes/nmc/radar.js create mode 100644 lib/routes/nmc/router.js create mode 100644 lib/routes/nmc/weatheralarm.js diff --git a/lib/router.js b/lib/router.js index b1a0e80697..80d0cfa6fc 100644 --- a/lib/router.js +++ b/lib/router.js @@ -155,7 +155,7 @@ router.get('/mafengwo/ziyouxing/:code', lazyloadRouteHandler('./routes/mafengwo/ router.get('/novel/uukanshu/:uid', lazyloadRouteHandler('./routes/novel/uukanshu')); // 中国气象网 -router.get('/weatheralarm/:province?', lazyloadRouteHandler('./routes/weatheralarm')); +// router.get('/weatheralarm/:province?', lazyloadRouteHandler('./routes/weatheralarm')); // Gitlab router.get('/gitlab/explore/:type/:host?', lazyloadRouteHandler('./routes/gitlab/explore')); diff --git a/lib/routes-deprecated/weatheralarm/index.js b/lib/routes-deprecated/weatheralarm/index.js deleted file mode 100644 index 88d0595378..0000000000 --- a/lib/routes-deprecated/weatheralarm/index.js +++ /dev/null @@ -1,26 +0,0 @@ -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const province = ctx.params.province || '&'; - const alarmInfoURL = `http://www.nmc.cn/rest/findAlarm?pageNo=1&pageSize=20&signaltype=&signallevel=&province=${province}`; - const response = await got({ - method: 'get', - url: alarmInfoURL, - }); - const data = response.data.data; - const list = data.page.list; - - ctx.state.data = { - title: '中央气象台全国气象预警', - link: `http://www.nmc.cn/publish/alarm.html`, - item: list.map((item) => { - const title = item.title; - const url = item.url; - return { - title, - link: `http://www.nmc.cn${url}`, - pubDate: item.issuetime, - }; - }), - }; -}; diff --git a/lib/routes/nmc/maintainer.js b/lib/routes/nmc/maintainer.js new file mode 100644 index 0000000000..42f2f53ab7 --- /dev/null +++ b/lib/routes/nmc/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/weatheralarm/:province?': ['ylc395'], +}; diff --git a/lib/routes/nmc/radar.js b/lib/routes/nmc/radar.js new file mode 100644 index 0000000000..0e77a18f3e --- /dev/null +++ b/lib/routes/nmc/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'nmc.cn': { + _name: '中央气象台', + '.': [ + { + title: '全国气象预警', + docs: 'https://docs.rsshub.app/routes/forecast#zhong-yang-qi-xiang-tai', + source: ['/publish/alarm.html', '/'], + target: '/nmc/weatheralarm', + }, + ], + }, +}; diff --git a/lib/routes/nmc/router.js b/lib/routes/nmc/router.js new file mode 100644 index 0000000000..fde453364b --- /dev/null +++ b/lib/routes/nmc/router.js @@ -0,0 +1,3 @@ +export default (router) => { + router.get('/weatheralarm/:province?', './weatheralarm'); +}; diff --git a/lib/routes/nmc/weatheralarm.js b/lib/routes/nmc/weatheralarm.js new file mode 100644 index 0000000000..825d35650f --- /dev/null +++ b/lib/routes/nmc/weatheralarm.js @@ -0,0 +1,49 @@ +import cache from '@/utils/cache'; +import got from '@/utils/got'; +import { parseDate } from '@/utils/parse-date'; +import timezone from '@/utils/timezone'; +import * as cheerio from 'cheerio'; + +export default async (ctx) => { + const { province } = ctx.req.param(); + const alarmInfoURL = `http://www.nmc.cn/rest/findAlarm`; + const { data: response } = await got(alarmInfoURL, { + searchParams: { + pageNo: 1, + pageSize: 20, + signaltype: '', + signallevel: '', + province, + }, + }); + + const list = response.data.page.list.map((item) => ({ + title: item.title, + link: `http://www.nmc.cn${item.url}`, + pubDate: timezone(parseDate(item.issuetime), 8), + })); + + const items = await Promise.all( + list.map((item) => + cache.tryGet(item.link, async () => { + const { data: response } = await got(item.link); + const $ = cheerio.load(response); + + item.description = + $('#icon').html() + + $('#alarmtext') + .toArray() + .map((i) => $(i).html()) + .join(''); + + return item; + }) + ) + ); + + ctx.set('data', { + title: '中央气象台全国气象预警', + link: 'http://www.nmc.cn/publish/alarm.html', + item: items, + }); +}; diff --git a/website/docs/routes/forecast.mdx b/website/docs/routes/forecast.mdx index 2f17b104ed..b3bd703fd8 100644 --- a/website/docs/routes/forecast.mdx +++ b/website/docs/routes/forecast.mdx @@ -316,6 +316,6 @@ ### 全国气象预警 {#zhong-yang-qi-xiang-tai-quan-guo-qi-xiang-yu-jing} - + 可通过全局过滤参数订阅您感兴趣的地区. From 5928c5db2472e101c2f5c3bafed77a2f72edd40a Mon Sep 17 00:00:00 2001 From: psychosispy <128822194+psychosispy@users.noreply.github.com> Date: Sun, 3 Mar 2024 03:07:01 +0800 Subject: [PATCH 02/12] feat(route): Rewrite the API URL to original URL (#14617) * feat(route): Rewrite the API URL to original URL * Update notifications.js * camelCase --- lib/routes/github/notifications.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/routes/github/notifications.js b/lib/routes/github/notifications.js index af98c7154f..faab6e724e 100644 --- a/lib/routes/github/notifications.js +++ b/lib/routes/github/notifications.js @@ -19,13 +19,19 @@ export default async (ctx) => { }); const notifications = response.data; - const items = notifications.map((item) => ({ - title: item.subject.title, - description: item.subject.title, - pubDate: parseDate(item.updated_at), // item.updated_at follows ISO 8601. - guid: item.id, - link: item.subject.url, - })); + const items = notifications.map((item) => { + let originUrl = item.subject.url ? item.subject.url.replace('https://api.github.com/repos/', 'https://github.com/') : 'https://github.com/notifications'; + if (originUrl.includes('/releases/')) { + originUrl = originUrl.replace(/\/releases\/\d+$/, '/releases'); + } + return { + title: item.subject.title, + description: item.subject.title, + pubDate: parseDate(item.updated_at), // item.updated_at follows ISO 8601. + guid: item.id, + link: originUrl, + }; + }); ctx.set('data', { title: 'Github Notifications', From 6a3d132008a0c3518a85394110bb3758f98e496a Mon Sep 17 00:00:00 2001 From: Ethan Shen <42264778+nczitzk@users.noreply.github.com> Date: Sun, 3 Mar 2024 03:28:25 +0800 Subject: [PATCH 03/12] =?UTF-8?q?feat(route):=20add=20=E4=B8=AD=E5=9B=BD?= =?UTF-8?q?=E5=9B=BD=E5=AE=B6=E5=9B=BE=E4=B9=A6=E9=A6=86=E8=AF=BB=E8=80=85?= =?UTF-8?q?=E4=BA=91=E5=B9=B3=E5=8F=B0=20(#14620)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(route): add 中国国家图书馆读者云平台 * fix radar * fix typo --- lib/routes/nlc/maintainer.js | 3 + lib/routes/nlc/radar.js | 66 ++++++++++++++++++++++ lib/routes/nlc/read.js | 71 ++++++++++++++++++++++++ lib/routes/nlc/router.js | 3 + lib/routes/nlc/templates/description.art | 17 ++++++ website/docs/routes/other.mdx | 12 ++++ 6 files changed, 172 insertions(+) create mode 100644 lib/routes/nlc/maintainer.js create mode 100644 lib/routes/nlc/radar.js create mode 100644 lib/routes/nlc/read.js create mode 100644 lib/routes/nlc/router.js create mode 100644 lib/routes/nlc/templates/description.art diff --git a/lib/routes/nlc/maintainer.js b/lib/routes/nlc/maintainer.js new file mode 100644 index 0000000000..2a5a4f02d7 --- /dev/null +++ b/lib/routes/nlc/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/read/:type?': ['nczitzk'], +}; diff --git a/lib/routes/nlc/radar.js b/lib/routes/nlc/radar.js new file mode 100644 index 0000000000..607df4da50 --- /dev/null +++ b/lib/routes/nlc/radar.js @@ -0,0 +1,66 @@ +module.exports = { + 'nlc.cn': { + _name: '中国国家图书馆', + read: [ + { + title: '读者云平台', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: (_, url) => { + url = new URL(url); + const type = url.searchParams.get('type'); + + return `/nlc/read/${type ? `/${type}` : ''}`; + }, + }, + { + title: '电子图书', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/电子图书', + }, + { + title: '电子期刊', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/电子期刊', + }, + { + title: '电子论文', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/电子论文', + }, + { + title: '电子报纸', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/电子报纸', + }, + { + title: '音视频', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/音视频', + }, + { + title: '标准专利', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/标准专利', + }, + { + title: '工具书', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/工具书', + }, + { + title: '少儿资源', + docs: 'https://docs.rsshub.app/routes/other#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai', + source: ['/outRes/outResList'], + target: '/nlc/read/少儿资源', + }, + ], + }, +}; diff --git a/lib/routes/nlc/read.js b/lib/routes/nlc/read.js new file mode 100644 index 0000000000..f9afd64681 --- /dev/null +++ b/lib/routes/nlc/read.js @@ -0,0 +1,71 @@ +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { art } from '@/utils/render'; +import * as path from 'node:path'; + +export default async (ctx) => { + const { type = '电子图书' } = ctx.req.param(); + const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15; + + const author = '中国国家图书馆'; + + const rootUrl = 'http://read.nlc.cn'; + const currentUrl = new URL(`/outRes/outResList?type=${type}`, rootUrl).href; + + const { data: response } = await got(currentUrl); + + const $ = load(response); + + const items = $('ul.YMH2019_New_GRZX_list7 li a.aa') + .slice(0, limit) + .toArray() + .map((item) => { + item = $(item); + + const title = item.find('span').first().text(); + + return { + title, + link: item.prop('onclick').match(/openOutRes\('1','(.*?)','1',/)[1], + description: art(path.join(__dirname, 'templates/description.art'), { + images: item + .find('div.pic img') + .toArray() + .map((i) => { + i = $(i); + + return { + src: i.prop('src'), + alt: title, + }; + }), + intro: item.find('div.txt').prop('title'), + }), + author, + category: [type], + guid: `nlc-read#${ + item + .prev() + .prop('onclick') + .match(/\('(\d+)'\)/)[1] + }`, + }; + }); + + const image = new URL('static/style/css/images/YMH_home_main_logo.png', rootUrl).href; + const icon = new URL($('link[rel="shortcut icon"]').prop('href'), rootUrl).href; + + ctx.set('data', { + item: items, + title: `${$('title').text()} - ${type}`, + link: currentUrl, + description: type, + language: 'zh', + image, + icon, + logo: icon, + subtitle: type, + author, + allowEmpty: true, + }); +}; diff --git a/lib/routes/nlc/router.js b/lib/routes/nlc/router.js new file mode 100644 index 0000000000..87a34ad553 --- /dev/null +++ b/lib/routes/nlc/router.js @@ -0,0 +1,3 @@ +export default (router) => { + router.get('/read/:type?', './read'); +}; diff --git a/lib/routes/nlc/templates/description.art b/lib/routes/nlc/templates/description.art new file mode 100644 index 0000000000..a3f88c9b4d --- /dev/null +++ b/lib/routes/nlc/templates/description.art @@ -0,0 +1,17 @@ +{{ if images }} + {{ each images image }} + {{ if image?.src }} +
+ {{ image.alt }} +
+ {{ /if }} + {{ /each }} +{{ /if }} + +{{ if intro }} +

{{ intro }}

+{{ /if }} \ No newline at end of file diff --git a/website/docs/routes/other.mdx b/website/docs/routes/other.mdx index 5c0fcad4e9..cb9d1607fc 100644 --- a/website/docs/routes/other.mdx +++ b/website/docs/routes/other.mdx @@ -995,6 +995,18 @@ Specify options (in the format of query string) in parameter `routeParams` param | usd | gbp | hkd | chf | sek | dkk | nok | jpy | cad | aud | sgd | eur | mop | thb | nzd | krw |
+## 中国国家图书馆 {#zhong-guo-guo-jia-tu-shu-guan} + +### 读者云平台 {#zhong-guo-guo-jia-tu-shu-guan-du-zhe-yun-ping-tai} + + + | [电子图书](http://read.nlc.cn/outRes/outResList?type=电子图书) | [电子期刊](http://read.nlc.cn/outRes/outResList?type=电子期刊) | [电子论文](http://read.nlc.cn/outRes/outResList?type=电子论文) | [电子报纸](http://read.nlc.cn/outRes/outResList?type=电子报纸) | [音视频](http://read.nlc.cn/outRes/outResList?type=音视频) | + | -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------- | + + | [标准专利](http://read.nlc.cn/outRes/outResList?type=标准专利) | [工具书](http://read.nlc.cn/outRes/outResList?type=工具书) | [少儿资源](http://read.nlc.cn/outRes/outResList?type=少儿资源) | + | -------------------------------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------- | + + ## 中国互联网联合辟谣平台 {#zhong-guo-hu-lian-wang-lian-he-pi-yao-ping-tai} ### 今日辟谣 {#zhong-guo-hu-lian-wang-lian-he-pi-yao-ping-tai-jin-ri-pi-yao} From 0d02f04a44e2c74cf8b8038b855a33b19658899d Mon Sep 17 00:00:00 2001 From: ygguorun <36809814+ygguorun@users.noreply.github.com> Date: Sun, 3 Mar 2024 13:56:51 +0800 Subject: [PATCH 04/12] =?UTF-8?q?feat(route):=20add=20bilibili=20UP=20?= =?UTF-8?q?=E4=B8=BB=E7=82=B9=E8=B5=9E=E8=A7=86=E9=A2=91=20(#14596)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/bilibili/like.js | 35 ++++++++++++++++++++++++++++ lib/routes/bilibili/maintainer.js | 1 + lib/routes/bilibili/radar.js | 6 +++++ lib/routes/bilibili/router.js | 1 + website/docs/routes/social-media.mdx | 4 ++++ 5 files changed, 47 insertions(+) create mode 100644 lib/routes/bilibili/like.js diff --git a/lib/routes/bilibili/like.js b/lib/routes/bilibili/like.js new file mode 100644 index 0000000000..2b628aec41 --- /dev/null +++ b/lib/routes/bilibili/like.js @@ -0,0 +1,35 @@ +import got from '@/utils/got'; +const cache = require('./cache'); +const utils = require('./utils'); +import { parseDate } from '@/utils/parse-date'; + +module.exports = async (ctx) => { + const uid = ctx.req.param('uid'); + const disableEmbed = ctx.req.param('disableEmbed'); + + const name = await cache.getUsernameFromUID(ctx, uid); + + const response = await got({ + url: `https://api.bilibili.com/x/space/like/video?vmid=${uid}`, + headers: { + Referer: `https://space.bilibili.com/${uid}/`, + }, + }); + const { data, code, message } = response.data; + if (code) { + throw new Error(message ?? code); + } + + ctx.set('data', { + title: `${name} 的 bilibili 点赞视频`, + link: `https://space.bilibili.com/${uid}`, + description: `${name} 的 bilibili 点赞视频`, + item: data.list.map((item) => ({ + title: item.title, + description: `${item.desc}${disableEmbed ? '' : `

${utils.iframe(item.aid)}`}
`, + pubDate: parseDate(item.pubdate * 1000), + link: item.pubdate > utils.bvidTime && item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.aid}`, + author: item.owner.name, + })), + }); +}; diff --git a/lib/routes/bilibili/maintainer.js b/lib/routes/bilibili/maintainer.js index 2cbb05bfe8..bfab17167d 100644 --- a/lib/routes/bilibili/maintainer.js +++ b/lib/routes/bilibili/maintainer.js @@ -31,6 +31,7 @@ module.exports = { '/user/fav/:uid/:disableEmbed?': ['DIYgod'], '/user/followers/:uid/:loginUid': ['Qixingchen'], '/user/followings/:uid/:loginUid': ['Qixingchen'], + '/user/like/:uid/:disableEmbed?': ['ygguorun'], '/user/video/:uid/:disableEmbed?': ['DIYgod'], '/video/danmaku/:bvid/:pid?': ['Qixingchen'], '/video/page/:bvid/:disableEmbed?': ['sxzz'], diff --git a/lib/routes/bilibili/radar.js b/lib/routes/bilibili/radar.js index 24fa549a60..91df8b0b90 100644 --- a/lib/routes/bilibili/radar.js +++ b/lib/routes/bilibili/radar.js @@ -102,6 +102,12 @@ module.exports = { source: '/:uid', target: '/bilibili/user/coin/:uid', }, + { + title: 'UP 主点赞视频', + docs: 'https://docs.rsshub.app/routes/social-media#bilibili', + source: '/:uid', + target: '/bilibili/user/like/:uid', + }, { title: 'UP 主粉丝', docs: 'https://docs.rsshub.app/routes/social-media#bilibili', diff --git a/lib/routes/bilibili/router.js b/lib/routes/bilibili/router.js index 739d7fa2ea..01c61b004a 100644 --- a/lib/routes/bilibili/router.js +++ b/lib/routes/bilibili/router.js @@ -31,6 +31,7 @@ export default (router) => { router.get('/user/fav/:uid/:disableEmbed?', './user-fav'); router.get('/user/followers/:uid/:loginUid', './followers'); router.get('/user/followings/:uid/:loginUid', './followings'); + router.get('/user/like/:uid/:disableEmbed?', './like'); router.get('/user/video/:uid/:disableEmbed?', './video'); router.get('/user/video-all/:uid/:disableEmbed?', './video-all'); router.get('/video/danmaku/:bvid/:pid?', './danmaku'); diff --git a/website/docs/routes/social-media.mdx b/website/docs/routes/social-media.mdx index dcfd03b0fb..541f207c34 100644 --- a/website/docs/routes/social-media.mdx +++ b/website/docs/routes/social-media.mdx @@ -67,6 +67,10 @@ +### UP 主点赞视频 {#bilibili-up-zhu-dian-zan-shi-pin} + + + ### UP 主粉丝 {#bilibili-up-zhu-fen-si} From 2c771aa0f63e786874edbe1b57478f6ca64dfc91 Mon Sep 17 00:00:00 2001 From: Tony Date: Sun, 3 Mar 2024 06:03:38 +0000 Subject: [PATCH 05/12] fix: sentry import --- lib/middleware/sentry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/middleware/sentry.ts b/lib/middleware/sentry.ts index 39818a3064..04d59e95e1 100644 --- a/lib/middleware/sentry.ts +++ b/lib/middleware/sentry.ts @@ -1,7 +1,7 @@ import { MiddlewareHandler } from 'hono'; import logger from '@/utils/logger'; import { config } from '@/config'; -import Sentry from '@sentry/node'; +import * as Sentry from '@sentry/node'; import { getRouteNameFromPath } from '@/utils/helpers'; if (config.sentry.dsn) { From cd6f2d982c3a628ddee5eae2f4a9fb4739e8ddfe Mon Sep 17 00:00:00 2001 From: Yufan You Date: Sun, 3 Mar 2024 14:33:11 +0800 Subject: [PATCH 06/12] fix: use path param with regex for npm package feed (#14626) * fix: use path param with regex for npm package feed 1. Don't include query params like `?code` in the package name. 2. Handle special cases when the org name of the package ends with `package`, i.e. the package name is something like `@*package/*`. * refactor: use map --------- --- lib/routes/npm/package.js | 12 +++++------- lib/routes/npm/router.js | 3 ++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/routes/npm/package.js b/lib/routes/npm/package.js index c8119a8a95..d768e4766d 100644 --- a/lib/routes/npm/package.js +++ b/lib/routes/npm/package.js @@ -3,7 +3,7 @@ import { art } from '@/utils/render'; import * as path from 'node:path'; export default async (ctx) => { - const name = ctx.req.url.split('package/')[1]; + const name = ctx.req.param('name'); const packageDownloadLastMonthAPI = `https://api.npmjs.org/downloads/point/last-month/${name}`; // 按月统计 const packageDownloadLastWeekAPI = `https://api.npmjs.org/downloads/point/last-week/${name}`; // 按周统计 const packageDownloadLastDayAPI = `https://api.npmjs.org/downloads/point/last-day/${name}`; // 按天统计 @@ -15,14 +15,12 @@ export default async (ctx) => { const packageVersionRes = await got(packageVersionAPI).json(); const packageVersion = packageVersionRes.time; - const packageVersionList = []; - for (const key in packageVersion) { - packageVersionList.push({ + const packageVersionList = Object.keys(packageVersion) + .map((key) => ({ version: key, time: packageVersion[key], - }); - } - packageVersionList.reverse(); + })) + .toReversed(); ctx.set('data', { title: `${name} - npm`, diff --git a/lib/routes/npm/router.js b/lib/routes/npm/router.js index 03da709285..0b04076bb8 100644 --- a/lib/routes/npm/router.js +++ b/lib/routes/npm/router.js @@ -1,3 +1,4 @@ export default (router) => { - router.get('package/*', './package'); + // https://github.com/dword-design/package-name-regex/blob/master/src/index.js + router.get('package/:name{(@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*}', './package'); }; From 172f6cfd2b69ea6affdbdedf61e6dde1671f3796 Mon Sep 17 00:00:00 2001 From: LyleLee Date: Sun, 3 Mar 2024 16:07:03 +0800 Subject: [PATCH 07/12] fix(route): fix radio canada by fixing regular expression to match correct data (#14630) --- lib/routes/radio-canada/latest.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/routes/radio-canada/latest.js b/lib/routes/radio-canada/latest.js index 804319d2a0..accb7d5c05 100644 --- a/lib/routes/radio-canada/latest.js +++ b/lib/routes/radio-canada/latest.js @@ -31,10 +31,10 @@ export default async (ctx) => { }); const $ = load(detailResponse.data); - const rcState = $('script:contains("window._rcState_ = JSON.parse")') + const rcState = $('script:contains("window._rcState_ = ")') .text() - .match(/JSON\.parse\((".*")\);/)[1]; - const rcStateJson = JSON.parse(JSON.parse(rcState)); + .match(/window\._rcState_ = (.*);/)[1]; + const rcStateJson = JSON.parse(rcState); const news = Object.values(rcStateJson.pagesV2.pages)[0]; item.description = news.data.newsStory.body.html.replaceAll('\\n', '
'); From 7a93e0c7276e92da3a93e95ac227ac592996f382 Mon Sep 17 00:00:00 2001 From: cnkmmk <22782790+cnkmmk@users.noreply.github.com> Date: Sun, 3 Mar 2024 23:09:47 +0800 Subject: [PATCH 08/12] =?UTF-8?q?feat(route):=20add=20=E5=9B=BD=E5=A4=96?= =?UTF-8?q?=E4=B8=BB=E6=9C=BA=E6=B5=8B=E8=AF=84=20(#14633)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/zhujiceping/maintainer.js | 3 +++ lib/routes/zhujiceping/radar.js | 13 +++++++++++ lib/routes/zhujiceping/router.js | 3 +++ lib/routes/zhujiceping/rss.js | 32 ++++++++++++++++++++++++++++ website/docs/routes/blog.mdx | 6 ++++++ 5 files changed, 57 insertions(+) create mode 100644 lib/routes/zhujiceping/maintainer.js create mode 100644 lib/routes/zhujiceping/radar.js create mode 100644 lib/routes/zhujiceping/router.js create mode 100644 lib/routes/zhujiceping/rss.js diff --git a/lib/routes/zhujiceping/maintainer.js b/lib/routes/zhujiceping/maintainer.js new file mode 100644 index 0000000000..387d961bfe --- /dev/null +++ b/lib/routes/zhujiceping/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/': ['cnkmmk'], +}; diff --git a/lib/routes/zhujiceping/radar.js b/lib/routes/zhujiceping/radar.js new file mode 100644 index 0000000000..5ea1b8e747 --- /dev/null +++ b/lib/routes/zhujiceping/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'zhujiceping.com': { + _name: '国外主机测评', + '.': [ + { + title: '最新发布', + docs: 'https://docs.rsshub.app/routes/blog#guo-wai-zhu-ji-ce-ping', + source: ['/'], + target: '/zhujiceping', + }, + ], + }, +}; diff --git a/lib/routes/zhujiceping/router.js b/lib/routes/zhujiceping/router.js new file mode 100644 index 0000000000..09c585b573 --- /dev/null +++ b/lib/routes/zhujiceping/router.js @@ -0,0 +1,3 @@ +export default (router) => { + router.get('/', './rss'); +}; diff --git a/lib/routes/zhujiceping/rss.js b/lib/routes/zhujiceping/rss.js new file mode 100644 index 0000000000..7c75304996 --- /dev/null +++ b/lib/routes/zhujiceping/rss.js @@ -0,0 +1,32 @@ +import { parseDate } from '@/utils/parse-date'; +import got from '@/utils/got'; +import { load } from 'cheerio'; + +export default async (ctx) => { + const url = 'https://www.zhujiceping.com/'; + const response = await got({ method: 'get', url }); + const $ = load(response.data); + + const list = $('article.excerpt') + .map((i, e) => { + const element = $(e); + const title = element.find('h2 > a').attr('title'); + const link = element.find('h2 > a').attr('href'); + const description = element.find('p.note').text(); + const dateraw = element.find('time').text(); + + return { + title, + description, + link, + pubDate: parseDate(dateraw, 'YYYY-MM-DD'), + }; + }) + .get(); + + ctx.set('data', { + title: '国外主机测评', + link: url, + item: list, + }); +}; diff --git a/website/docs/routes/blog.mdx b/website/docs/routes/blog.mdx index 84aa4d03b2..f0c431f15a 100644 --- a/website/docs/routes/blog.mdx +++ b/website/docs/routes/blog.mdx @@ -491,3 +491,9 @@ ### 上周热门 TOP 20 {#zhu-bai-shang-zhou-re-men-top-20} + +## 国外主机测评 {#guo-wai-zhu-ji-ce-ping} + +### 最新发布 {#guo-wai-zhu-ji-ce-ping-zui-xin-fa-bu} + + From 3e41600aa8c616d28877e9ce3766b53270df1527 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 3 Mar 2024 15:12:07 +0000 Subject: [PATCH 09/12] style: auto format --- website/docs/routes/blog.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/docs/routes/blog.mdx b/website/docs/routes/blog.mdx index f0c431f15a..0ea8cd45e3 100644 --- a/website/docs/routes/blog.mdx +++ b/website/docs/routes/blog.mdx @@ -334,6 +334,12 @@ | news | blog | articles | about-influence | customers | +## 国外主机测评 {#guo-wai-zhu-ji-ce-ping} + +### 最新发布 {#guo-wai-zhu-ji-ce-ping-zui-xin-fa-bu} + + + ## 虎皮椒 {#hu-pi-jiao} ### 文章 {#hu-pi-jiao-wen-zhang} @@ -491,9 +497,3 @@ ### 上周热门 TOP 20 {#zhu-bai-shang-zhou-re-men-top-20} - -## 国外主机测评 {#guo-wai-zhu-ji-ce-ping} - -### 最新发布 {#guo-wai-zhu-ji-ce-ping-zui-xin-fa-bu} - - From 6b7b95d1b3a49ac29b2b2b532cdf8972a418fd4e Mon Sep 17 00:00:00 2001 From: JimenezLi <75196426+JimenezLi@users.noreply.github.com> Date: Sun, 3 Mar 2024 23:48:56 +0800 Subject: [PATCH 10/12] =?UTF-8?q?fix(route):=20=E7=99=BE=E5=BA=A6=E8=B4=B4?= =?UTF-8?q?=E5=90=A7=20(#14635)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/routes/baidu/radar.js | 2 +- lib/routes/baidu/tieba/forum.js | 2 +- lib/routes/baidu/tieba/post.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/routes/baidu/radar.js b/lib/routes/baidu/radar.js index 5d91512855..13e02d4527 100644 --- a/lib/routes/baidu/radar.js +++ b/lib/routes/baidu/radar.js @@ -75,7 +75,7 @@ module.exports = { const qw = searchParams.get('qw'); const kw = searchParams.get('kw'); if (qw) { - const route = `/baidu/tieba/user/${qw}`; + const route = `/baidu/tieba/search/${qw}`; return kw ? `${route}/kw=${kw}` : route; } }, diff --git a/lib/routes/baidu/tieba/forum.js b/lib/routes/baidu/tieba/forum.js index a41c9d35c6..3020e58566 100644 --- a/lib/routes/baidu/tieba/forum.js +++ b/lib/routes/baidu/tieba/forum.js @@ -12,7 +12,7 @@ export default async (ctx) => { // PC端:https://tieba.baidu.com/f?kw=${encodeURIComponent(kw)} // 移动端接口:https://tieba.baidu.com/mo/q/m?kw=${encodeURIComponent(kw)}&lp=5024&forum_recommend=1&lm=0&cid=0&has_url_param=1&pn=0&is_ajax=1 const params = { kw: encodeURIComponent(kw) }; - ctx._matchedRoute.includes('good') && (params.tab = 'good'); + ctx.req.path.includes('good') && (params.tab = 'good'); cid && (params.cid = cid); const { data } = await got(`https://tieba.baidu.com/f`, { headers: { diff --git a/lib/routes/baidu/tieba/post.js b/lib/routes/baidu/tieba/post.js index de3af370b6..cfd7f92f23 100644 --- a/lib/routes/baidu/tieba/post.js +++ b/lib/routes/baidu/tieba/post.js @@ -30,7 +30,7 @@ async function getPost(id, lz = 0, pn = 7e6) { export default async (ctx) => { const id = ctx.req.param('id'); - const lz = ctx._matchedRoute.includes('lz') ? 1 : 0; + const lz = ctx.req.path.includes('lz') ? 1 : 0; const html = await getPost(id, lz); const $ = load(html); const title = $('.core_title_txt').attr('title'); From 30657490ec728b9626ec5618f05ce2ff7fa0abfc Mon Sep 17 00:00:00 2001 From: Yufan You Date: Mon, 4 Mar 2024 00:01:14 +0800 Subject: [PATCH 11/12] fix: use access token for all Mastodon routes (#14634) * fix: use access token for all Mastodon routes * fix: only send access token to MASTODON_API_HOST --- lib/routes/mastodon/timeline-local.js | 2 +- lib/routes/mastodon/timeline-remote.js | 2 +- lib/routes/mastodon/utils.js | 13 ++++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/routes/mastodon/timeline-local.js b/lib/routes/mastodon/timeline-local.js index 973a0f8bc3..96b9eeb2b8 100644 --- a/lib/routes/mastodon/timeline-local.js +++ b/lib/routes/mastodon/timeline-local.js @@ -11,7 +11,7 @@ export default async (ctx) => { const url = `http://${site}/api/v1/timelines/public?local=true&only_media=${only_media}`; - const response = await got.get(url); + const response = await got.get(url, { headers: utils.apiHeaders() }); const list = response.data; ctx.set('data', { diff --git a/lib/routes/mastodon/timeline-remote.js b/lib/routes/mastodon/timeline-remote.js index 1cb3a50b41..2dc557ccaa 100644 --- a/lib/routes/mastodon/timeline-remote.js +++ b/lib/routes/mastodon/timeline-remote.js @@ -11,7 +11,7 @@ export default async (ctx) => { const url = `http://${site}/api/v1/timelines/public?remote=true&only_media=${only_media}`; - const response = await got.get(url); + const response = await got.get(url, { headers: utils.apiHeaders() }); const list = response.data; ctx.set('data', { diff --git a/lib/routes/mastodon/utils.js b/lib/routes/mastodon/utils.js index 74d25cb196..df58e73f0d 100644 --- a/lib/routes/mastodon/utils.js +++ b/lib/routes/mastodon/utils.js @@ -5,6 +5,12 @@ import { config } from '@/config'; const allowSiteList = ['mastodon.social', 'pawoo.net']; +const apiHeaders = (site) => { + const { accessToken, apiHost } = config.mastodon; + // avoid sending API token to other sites + return accessToken && site === apiHost ? { Authorization: `Bearer ${accessToken}` } : {}; +}; + const mediaParse = (media_attachments) => media_attachments .map((item) => { @@ -59,6 +65,7 @@ async function getAccountStatuses(site, account_id, only_media) { const statuses_response = await got({ method: 'get', url: statuses_url, + headers: apiHeaders(site), }); const data = statuses_response.data; @@ -70,6 +77,7 @@ async function getAccountStatuses(site, account_id, only_media) { const account_response = await got({ method: 'get', url: account_url, + headers: apiHeaders(site), }); account_data = account_response.data; } @@ -95,9 +103,7 @@ async function getAccountIdByAcct(acct) { const search_response = await got({ method: 'get', url: search_url, - headers: { - ...(mastodonConfig.accessToken ? { Authorization: `Bearer ${mastodonConfig.accessToken}` } : {}), - }, + headers: apiHeaders(site), searchParams: { q: acct, type: 'accounts', @@ -123,6 +129,7 @@ async function getAccountIdByAcct(acct) { } module.exports = { + apiHeaders, parseStatuses, getAccountStatuses, getAccountIdByAcct, From 23563052143737acf6acd99b5fe8af8682a8c053 Mon Sep 17 00:00:00 2001 From: Rongrong Date: Mon, 4 Mar 2024 00:14:55 +0800 Subject: [PATCH 12/12] fix(route/weibo/user): querystring (#14636) * fix(route/weibo/user): querystring Signed-off-by: Rongrong * Update lib/routes/weibo/user.js --------- Signed-off-by: Rongrong --- lib/routes/weibo/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/routes/weibo/user.js b/lib/routes/weibo/user.js index a68b633c5e..3a38cadb60 100644 --- a/lib/routes/weibo/user.js +++ b/lib/routes/weibo/user.js @@ -1,5 +1,5 @@ import cache from '@/utils/cache'; -const querystring = require('query-string'); +import querystring from 'querystring'; import got from '@/utils/got'; const weiboUtils = require('./utils'); import { config } from '@/config';