From 51168fe8e09ffdc39104e8a741839cc69e39a851 Mon Sep 17 00:00:00 2001 From: Ethan Shen <42264778+nczitzk@users.noreply.github.com> Date: Sun, 7 Jan 2024 20:37:07 +0800 Subject: [PATCH 01/15] fix(route): Tradingview Blog (#14191) * fix(route): Tradingview Blog * fix: use tiny-async-pool --- lib/v2/tradingview/blog.js | 87 ++++++++++++++----- lib/v2/tradingview/maintainer.js | 2 +- lib/v2/tradingview/radar.js | 88 +++++++++++++++++++- lib/v2/tradingview/router.js | 2 +- lib/v2/tradingview/templates/description.art | 15 +++- website/docs/routes/program-update.mdx | 23 ++++- 6 files changed, 186 insertions(+), 31 deletions(-) diff --git a/lib/v2/tradingview/blog.js b/lib/v2/tradingview/blog.js index bbac1845fb3e2e..2efb7889b9ba66 100644 --- a/lib/v2/tradingview/blog.js +++ b/lib/v2/tradingview/blog.js @@ -6,55 +6,98 @@ const { art } = require('@/utils/render'); const path = require('path'); module.exports = async (ctx) => { - const language = ctx.params.language ?? 'en'; + const { category = 'en' } = ctx.params; + const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 22; const rootUrl = 'https://www.tradingview.com'; - const currentUrl = `${rootUrl}/blog/${language}`; + const currentUrl = new URL(`blog/${category.endsWith('/') ? category : `${category}/`}`, rootUrl).href; - const response = await got({ - method: 'get', - url: currentUrl, - }); + const { data: response } = await got(currentUrl); - const $ = cheerio.load(response.data); + const $ = cheerio.load(response); - const list = $('.articles-grid-item a[rel="bookmark"]') - .slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 20) + const items = $('article[id]') + .slice(0, limit) .toArray() .map((item) => { item = $(item); + const title = item.find('div.title').text(); + return { - title: item.find('.title').text(), - link: item.attr('href'), - pubDate: parseDate(item.find('.date').text(), 'MMMM D, YYYY'), + title, + link: item.find('a.articles-grid-link').prop('href'), + description: art(path.join(__dirname, 'templates/description.art'), { + image: { + src: item + .find('div.articles-grid-img img') + .prop('src') + .replace(/-\d+x\d+\./, '.'), + alt: title, + }, + }), + category: item + .find('a.section') + .toArray() + .map((c) => $(c).text()), + guid: `tradingview-blog-${category}-${item.prop('id')}`, + pubDate: parseDate(item.find('div.date').text(), 'MMM D, YYYY'), }; }); - const items = []; - for await (const item of asyncPool(3, list, (item) => + for await (const item of asyncPool(3, items, (item) => ctx.cache.tryGet(item.link, async () => { - const detailResponse = await got({ - method: 'get', - url: item.link, - }); + const { data: detailResponse } = await got(item.link); + + const content = cheerio.load(detailResponse); - const content = cheerio.load(detailResponse.data); + content('div.entry-content') + .find('img') + .each((_, e) => { + content(e).replaceWith( + art(path.join(__dirname, 'templates/description.art'), { + image: { + src: content(e) + .prop('src') + .replace(/-\d+x\d+\./, '.'), + width: content(e).prop('width'), + height: content(e).prop('height'), + }, + }) + ); + }); + item.title = content('meta[property="og:title"]').prop('content'); item.description = art(path.join(__dirname, 'templates/description.art'), { - image: content('.single-img img').attr('src'), - description: content('.entry-content').html(), + image: { + src: content('meta[property="og:image"]').prop('content'), + alt: item.title, + }, + description: content('div.entry-content').html(), }); + item.author = content('meta[property="og:site_name"]').prop('content'); + item.category = content('div.sections a.section') + .toArray() + .map((c) => content(c).text()); + item.pubDate = parseDate(content('div.single-date').text(), 'MMM D, YYYY'); return item; }) )) { + items.shift(); items.push(item); } + const icon = new URL($('link[rel="icon"]').prop('href'), rootUrl).href; + ctx.state.data = { + item: items, title: $('title').text(), link: currentUrl, - item: items, + description: $('div.site-subtitle').text(), + language: $('html').prop('lang'), + icon, + logo: icon, + subtitle: $('h1.site-title').text(), }; }; diff --git a/lib/v2/tradingview/maintainer.js b/lib/v2/tradingview/maintainer.js index 8135e010a57868..cb9d37b3a3a949 100644 --- a/lib/v2/tradingview/maintainer.js +++ b/lib/v2/tradingview/maintainer.js @@ -1,3 +1,3 @@ module.exports = { - '/blog/:language?': ['nczitzk'], + '/blog/:language?/category/:category?': ['nczitzk'], }; diff --git a/lib/v2/tradingview/radar.js b/lib/v2/tradingview/radar.js index 6dd935085aefd1..642caa3f60af72 100644 --- a/lib/v2/tradingview/radar.js +++ b/lib/v2/tradingview/radar.js @@ -5,8 +5,92 @@ module.exports = { { title: 'Blog', docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', - source: ['/blog/:language', '/'], - target: '/tradingview/blog', + source: ['/blog/:language/'], + target: '/tradingview/blog/:language/', + }, + { + title: 'Blog - Alerts', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/alerts/'], + target: '/tradingview/blog/:language/category/alerts', + }, + { + title: 'Blog - Bitcoin and Crypto', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/bitcoin-charts/'], + target: '/tradingview/blog/:language/category/bitcoin-charts', + }, + { + title: 'Blog - Business Updates', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/business-updates/'], + target: '/tradingview/blog/:language/category/business-updates', + }, + { + title: 'Blog - Charting', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/charts/'], + target: '/tradingview/blog/:language/category/charts', + }, + { + title: 'Blog - Charting Library', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/charting-library/'], + target: '/tradingview/blog/:language/category/charting-library', + }, + { + title: 'Blog - Data Feeds and Exchanges', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/data-feeds-exchanges/'], + target: '/tradingview/blog/:language/category/data-feeds-exchanges', + }, + { + title: 'Blog - Desktop', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/desktop/'], + target: '/tradingview/blog/:language/category/desktop', + }, + { + title: 'Blog - Market Analysis', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/market-analysis/'], + target: '/tradingview/blog/:language/category/market-analysis', + }, + { + title: 'Blog - Mobile', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/mobile/'], + target: '/tradingview/blog/:language/category/mobile', + }, + { + title: 'Blog - Pine Script®', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/pine/'], + target: '/tradingview/blog/:language/category/pine', + }, + { + title: 'Blog - Screener', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/stock-screener/'], + target: '/tradingview/blog/:language/category/stock-screener', + }, + { + title: 'Blog - Social', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/social/'], + target: '/tradingview/blog/:language/category/social', + }, + { + title: 'Blog - Trading and Brokerage', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/trading/'], + target: '/tradingview/blog/:language/category/trading', + }, + { + title: 'Blog - Widgets', + docs: 'https://docs.rsshub.app/routes/program-update#tradingview-blog', + source: ['/blog/:language/category/widgets/'], + target: '/tradingview/blog/:language/category/widgets', }, ], }, diff --git a/lib/v2/tradingview/router.js b/lib/v2/tradingview/router.js index fadb0f6b3767da..98bb22bf2c0d0a 100644 --- a/lib/v2/tradingview/router.js +++ b/lib/v2/tradingview/router.js @@ -1,3 +1,3 @@ module.exports = function (router) { - router.get('/blog/:language?', require('./blog')); + router.get('/blog/:category*', require('./blog')); }; diff --git a/lib/v2/tradingview/templates/description.art b/lib/v2/tradingview/templates/description.art index c823516c9a36ad..a89e118b25e33d 100644 --- a/lib/v2/tradingview/templates/description.art +++ b/lib/v2/tradingview/templates/description.art @@ -1,4 +1,13 @@ -{{ if image }} - +{{ if image?.src }} +
+ {{ image.alt }} +
{{ /if }} -{{@ description }} \ No newline at end of file + +{{ if description }} + {{@ description }} +{{ /if }} \ No newline at end of file diff --git a/website/docs/routes/program-update.mdx b/website/docs/routes/program-update.mdx index 506dae42bb64e3..ccf012212ff8e0 100644 --- a/website/docs/routes/program-update.mdx +++ b/website/docs/routes/program-update.mdx @@ -570,8 +570,8 @@ Logseq 开发团队已经放弃了 [旧网站](https://logseq.com/blog)。 ### Blog {#tradingview-blog} - - Language + + #### Language | Id | Language | | -- | ------------------- | @@ -595,6 +595,25 @@ Logseq 开发团队已经放弃了 [旧网站](https://logseq.com/blog)。 | sv | Svenska | | ar | العربية | | il | Hebrew | + + #### Category + + | Category | ID | + | ---------------------------------------------------------------------------------------------- | ----------------------------- | + | [Alerts](https://www.tradingview.com/blog/en/category/alerts/) | category/alerts | + | [Bitcoin and Crypto](https://www.tradingview.com/blog/en/category/bitcoin-charts/) | category/bitcoin-charts | + | [Business Updates](https://www.tradingview.com/blog/en/category/business-updates/) | category/business-updates | + | [Charting](https://www.tradingview.com/blog/en/category/charts/) | category/charts | + | [Charting Library](https://www.tradingview.com/blog/en/category/charting-library/) | category/charting-library | + | [Data Feeds and Exchanges](https://www.tradingview.com/blog/en/category/data-feeds-exchanges/) | category/data-feeds-exchanges | + | [Desktop](https://www.tradingview.com/blog/en/category/desktop/) | category/desktop | + | [Market Analysis](https://www.tradingview.com/blog/en/category/market-analysis/) | category/market-analysis | + | [Mobile](https://www.tradingview.com/blog/en/category/mobile/) | category/mobile | + | [Pine Script®](https://www.tradingview.com/blog/en/category/pine/) | category/pine | + | [Screener](https://www.tradingview.com/blog/en/category/stock-screener/) | category/stock-screener | + | [Social](https://www.tradingview.com/blog/en/category/social/) | category/social | + | [Trading and Brokerage](https://www.tradingview.com/blog/en/category/trading/) | category/trading | + | [Widgets](https://www.tradingview.com/blog/en/category/widgets/) | category/widgets | ## Typora {#typora} From 86dfd066d4123827711f680724e9650d44bcb6f9 Mon Sep 17 00:00:00 2001 From: SUEPbot <114787369+SUEPbot@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:06:09 +0800 Subject: [PATCH 02/15] fix(route): fix shiep/jsjxy shiep/jwc (#14196) --- lib/v2/shiep/config.js | 4 ++-- lib/v2/shiep/index.js | 29 ++++++++++++++++------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/lib/v2/shiep/config.js b/lib/v2/shiep/config.js index 8694d39a435f90..7051f3bd126f36 100644 --- a/lib/v2/shiep/config.js +++ b/lib/v2/shiep/config.js @@ -26,9 +26,9 @@ const config = { jjc: { title: '基建处', id: '327' }, jjxy: { title: '继续教育学院(国际教育学院)', id: '2582' }, jsjxfzzx: { title: '教师教学发展中心', id: '3909' }, - jsjxy: { title: '计算机科学与技术学院', id: 'xygg', listSelector: 'div.post-entry-2', pubDateSelector: 'span:nth-child(2)' }, + jsjxy: { title: '计算机科学与技术学院', id: 'xygg', listSelector: 'div.xylist', pubDateSelector: 'span:nth-child(2)' }, jszyzx: { title: '技术转移中心', id: '4247' }, - jwc: { title: '教务处', id: '227' }, + jwc: { title: '教务处', id: '227', listSelector: 'div.text-list li', pubDateSelector: 'span.time' }, jxfz: { title: '电力装备设计与制造虚拟仿真中心', id: '3330' }, kczx: { title: '能源电力科创中心', id: '3946' }, kyc: { title: '科研处/融合办', id: '834' }, diff --git a/lib/v2/shiep/index.js b/lib/v2/shiep/index.js index f189ddc9075fa9..044c4c41ca52aa 100644 --- a/lib/v2/shiep/index.js +++ b/lib/v2/shiep/index.js @@ -10,7 +10,13 @@ module.exports = async (ctx) => { const type = ctx.params.type; if (!Object.keys(config).includes(type)) { - throw Error('Invalid type'); + throw Error(`Invalid type: ${type}`); + } + + const { listSelector = '.list_item', pubDateSelector = '.Article_PublishDate', descriptionSelector = '.wp_articlecontent', title } = config[type]; + + if (!title) { + throw Error(`Invalid type: ${type}`); } const host = `https://${type}.shiep.edu.cn`; @@ -20,23 +26,21 @@ module.exports = async (ctx) => { const response = await got(link); const $ = cheerio.load(response.data); - const listSelector = config[type].listSelector || '.list_item'; - const pubDateSelector = config[type].pubDateSelector || '.Article_PublishDate'; - const descriptionSelector = config[type].descriptionSelector || '.wp_articlecontent'; - const list = $(listSelector) .toArray() - .filter((item) => { - const date = dayjs($(item).find(pubDateSelector).text().trim()); - return date.isValid(); - }) .map((item) => { item = $(item); + const pubDateText = item.find(pubDateSelector).text().trim(); + const match = pubDateText.match(/\b(\d{4}-\d{2}-\d{2})\b/); return { - title: item.find('a').attr('title') || item.find('a').text(), + title: item.find('a').attr('title') || item.find('h3').text() || item.find('a').text(), link: new URL(item.find('a').attr('href'), host).href, - pubDate: parseDate(item.find(pubDateSelector).text().trim(), 'YYYY-MM-DD'), + pubDate: match ? parseDate(match[0], 'YYYY-MM-DD') : null, }; + }) + .filter((item) => { + const date = dayjs(item.pubDate); + return date.isValid(); }); const items = await Promise.all( @@ -62,9 +66,8 @@ module.exports = async (ctx) => { ); ctx.state.data = { - title: '上海电力大学-' + config[type].title, + title: `上海电力大学-${title}`, link, - description: '上海电力大学-' + config[type].title, item: items, }; }; From 176341e95b7ef784c6183130cbfa80c1249191cf Mon Sep 17 00:00:00 2001 From: Manish Bhattarai Date: Sun, 7 Jan 2024 23:16:11 -0500 Subject: [PATCH 03/15] docs: change html example to use items variable instead of item (#14205) * change html example to use items variable instead of item The existing example for HTML retrieval uses 'item' variable on item retrieval, but the final rss output uses the 'items' variable. This results in undefined variable for anyone who directly uses the example code. * docs: fix cn docs too --------- --- website/docs/joinus/new-rss/start-code.md | 4 ++-- .../current/joinus/new-rss/start-code.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/joinus/new-rss/start-code.md b/website/docs/joinus/new-rss/start-code.md index 6f9061d0b3a513..525c3cfeac331f 100644 --- a/website/docs/joinus/new-rss/start-code.md +++ b/website/docs/joinus/new-rss/start-code.md @@ -320,7 +320,7 @@ Next, we'll use Cheerio selectors to select the relevant HTML elements, parse th // We use a Cheerio selector to select all 'div' elements with the class name 'js-navigation-container' // that contain child elements with the class name 'flex-auto'. // highlight-start - const item = $('div.js-navigation-container .flex-auto') + const items = $('div.js-navigation-container .flex-auto') // We use the `toArray()` method to retrieve all the DOM elements selected as an array. .toArray() // We use the `map()` method to traverse the array and parse the data we need from each element. @@ -366,7 +366,7 @@ module.exports = async (ctx) => { const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); - const item = $('div.js-navigation-container .flex-auto') + const items = $('div.js-navigation-container .flex-auto') .toArray() .map((item) => { item = $(item); diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md index eec52ca0c60bcf..ff13344269fa9b 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/joinus/new-rss/start-code.md @@ -317,7 +317,7 @@ module.exports = async (ctx) => { // 我们使用 Cheerio 选择器选择所有带类名“js-navigation-container”的“div”元素, // 其中包含带类名“flex-auto”的子元素。 // highlight-start - const item = $('div.js-navigation-container .flex-auto') + const items = $('div.js-navigation-container .flex-auto') // 使用“toArray()”方法将选择的所有 DOM 元素以数组的形式返回。 .toArray() // 使用“map()”方法遍历数组,并从每个元素中解析需要的数据。 @@ -363,7 +363,7 @@ module.exports = async (ctx) => { const { data: response } = await got(`${baseUrl}/${user}/${repo}/issues`); const $ = cheerio.load(response); - const item = $('div.js-navigation-container .flex-auto') + const items = $('div.js-navigation-container .flex-auto') .toArray() .map((item) => { item = $(item); From 64d87889decc60586df594dd6cb08eb04ea49fe2 Mon Sep 17 00:00:00 2001 From: Ethan Shen <42264778+nczitzk@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:22:35 +0800 Subject: [PATCH 04/15] =?UTF-8?q?feat(route):=20add=20=E4=B8=AD=E5=8D=8E?= =?UTF-8?q?=E5=85=A8=E5=9B=BD=E4=B8=93=E5=88=A9=E4=BB=A3=E7=90=86=E5=B8=88?= =?UTF-8?q?=E5=8D=8F=E4=BC=9A=20(#14197)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/v2/acpaa/index.js | 57 +++++++++++++++++++++++++++++++++++ lib/v2/acpaa/maintainer.js | 3 ++ lib/v2/acpaa/radar.js | 19 ++++++++++++ lib/v2/acpaa/router.js | 3 ++ website/docs/routes/other.mdx | 6 ++++ 5 files changed, 88 insertions(+) create mode 100644 lib/v2/acpaa/index.js create mode 100644 lib/v2/acpaa/maintainer.js create mode 100644 lib/v2/acpaa/radar.js create mode 100644 lib/v2/acpaa/router.js diff --git a/lib/v2/acpaa/index.js b/lib/v2/acpaa/index.js new file mode 100644 index 00000000000000..6a96add2043b01 --- /dev/null +++ b/lib/v2/acpaa/index.js @@ -0,0 +1,57 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const timezone = require('@/utils/timezone'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const { id = '1', name = '重要通知' } = ctx.params; + const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30; + + const rootUrl = 'http://www.acpaa.cn'; + const currentUrl = new URL(`article/taglist.jhtml?tagIds=${id}&tagname=${name}`, rootUrl).href; + + const { data: response } = await got(currentUrl); + + const $ = cheerio.load(response); + + let items = $('div.text01 ul li a[title]') + .slice(0, limit) + .toArray() + .map((item) => { + item = $(item); + + return { + title: item.prop('title'), + link: new URL(item.prop('href'), rootUrl).href, + pubDate: timezone(parseDate(item.find('span[title]').prop('title')), +8), + }; + }); + + items = await Promise.all( + items.map((item) => + ctx.cache.tryGet(item.link, async () => { + const { data: detailResponse } = await got(item.link); + + const content = cheerio.load(detailResponse); + + item.title = content('div.xhjj_head01').text(); + item.description = content('div.text01').html(); + + return item; + }) + ) + ); + + const author = $('title').text().replace(/-/g, ''); + const subtitle = $('span.myTitle').text().trim(); + + ctx.state.data = { + item: items, + title: `${author} - ${subtitle}`, + link: currentUrl, + description: $('meta[property="og:description"]').prop('content'), + language: 'zh', + subtitle, + author, + }; +}; diff --git a/lib/v2/acpaa/maintainer.js b/lib/v2/acpaa/maintainer.js new file mode 100644 index 00000000000000..de07fba0f94c0b --- /dev/null +++ b/lib/v2/acpaa/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:id?/:name?': ['nczitzk'], +}; diff --git a/lib/v2/acpaa/radar.js b/lib/v2/acpaa/radar.js new file mode 100644 index 00000000000000..3be0bb4192a619 --- /dev/null +++ b/lib/v2/acpaa/radar.js @@ -0,0 +1,19 @@ +module.exports = { + 'acpaa.cn': { + _name: '中华全国专利代理师协会', + '.': [ + { + title: '文章', + docs: 'https://docs.rsshub.app/routes/other#zhong-hua-quan-guo-zhuan-li-dai-li-shi-xie-hui', + source: ['/article/taglist.jhtml'], + target: (url) => { + url = new URL(url); + const id = url.searchParams.get('id'); + const name = url.searchParams.get('name'); + + return `/acpaa${id ? `/${id}${name ? `/${name}` : ''}` : ''}`; + }, + }, + ], + }, +}; diff --git a/lib/v2/acpaa/router.js b/lib/v2/acpaa/router.js new file mode 100644 index 00000000000000..b9338560b36c9a --- /dev/null +++ b/lib/v2/acpaa/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:id?/:name?', require('./')); +}; diff --git a/website/docs/routes/other.mdx b/website/docs/routes/other.mdx index 42aeebd6930b76..273321b1082a87 100644 --- a/website/docs/routes/other.mdx +++ b/website/docs/routes/other.mdx @@ -1065,6 +1065,12 @@ Specify options (in the format of query string) in parameter `routeParams` param | short | zs | xh | xc | xhmr | xhmc | xcmr | xcmc | +## 中华全国专利代理师协会 {#zhong-hua-quan-guo-zhuan-li-dai-li-shi-xie-hui} + +### 标签 {#zhong-hua-quan-guo-zhuan-li-dai-li-shi-xie-hui-biao-qian} + + + ## はてな {#%E3%81%AF%E3%81%A6%E3%81%AA} ### はてな匿名ダイアリー - 人気記事アーカイブ {#%E3%81%AF%E3%81%A6%E3%81%AA-%E3%81%AF%E3%81%A6%E3%81%AA-ni-ming-%E3%83%80%E3%82%A4%E3%82%A2%E3%83%AA%E3%83%BC-ren-qi-ji-shi-%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96} From acf59ee40edbd208c73d57a77222a3a90dec3a6b Mon Sep 17 00:00:00 2001 From: Jebbs Date: Mon, 8 Jan 2024 12:49:17 +0800 Subject: [PATCH 05/15] fix: zhihu timeline (#14169) * fix zhihu timeline * deal with content in an array * adopt content_html if exists --- lib/v2/zhihu/timeline.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/v2/zhihu/timeline.js b/lib/v2/zhihu/timeline.js index ed648dc19109ea..67162a37055ffb 100644 --- a/lib/v2/zhihu/timeline.js +++ b/lib/v2/zhihu/timeline.js @@ -53,13 +53,28 @@ module.exports = async (ctx) => { return actors.map((e) => e.name).join(', '); }; + const getContent = (content) => { + if (!content || !Array.isArray(content)) { + return content; + } + // content can be a string or an array of objects + return ( + content + .map((e) => e.content) + .filter((e) => e instanceof String && !!e) + // some content may not be wrapped in tag, it will cause error when parsing + .map((e) => `
${e}
`) + .join('') + ); + }; + const buildItem = (e) => { if (!e || !e.target) { return {}; } return { title: `${e.action_text_tpl.replace('{}', buildActors(e))}: ${getOne([e.target.title, e.target.question ? e.target.question.title : ''])}`, - description: utils.ProcessImage(getOne([e.target.content, e.target.detail, e.target.excerpt, ''])), + description: utils.ProcessImage(`
${getOne([e.target.content_html, getContent(e.target.content), e.target.detail, e.target.excerpt, ''])}
`), pubDate: parseDate(e.updated_time * 1000), link: buildLink(e), author: e.target.author ? e.target.author.name : '', From c626f8ccde9944284812f0e8100f078cb838bd86 Mon Sep 17 00:00:00 2001 From: Nano Date: Mon, 8 Jan 2024 13:48:20 +0800 Subject: [PATCH 06/15] =?UTF-8?q?fix(route):=20=E5=A4=84=E7=90=86=E5=A4=A7?= =?UTF-8?q?=E9=BA=A6=E7=BD=91=E6=9F=A5=E8=AF=A2=E7=BB=93=E6=9E=9C=E4=B8=BA?= =?UTF-8?q?=E7=A9=BA=E7=9A=84=E6=83=85=E5=86=B5=20(#14203)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(route): 处理大麦网查询结果为空的情况 * refactor: migrate to v2 --------- --- lib/router.js | 2 +- lib/routes/damai/activity.js | 28 ------------------ lib/v2/damai/activity.js | 44 +++++++++++++++++++++++++++++ lib/v2/damai/maintainer.js | 3 ++ lib/v2/damai/radar.js | 13 +++++++++ lib/v2/damai/router.js | 3 ++ lib/v2/damai/templates/activity.art | 5 ++++ website/docs/routes/shopping.mdx | 2 +- 8 files changed, 70 insertions(+), 30 deletions(-) delete mode 100644 lib/routes/damai/activity.js create mode 100644 lib/v2/damai/activity.js create mode 100644 lib/v2/damai/maintainer.js create mode 100644 lib/v2/damai/radar.js create mode 100644 lib/v2/damai/router.js create mode 100644 lib/v2/damai/templates/activity.art diff --git a/lib/router.js b/lib/router.js index 9ba588b478503c..a5a00f7c91cd16 100644 --- a/lib/router.js +++ b/lib/router.js @@ -911,7 +911,7 @@ router.get('/4gamers/tag/:tag', lazyloadRouteHandler('./routes/4gamers/tag')); router.get('/4gamers/topic/:topic', lazyloadRouteHandler('./routes/4gamers/topic')); // 大麦网 -router.get('/damai/activity/:city/:category/:subcategory/:keyword?', lazyloadRouteHandler('./routes/damai/activity')); +// router.get('/damai/activity/:city/:category/:subcategory/:keyword?', lazyloadRouteHandler('./routes/damai/activity')); // 桂林电子科技大学新闻资讯 router.get('/guet/xwzx/:type?', lazyloadRouteHandler('./routes/guet/news')); diff --git a/lib/routes/damai/activity.js b/lib/routes/damai/activity.js deleted file mode 100644 index f20245c46fcd87..00000000000000 --- a/lib/routes/damai/activity.js +++ /dev/null @@ -1,28 +0,0 @@ -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const city = ctx.params.city === '全部' ? '' : ctx.params.city; - const category = ctx.params.category === '全部' ? '' : ctx.params.category; - const subcategory = ctx.params.subcategory === '全部' ? '' : ctx.params.subcategory; - const keyword = ctx.params.keyword ? ctx.params.keyword : ''; - - const url = `https://search.damai.cn/searchajax.html?keyword=${encodeURIComponent(keyword)}&cty=${encodeURIComponent(city)}&ctl=${encodeURIComponent(category)}&sctl=${encodeURIComponent( - subcategory - )}&tsg=0&st=&et=&order=3&pageSize=30&currPage=1&tn=`; - - const response = await got.get(url); - const data = response.data; - const list = data.pageData.resultData; - - ctx.state.data = { - title: `大麦网票务 - ${city ? city : '全国'} - ${category ? category : '全部分类'}${subcategory ? ' - ' + subcategory : ''}${keyword ? ' - ' + keyword : ''}`, - link: 'https://search.damai.cn/search.htm', - item: list.map((item) => ({ - title: item.nameNoHtml, - author: item.actors ? item.actors.replace(/<[^<>]*>/, '') : '大麦网', - description: `

${item.description}

地点:${item.venuecity} | ${item.venue}

时间:${item.showtime}

票价:${item.price_str}

`, - pubDate: new Date(), - link: `https://detail.damai.cn/item.htm?id=${item.projectid}`, - })), - }; -}; diff --git a/lib/v2/damai/activity.js b/lib/v2/damai/activity.js new file mode 100644 index 00000000000000..bc6bb8ea91c9f5 --- /dev/null +++ b/lib/v2/damai/activity.js @@ -0,0 +1,44 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { art } = require('@/utils/render'); +const { join } = require('path'); + +module.exports = async (ctx) => { + const city = ctx.params.city === '全部' ? '' : ctx.params.city; + const category = ctx.params.category === '全部' ? '' : ctx.params.category; + const subcategory = ctx.params.subcategory === '全部' ? '' : ctx.params.subcategory; + const keyword = ctx.params.keyword ? ctx.params.keyword : ''; + + const url = 'https://search.damai.cn/searchajax.html'; + + const response = await got(url, { + searchParams: { + keyword, + cty: city, + ctl: category, + sctl: subcategory, + tsg: 0, + st: '', + et: '', + order: 3, + pageSize: 30, + currPage: 1, + tn: '', + }, + }); + const data = response.data; + const list = data.pageData.resultData || []; + + ctx.state.data = { + title: `大麦网票务 - ${city || '全国'} - ${category || '全部分类'}${subcategory ? ' - ' + subcategory : ''}${keyword ? ' - ' + keyword : ''}`, + link: 'https://search.damai.cn/search.htm', + item: list.map((item) => ({ + title: item.nameNoHtml, + author: item.actors ? cheerio.load(item.actors, null, false).text() : '大麦网', + description: art(join(__dirname, 'templates/activity.art'), { + item, + }), + link: `https://detail.damai.cn/item.htm?id=${item.projectid}`, + })), + }; +}; diff --git a/lib/v2/damai/maintainer.js b/lib/v2/damai/maintainer.js new file mode 100644 index 00000000000000..1e5144889ef33a --- /dev/null +++ b/lib/v2/damai/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/activity/:city/:category/:subcategory/:keyword?': ['hoilc'], +}; diff --git a/lib/v2/damai/radar.js b/lib/v2/damai/radar.js new file mode 100644 index 00000000000000..bd47baad76848c --- /dev/null +++ b/lib/v2/damai/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'damai.cn': { + _name: '大麦网', + search: [ + { + title: '票务更新', + docs: 'https://docs.rsshub.app/routes/shopping#da-mai-wang', + source: ['/search.html'], + target: (_params, url) => `/damai/activity/全部/全部/全部/${new URL(url).searchParams.get('keyword') || ''}`, + }, + ], + }, +}; diff --git a/lib/v2/damai/router.js b/lib/v2/damai/router.js new file mode 100644 index 00000000000000..98e08502ea7df9 --- /dev/null +++ b/lib/v2/damai/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/activity/:city/:category/:subcategory/:keyword?', require('./activity')); +}; diff --git a/lib/v2/damai/templates/activity.art b/lib/v2/damai/templates/activity.art new file mode 100644 index 00000000000000..5e0e359c541af8 --- /dev/null +++ b/lib/v2/damai/templates/activity.art @@ -0,0 +1,5 @@ + +

{{@ item.description }}

+

地点:{{ item.venuecity }} | {{ item.venue }}

+

时间:{{ item.showtime }}

+

票价:{{ item.price_str }}

diff --git a/website/docs/routes/shopping.mdx b/website/docs/routes/shopping.mdx index 749e0a03579794..767cdd6bcee773 100644 --- a/website/docs/routes/shopping.mdx +++ b/website/docs/routes/shopping.mdx @@ -239,7 +239,7 @@ For instance, in `https://www.zagg.com/en_us/new-arrivals?brand=164&cat=3038%2C3 ### 票务更新 {#da-mai-wang-piao-wu-geng-xin} - + 城市、分类名、子分类名,请参见[大麦网搜索页面](https://search.damai.cn/search.htm) From 6a3a89ff82a73400d8e2642fa74df5395a2e1d3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 22:06:44 +0000 Subject: [PATCH 07/15] chore(deps): bump @tonyrl/rand-user-agent from 2.0.44 to 2.0.45 (#14208) * chore(deps): bump @tonyrl/rand-user-agent from 2.0.44 to 2.0.45 Bumps [@tonyrl/rand-user-agent](https://github.com/TonyRL/rand-user-agent) from 2.0.44 to 2.0.45. - [Release notes](https://github.com/TonyRL/rand-user-agent/releases) - [Commits](https://github.com/TonyRL/rand-user-agent/compare/v2.0.44...v2.0.45) --- updated-dependencies: - dependency-name: "@tonyrl/rand-user-agent" 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 | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 4f0d5640392be9..0228a7fec6598f 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "@notionhq/client": "2.2.14", "@postlight/parser": "2.2.3", "@sentry/node": "7.92.0", - "@tonyrl/rand-user-agent": "2.0.44", + "@tonyrl/rand-user-agent": "2.0.45", "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 e2563fcde3559b..5f9e2b653224e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,8 @@ dependencies: specifier: 7.92.0 version: 7.92.0 '@tonyrl/rand-user-agent': - specifier: 2.0.44 - version: 2.0.44 + specifier: 2.0.45 + version: 2.0.45 aes-js: specifier: 3.1.2 version: 3.1.2 @@ -1357,8 +1357,8 @@ packages: defer-to-connect: 2.0.1 dev: false - /@tonyrl/rand-user-agent@2.0.44: - resolution: {integrity: sha512-m+186oR7dSKjbOcQYW7twY/uLrstr4zi69FI0bqOjiyoKPuRkXgI5VWQss2VNACKn18trI0qtqbO+6B+UJqbMQ==} + /@tonyrl/rand-user-agent@2.0.45: + resolution: {integrity: sha512-7G3VVt+7VHo3ifY+ztvbA9IO2kJyo2HjasKfiYwcVP38ENnQ980Xh6Aw5vl3+gQ6AWck03fDqNJbiEp74pikxA==} engines: {node: '>=14.16'} dev: false From c5b9f06b65e017cdff549fece502acef4590f5ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 22:16:04 +0000 Subject: [PATCH 08/15] chore(deps): bump jsdom from 23.1.0 to 23.2.0 (#14209) * chore(deps): bump jsdom from 23.1.0 to 23.2.0 Bumps [jsdom](https://github.com/jsdom/jsdom) from 23.1.0 to 23.2.0. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md) - [Commits](https://github.com/jsdom/jsdom/compare/23.1.0...23.2.0) --- updated-dependencies: - dependency-name: jsdom 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 | 50 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 0228a7fec6598f..1a4e368ba22be3 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "ioredis": "5.3.2", "ip-regex": "4.3.0", "is-localhost-ip": "2.0.0", - "jsdom": "23.1.0", + "jsdom": "23.2.0", "json-bigint": "1.0.0", "json5": "2.2.3", "jsrsasign": "10.9.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f9e2b653224e0..1406e4f2475e77 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,8 +93,8 @@ dependencies: specifier: 2.0.0 version: 2.0.0 jsdom: - specifier: 23.1.0 - version: 23.1.0 + specifier: 23.2.0 + version: 23.2.0 json-bigint: specifier: 1.0.0 version: 1.0.0 @@ -413,6 +413,14 @@ packages: '@jridgewell/trace-mapping': 0.3.19 dev: true + /@asamuzakjp/dom-selector@2.0.1: + resolution: {integrity: sha512-QJAJffmCiymkv6YyQ7voyQb5caCth6jzZsQncYCpHXrJ7RqdYG5y43+is8mnFcYubdOkr7cn1+na9BdFMxqw7w==} + dependencies: + bidi-js: 1.0.3 + css-tree: 2.3.1 + is-potential-custom-element-name: 1.0.1 + dev: false + /@babel/code-frame@7.22.13: resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} engines: {node: '>=6.9.0'} @@ -2226,6 +2234,12 @@ packages: dependencies: tweetnacl: 0.14.5 + /bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + dependencies: + require-from-string: 2.0.2 + dev: false + /big-integer@1.6.51: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} @@ -2861,6 +2875,14 @@ packages: nth-check: 2.1.1 dev: false + /css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.0.2 + dev: false + /css-what@2.1.3: resolution: {integrity: sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==} dev: false @@ -5247,8 +5269,8 @@ packages: engines: {node: '>=0.1.90'} dev: true - /jsdom@23.1.0: - resolution: {integrity: sha512-wRscu8dBFxi7O65Cvi0jFRDv0Qa7XEHPix8Qg/vlXHLAMQsRWV1EDeQHBermzXf4Dt7JtFgBLbva3iTcBZDXEQ==} + /jsdom@23.2.0: + resolution: {integrity: sha512-L88oL7D/8ufIES+Zjz7v0aes+oBMh2Xnh3ygWvL0OaICOomKEPKuPnIfBJekiXr+BHbbMjrWn/xqrDQuxFTeyA==} engines: {node: '>=18'} peerDependencies: canvas: ^2.11.2 @@ -5256,6 +5278,7 @@ packages: canvas: optional: true dependencies: + '@asamuzakjp/dom-selector': 2.0.1 cssstyle: 4.0.1 data-urls: 5.0.0 decimal.js: 10.4.3 @@ -5264,7 +5287,6 @@ packages: http-proxy-agent: 7.0.0 https-proxy-agent: 7.0.2 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.7 parse5: 7.1.2 rrweb-cssom: 0.6.0 saxes: 6.0.0 @@ -6066,6 +6088,10 @@ packages: '@types/mdast': 4.0.3 dev: true + /mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + dev: false + /mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} dev: false @@ -6939,10 +6965,6 @@ packages: boolbase: 1.0.0 dev: false - /nwsapi@2.2.7: - resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} - dev: false - /oauth-1.0a@2.2.6: resolution: {integrity: sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==} dev: false @@ -7887,6 +7909,11 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: false + /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: false @@ -8203,6 +8230,11 @@ packages: atomic-sleep: 1.0.0 dev: false + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: false + /source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: From 377dd9f2c78bfddb94d08610bc8b60feb26eee30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 22:38:50 +0000 Subject: [PATCH 09/15] chore(deps-dev): bump @types/react from 18.2.46 to 18.2.47 in /website (#14210) Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.46 to 18.2.47. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: "@types/react" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- website/package.json | 2 +- website/pnpm-lock.yaml | 54 +++++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/website/package.json b/website/package.json index 853ce3d2d23f8d..c9b01ead84a699 100644 --- a/website/package.json +++ b/website/package.json @@ -36,7 +36,7 @@ "@docusaurus/types": "3.1.0", "@types/markdown-it": "^13.0.7", "@types/mdx-js__react": "^1.5.8", - "@types/react": "^18.2.46", + "@types/react": "^18.2.47", "@types/react-dom": "^18.2.18", "typescript": "^5.3.3" }, diff --git a/website/pnpm-lock.yaml b/website/pnpm-lock.yaml index c499923deee573..1dda6f60ebd789 100644 --- a/website/pnpm-lock.yaml +++ b/website/pnpm-lock.yaml @@ -19,10 +19,10 @@ dependencies: version: 3.1.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@docusaurus/preset-classic': specifier: 3.1.0 - version: 3.1.0(@algolia/client-search@4.22.0)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3) + version: 3.1.0(@algolia/client-search@4.22.0)(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3) '@mdx-js/react': specifier: ^3.0.0 - version: 3.0.0(@types/react@18.2.46)(react@18.2.0) + version: 3.0.0(@types/react@18.2.47)(react@18.2.0) clsx: specifier: ^2.1.0 version: 2.1.0 @@ -62,8 +62,8 @@ devDependencies: specifier: ^1.5.8 version: 1.5.8 '@types/react': - specifier: ^18.2.46 - version: 18.2.46 + specifier: ^18.2.47 + version: 18.2.47 '@types/react-dom': specifier: ^18.2.18 version: 18.2.18 @@ -1641,7 +1641,7 @@ packages: resolution: {integrity: sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==} dev: false - /@docsearch/react@3.5.2(@algolia/client-search@4.22.0)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0): + /@docsearch/react@3.5.2(@algolia/client-search@4.22.0)(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0): resolution: {integrity: sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==} peerDependencies: '@types/react': '>= 16.8.0 < 19.0.0' @@ -1661,7 +1661,7 @@ packages: '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.22.0)(algoliasearch@4.22.0)(search-insights@2.13.0) '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.22.0)(algoliasearch@4.22.0) '@docsearch/css': 3.5.2 - '@types/react': 18.2.46 + '@types/react': 18.2.47 algoliasearch: 4.22.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -2001,7 +2001,7 @@ packages: '@docusaurus/react-loadable': 5.5.2(react@18.2.0) '@docusaurus/types': 3.1.0(react-dom@18.2.0)(react@18.2.0) '@types/history': 4.7.11 - '@types/react': 18.2.46 + '@types/react': 18.2.47 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.3 react: 18.2.0 @@ -2393,7 +2393,7 @@ packages: - webpack-cli dev: false - /@docusaurus/preset-classic@3.1.0(@algolia/client-search@4.22.0)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3): + /@docusaurus/preset-classic@3.1.0(@algolia/client-search@4.22.0)(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3): resolution: {integrity: sha512-xGLQRFmmT9IinAGUDVRYZ54Ys28USNbA3OTXQXnSJLPr1rCY7CYnHI4XoOnKWrNnDiAI4ruMzunXWyaElUYCKQ==} engines: {node: '>=18.0'} peerDependencies: @@ -2409,9 +2409,9 @@ packages: '@docusaurus/plugin-google-gtag': 3.1.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@docusaurus/plugin-google-tag-manager': 3.1.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@docusaurus/plugin-sitemap': 3.1.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) - '@docusaurus/theme-classic': 3.1.0(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) + '@docusaurus/theme-classic': 3.1.0(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@docusaurus/theme-common': 3.1.0(@docusaurus/types@3.1.0)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) - '@docusaurus/theme-search-algolia': 3.1.0(@algolia/client-search@4.22.0)(@docusaurus/types@3.1.0)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3) + '@docusaurus/theme-search-algolia': 3.1.0(@algolia/client-search@4.22.0)(@docusaurus/types@3.1.0)(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3) '@docusaurus/types': 3.1.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -2442,11 +2442,11 @@ packages: peerDependencies: react: '*' dependencies: - '@types/react': 18.2.46 + '@types/react': 18.2.47 prop-types: 15.8.1 react: 18.2.0 - /@docusaurus/theme-classic@3.1.0(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3): + /@docusaurus/theme-classic@3.1.0(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3): resolution: {integrity: sha512-/+jMl2Z9O8QQxves5AtHdt91gWsEZFgOV3La/6eyKEd7QLqQUtM5fxEJ40rq9NKYjqCd1HzZ9egIMeJoWwillw==} engines: {node: '>=18.0'} peerDependencies: @@ -2465,7 +2465,7 @@ packages: '@docusaurus/utils': 3.1.0(@docusaurus/types@3.1.0) '@docusaurus/utils-common': 3.1.0(@docusaurus/types@3.1.0) '@docusaurus/utils-validation': 3.1.0(@docusaurus/types@3.1.0) - '@mdx-js/react': 3.0.0(@types/react@18.2.46)(react@18.2.0) + '@mdx-js/react': 3.0.0(@types/react@18.2.47)(react@18.2.0) clsx: 2.1.0 copy-text-to-clipboard: 3.2.0 infima: 0.2.0-alpha.43 @@ -2515,7 +2515,7 @@ packages: '@docusaurus/utils': 3.1.0(@docusaurus/types@3.1.0) '@docusaurus/utils-common': 3.1.0(@docusaurus/types@3.1.0) '@types/history': 4.7.11 - '@types/react': 18.2.46 + '@types/react': 18.2.47 '@types/react-router-config': 5.0.11 clsx: 2.1.0 parse-numeric-range: 1.3.0 @@ -2544,14 +2544,14 @@ packages: - webpack-cli dev: false - /@docusaurus/theme-search-algolia@3.1.0(@algolia/client-search@4.22.0)(@docusaurus/types@3.1.0)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3): + /@docusaurus/theme-search-algolia@3.1.0(@algolia/client-search@4.22.0)(@docusaurus/types@3.1.0)(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3): resolution: {integrity: sha512-8cJH0ZhPsEDjq3jR3I+wHmWzVY2bXMQJ59v2QxUmsTZxbWA4u+IzccJMIJx4ooFl9J6iYynwYsFuHxyx/KUmfQ==} engines: {node: '>=18.0'} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 dependencies: - '@docsearch/react': 3.5.2(@algolia/client-search@4.22.0)(@types/react@18.2.46)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0) + '@docsearch/react': 3.5.2(@algolia/client-search@4.22.0)(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0) '@docusaurus/core': 3.1.0(@docusaurus/types@3.1.0)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@docusaurus/logger': 3.1.0 '@docusaurus/plugin-content-docs': 3.1.0(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) @@ -2611,7 +2611,7 @@ packages: react-dom: ^18.0.0 dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.46 + '@types/react': 18.2.47 commander: 5.1.0 joi: 17.11.0 react: 18.2.0 @@ -2635,7 +2635,7 @@ packages: dependencies: '@mdx-js/mdx': 3.0.0 '@types/history': 4.7.11 - '@types/react': 18.2.46 + '@types/react': 18.2.47 commander: 5.1.0 joi: 17.11.0 react: 18.2.0 @@ -2874,14 +2874,14 @@ packages: transitivePeerDependencies: - supports-color - /@mdx-js/react@3.0.0(@types/react@18.2.46)(react@18.2.0): + /@mdx-js/react@3.0.0(@types/react@18.2.47)(react@18.2.0): resolution: {integrity: sha512-nDctevR9KyYFyV+m+/+S4cpzCWHqj+iHDHq3QrsWezcC+B17uZdIWgCguESUkwFhM3n/56KxWVE3V6EokrmONQ==} peerDependencies: '@types/react': '>=16' react: '>=16' dependencies: '@types/mdx': 2.0.9 - '@types/react': 18.2.46 + '@types/react': 18.2.47 react: 18.2.0 dev: false @@ -3351,7 +3351,7 @@ packages: /@types/mdx-js__react@1.5.8: resolution: {integrity: sha512-iLQL8JZ4AZ+rpZvGUsQwENffpsSCMLYB8kE6OhGasLmdYn7aSLq53uOvZrKx5FM+hymE2nm08HDfq7tFx02ElA==} dependencies: - '@types/react': 18.2.46 + '@types/react': 18.2.47 dev: true /@types/mdx@2.0.10: @@ -3409,31 +3409,31 @@ packages: /@types/react-dom@18.2.18: resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} dependencies: - '@types/react': 18.2.46 + '@types/react': 18.2.47 dev: true /@types/react-router-config@5.0.11: resolution: {integrity: sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.46 + '@types/react': 18.2.47 '@types/react-router': 5.1.20 /@types/react-router-dom@5.3.3: resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.46 + '@types/react': 18.2.47 '@types/react-router': 5.1.20 /@types/react-router@5.1.20: resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.46 + '@types/react': 18.2.47 - /@types/react@18.2.46: - resolution: {integrity: sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w==} + /@types/react@18.2.47: + resolution: {integrity: sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==} dependencies: '@types/prop-types': 15.7.9 '@types/scheduler': 0.16.5 From 413c97a0cf95fe616523d4fc7969854ca9c4fe71 Mon Sep 17 00:00:00 2001 From: Damian Kaczmarczyk Date: Tue, 9 Jan 2024 16:40:40 +0100 Subject: [PATCH 10/15] feat(route): Add Onet (#14200) * feat(route): Add Onet * use arrow function in `router.js` * Update lib/v2/onet/templates/article.art * Update lib/v2/onet/templates/image.art * Update lib/v2/onet/maintainer.js * Update website/docs/routes/new-media.mdx --------- --- lib/v2/onet/maintainer.js | 3 ++ lib/v2/onet/news.js | 56 +++++++++++++++++++++++++++++++ lib/v2/onet/radar.js | 13 +++++++ lib/v2/onet/router.js | 3 ++ lib/v2/onet/templates/article.art | 5 +++ lib/v2/onet/templates/image.art | 9 +++++ lib/v2/onet/utils.js | 51 ++++++++++++++++++++++++++++ website/docs/routes/new-media.mdx | 8 +++++ 8 files changed, 148 insertions(+) create mode 100644 lib/v2/onet/maintainer.js create mode 100644 lib/v2/onet/news.js create mode 100644 lib/v2/onet/radar.js create mode 100644 lib/v2/onet/router.js create mode 100644 lib/v2/onet/templates/article.art create mode 100644 lib/v2/onet/templates/image.art create mode 100644 lib/v2/onet/utils.js diff --git a/lib/v2/onet/maintainer.js b/lib/v2/onet/maintainer.js new file mode 100644 index 00000000000000..8a1875e34b79c9 --- /dev/null +++ b/lib/v2/onet/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/news': ['Vegann'], +}; diff --git a/lib/v2/onet/news.js b/lib/v2/onet/news.js new file mode 100644 index 00000000000000..225e146a733da2 --- /dev/null +++ b/lib/v2/onet/news.js @@ -0,0 +1,56 @@ +const parser = require('@/utils/rss-parser'); +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); +const { parseArticleContent, parseMainImage } = require('./utils'); + +module.exports = async (ctx) => { + const rssUrl = 'https://wiadomosci.onet.pl/.feed'; + const feed = await parser.parseURL(rssUrl); + const items = await Promise.all( + feed.items.map(async (item) => { + const { description, author, category } = await ctx.cache.tryGet(item.link, async () => { + const { data: response } = await got(item.link, { + headers: { + referer: 'https://www.onet.pl/', // for some reason onet.pl will redirect to the main page if referer is not set + }, + }); + + const $ = cheerio.load(response); + const content = parseArticleContent($); + + const mainImage = parseMainImage($); + + const description = art(path.join(__dirname, 'templates/article.art'), { + mainImage, + lead: $('#lead').text()?.trim(), + content: content.html()?.trim(), + }); + + const author = $('.authorNameWrapper span[itemprop="name"]').text()?.trim(); + const category = $('span.relatedTopic').text()?.trim(); + + return { description, author, category }; + }); + return { + title: item.title, + link: item.link, + description, + author, + category, + pubDate: parseDate(item.pubDate), + guid: item.id, + }; + }) + ); + ctx.state.data = { + title: feed.title, + link: feed.link, + description: feed.title, + item: items, + language: 'pl', + image: 'https://ocdn.eu/wiadomosciucs/static/logo2017/onet2017big_dark.png', + }; +}; diff --git a/lib/v2/onet/radar.js b/lib/v2/onet/radar.js new file mode 100644 index 00000000000000..f29d2f6b096de9 --- /dev/null +++ b/lib/v2/onet/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'onet.pl': { + _name: 'Onet', + wiadomosci: [ + { + title: 'News', + docs: 'https://docs.rsshub.app/routes/new-media#onet', + source: '/', + target: '/onet/news', + }, + ], + }, +}; diff --git a/lib/v2/onet/router.js b/lib/v2/onet/router.js new file mode 100644 index 00000000000000..630036b8e4f282 --- /dev/null +++ b/lib/v2/onet/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/news', require('./news')); +}; diff --git a/lib/v2/onet/templates/article.art b/lib/v2/onet/templates/article.art new file mode 100644 index 00000000000000..36ed5db532ab1b --- /dev/null +++ b/lib/v2/onet/templates/article.art @@ -0,0 +1,5 @@ +{{if lead }} +

{{ lead }}

+{{/if}} +{{@ mainImage }} +{{@ content }} diff --git a/lib/v2/onet/templates/image.art b/lib/v2/onet/templates/image.art new file mode 100644 index 00000000000000..a4a8c87244e1cd --- /dev/null +++ b/lib/v2/onet/templates/image.art @@ -0,0 +1,9 @@ +
+ {{ alt }} + + {{if caption }} + {{ caption }} - + {{/if}} + {{ author }} + +
diff --git a/lib/v2/onet/utils.js b/lib/v2/onet/utils.js new file mode 100644 index 00000000000000..af8a9a814525ab --- /dev/null +++ b/lib/v2/onet/utils.js @@ -0,0 +1,51 @@ +const { art } = require('@/utils/render'); +const path = require('path'); + +const parseMainImage = ($) => { + const mainImage = $('figure.mainPhoto'); + const img = mainImage.find('img'); + const author = mainImage.find('span.copyright'); + const caption = mainImage.find('span.imageDescription'); + + return art(path.join(__dirname, 'templates/image.art'), { + url: img.attr('src'), + alt: img.attr('alt')?.trim(), + author: author.text()?.trim(), + caption: caption.text()?.trim(), + }); +}; + +const parseArticleContent = ($) => { + const content = $('[itemprop="articleBody"]'); + $('*') + .contents() + .filter(function () { + return this.nodeType === 8; + }) + .remove(); + content.find('aside').remove(); + content.find('.videoPlayerContainer').remove(); + content.find('.pulsevideo').remove(); + content.find('.adsContainer').remove(); + content.find('.placeholder').remove(); + content.find('.contentPremium').removeAttr('style'); + content.find('div.image').each((i, el) => { + const img = $(el).find('img'); + const author = $(el).find('span.author'); + const caption = $(el).find('span.caption'); + const html = art(path.join(__dirname, 'templates/image.art'), { + url: img.attr('src'), + alt: img.attr('alt')?.trim(), + caption: caption.text()?.trim(), + author: author.text()?.trim(), + }); + + $(el).replaceWith(html); + }); + + return content; +}; +module.exports = { + parseArticleContent, + parseMainImage, +}; diff --git a/website/docs/routes/new-media.mdx b/website/docs/routes/new-media.mdx index 02fd7947f2b0d9..e0c42d38c5059c 100644 --- a/website/docs/routes/new-media.mdx +++ b/website/docs/routes/new-media.mdx @@ -1107,6 +1107,14 @@ +## Onet {#onet} + +### News {#onet-news} + + + This route provides a better reading experience (full text articles) over the official one for `https://wiadomosci.onet.pl`. + + ## OpenAI {#openai} ### Blog {#openai-blog} From 5348812899c29eeced8306d43887c0d7bde5f242 Mon Sep 17 00:00:00 2001 From: CrackTC Date: Wed, 10 Jan 2024 00:06:14 +0800 Subject: [PATCH 11/15] fix(route): saraba1st digest image (#14206) * fix saraba1st digest image * add missing semicolon --- lib/v2/saraba1st/digest.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/v2/saraba1st/digest.js b/lib/v2/saraba1st/digest.js index 07e4f3ab581bfe..286549b0ee0af8 100644 --- a/lib/v2/saraba1st/digest.js +++ b/lib/v2/saraba1st/digest.js @@ -75,5 +75,17 @@ async function fetchContent(url) { } }); + stubS.find('img').each(function () { + const img = subind(this); + const file = img.attr('file'); + if (file) { + img.attr('src', file); + img.removeAttr('zoomfile'); + img.removeAttr('file'); + img.removeAttr('onmouseover'); + img.removeAttr('onclick'); + } + }); + return stubS.html(); } From 035fdca3b7b3d597c37ee609d31e07de933ff840 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 22:29:01 +0000 Subject: [PATCH 12/15] chore(deps-dev): bump @types/koa from 2.13.12 to 2.14.0 (#14215) * chore(deps-dev): bump @types/koa from 2.13.12 to 2.14.0 Bumps [@types/koa](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/koa) from 2.13.12 to 2.14.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/koa) --- updated-dependencies: - dependency-name: "@types/koa" dependency-type: direct:development 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 | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 1a4e368ba22be3..ce06022406c233 100644 --- a/package.json +++ b/package.json @@ -164,7 +164,7 @@ "@types/imapflow": "1.0.17", "@types/jsdom": "21.1.6", "@types/json-bigint": "1.0.4", - "@types/koa": "2.13.12", + "@types/koa": "2.14.0", "@types/koa-basic-auth": "2.0.6", "@types/koa-favicon": "2.1.3", "@types/koa-mount": "4.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1406e4f2475e77..4fb3d014a339f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -245,8 +245,8 @@ devDependencies: specifier: 1.0.4 version: 1.0.4 '@types/koa': - specifier: 2.13.12 - version: 2.13.12 + specifier: 2.14.0 + version: 2.14.0 '@types/koa-basic-auth': specifier: 2.0.6 version: 2.0.6 @@ -1619,42 +1619,42 @@ packages: /@types/koa-basic-auth@2.0.6: resolution: {integrity: sha512-1/FdT3KiHIkVf+TxYiPPey0wnPBzuts6lz/Obskgo9ZY485J02+uI6STnD114L2iG+Wi5MBqU7EYNphKdKwZWQ==} dependencies: - '@types/koa': 2.13.12 + '@types/koa': 2.14.0 dev: true /@types/koa-compose@3.2.5: resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==} dependencies: - '@types/koa': 2.13.12 + '@types/koa': 2.14.0 dev: true /@types/koa-favicon@2.1.3: resolution: {integrity: sha512-L1XAF8k1iOuh3hA/ZjEqWURm9/62a8A1x7BZR9ZCMw8nbnUBt6oZksz2rfKRCEwESqI2e6WVGlF03fs9DbQQXQ==} dependencies: - '@types/koa': 2.13.12 + '@types/koa': 2.14.0 dev: true /@types/koa-mount@4.0.5: resolution: {integrity: sha512-pV1njJ7r94iqAFzT9D5sGSYKUHFGudCLAnmr4WFli7V5tJf5MAgRQK9leTPJ4gjvgr+hnTf86fZsKoFN358c7w==} dependencies: - '@types/koa': 2.13.12 + '@types/koa': 2.14.0 dev: true /@types/koa-send@4.1.3: resolution: {integrity: sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==} dependencies: - '@types/koa': 2.13.12 + '@types/koa': 2.14.0 dev: true /@types/koa-static@4.0.4: resolution: {integrity: sha512-j1AUzzl7eJYEk9g01hNTlhmipFh8RFbOQmaMNLvLcNNAkPw0bdTs3XTa3V045XFlrWN0QYnblbDJv2RzawTn6A==} dependencies: - '@types/koa': 2.13.12 + '@types/koa': 2.14.0 '@types/koa-send': 4.1.3 dev: true - /@types/koa@2.13.12: - resolution: {integrity: sha512-vAo1KuDSYWFDB4Cs80CHvfmzSQWeUb909aQib0C0aFx4sw0K9UZFz2m5jaEP+b3X1+yr904iQiruS0hXi31jbw==} + /@types/koa@2.14.0: + resolution: {integrity: sha512-DTDUyznHGNHAl+wd1n0z1jxNajduyTh8R53xoewuerdBzGo6Ogj6F2299BFtrexJw4NtgjsI5SMPCmV9gZwGXA==} dependencies: '@types/accepts': 1.3.5 '@types/content-disposition': 0.5.5 @@ -1669,7 +1669,7 @@ packages: /@types/koa__router@12.0.4: resolution: {integrity: sha512-Y7YBbSmfXZpa/m5UGGzb7XadJIRBRnwNY9cdAojZGp65Cpe5MAP3mOZE7e3bImt8dfKS4UFcR16SLH8L/z7PBw==} dependencies: - '@types/koa': 2.13.12 + '@types/koa': 2.14.0 dev: true /@types/linkify-it@3.0.3: From 12b409fa620724a3dd614defa7378575cb6f2167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=8E=E4=B8=BD?= Date: Wed, 10 Jan 2024 10:38:26 +0800 Subject: [PATCH 13/15] feat(route): add huggingface zh blog (#14211) * feat(route): add huggingface zh blog * refactor: update --- lib/v2/huggingface/blog-zh.js | 34 +++++++++++++++++++++++++++++ lib/v2/huggingface/maintainer.js | 1 + lib/v2/huggingface/radar.js | 6 +++++ lib/v2/huggingface/router.js | 1 + website/docs/routes/programming.mdx | 4 ++++ 5 files changed, 46 insertions(+) create mode 100644 lib/v2/huggingface/blog-zh.js diff --git a/lib/v2/huggingface/blog-zh.js b/lib/v2/huggingface/blog-zh.js new file mode 100644 index 00000000000000..0682fc1c9042f7 --- /dev/null +++ b/lib/v2/huggingface/blog-zh.js @@ -0,0 +1,34 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const { body: response } = await got('https://huggingface.co/blog/zh'); + const $ = cheerio.load(response); + + /** @type {Array<{blog: {local: string, title: string, author: string, thumbnail: string, date: string, tags: Array}, blogUrl: string, lang: 'zh', link: string}>} */ + const papers = $('div[data-target="BlogThumbnail"]') + .toArray() + .map((item) => { + const props = $(item).data('props'); + const link = $(item).find('a').attr('href'); + return { + ...props, + link, + }; + }); + + const items = papers.map((item) => ({ + title: item.blog.title, + link: `https://huggingface.co${item.link}`, + category: item.blog.tags, + pubDate: parseDate(item.blog.date), + author: item.blog.author, + })); + + ctx.state.data = { + title: 'Huggingface 中文博客', + link: 'https://huggingface.co/blog/zh', + item: items, + }; +}; diff --git a/lib/v2/huggingface/maintainer.js b/lib/v2/huggingface/maintainer.js index 1abfb61057ccef..ffc93bc13ed9e7 100644 --- a/lib/v2/huggingface/maintainer.js +++ b/lib/v2/huggingface/maintainer.js @@ -1,3 +1,4 @@ module.exports = { + '/blog-zh': ['zcf0508'], '/daily-papers': ['zeyugao'], }; diff --git a/lib/v2/huggingface/radar.js b/lib/v2/huggingface/radar.js index 24bf34063faf59..7198e5238c9ff3 100644 --- a/lib/v2/huggingface/radar.js +++ b/lib/v2/huggingface/radar.js @@ -8,6 +8,12 @@ module.exports = { source: ['/papers', '/'], target: '/huggingface/daily-papers', }, + { + title: '中文博客', + docs: 'https://docs.rsshub.app/routes/programming#huggingface', + source: ['/blog/zh', '/'], + target: '/huggingface/blog-zh', + }, ], }, }; diff --git a/lib/v2/huggingface/router.js b/lib/v2/huggingface/router.js index ca991e4ddc895d..5c62ff5f133561 100644 --- a/lib/v2/huggingface/router.js +++ b/lib/v2/huggingface/router.js @@ -1,3 +1,4 @@ module.exports = (router) => { + router.get('/blog-zh', require('./blog-zh')); router.get('/daily-papers', require('./daily-papers')); }; diff --git a/website/docs/routes/programming.mdx b/website/docs/routes/programming.mdx index e264355ef04015..c4d14219b0afdc 100644 --- a/website/docs/routes/programming.mdx +++ b/website/docs/routes/programming.mdx @@ -492,6 +492,10 @@ Subscribe to the updates (threads and submission) from a paritcular Hacker News +### 中文博客 {#huggingface-zhong-wen-bo-ke} + + + ## Issue Hunt {#issue-hunt} ### Project Funded {#issue-hunt-project-funded} From 327d0d0c77669b6e370ed3e6d378de8e894ce8d9 Mon Sep 17 00:00:00 2001 From: Manish Bhattarai Date: Tue, 9 Jan 2024 22:05:23 -0500 Subject: [PATCH 14/15] feat(route): Add ekantipur.com (Nepal) (#14207) * feat(route): Add ekantipur remove unused deps * feat(route): Add ekantipur radar * removed undefined field * updated maintainer.js to use optional field character - ? * updated radar.js with full name --------- --- lib/v2/ekantipur/issue.js | 64 +++++++++++++++++++++++ lib/v2/ekantipur/maintainer.js | 3 ++ lib/v2/ekantipur/radar.js | 13 +++++ lib/v2/ekantipur/router.js | 3 ++ website/docs/routes/traditional-media.mdx | 12 +++++ 5 files changed, 95 insertions(+) create mode 100644 lib/v2/ekantipur/issue.js create mode 100644 lib/v2/ekantipur/maintainer.js create mode 100644 lib/v2/ekantipur/radar.js create mode 100644 lib/v2/ekantipur/router.js diff --git a/lib/v2/ekantipur/issue.js b/lib/v2/ekantipur/issue.js new file mode 100644 index 00000000000000..2028b9b03537bd --- /dev/null +++ b/lib/v2/ekantipur/issue.js @@ -0,0 +1,64 @@ +// Require necessary modules +const got = require('@/utils/got'); // a customised got +const cheerio = require('cheerio'); // an HTML parser with a jQuery-like API + +module.exports = async (ctx) => { + // Your logic here + // Defining base URL + const baseUrl = 'https://ekantipur.com'; + + // Retrive the channel parameter + const { channel = 'news' } = ctx.params; + + // Fetches content of the requested channel + const { data: response } = await got(`${baseUrl}/${channel}`); + const $ = cheerio.load(response); + + // Retrive articles + const list = $('article.normal') + // We use the `toArray()` method to retrieve all the DOM elements selected as an array. + .toArray() + // We use the `map()` method to traverse the array and parse the data we need from each element. + .map((item) => { + item = $(item); + const a = item.find('a').first(); + return { + title: a.text(), + // We need an absolute URL for `link`, but `a.attr('href')` returns a relative URL. + link: `${baseUrl}${a.attr('href')}`, + author: item.find('div.author').text(), + category: channel, + }; + }); + + const items = await Promise.all( + list.map((item) => + ctx.cache.tryGet(item.link, async () => { + const { data: response } = await got(item.link); + const $ = cheerio.load(response); + + // Remove sponsor elements + $('a.static-sponsor').remove(); + $('div.ekans-wrapper').remove(); + + // Fetch title from the article page + item.title = $('h1.eng-text-heading').text(); + // Fetch article content from the article page + item.description = $('div.current-news-block').first().html(); + + // Every property of a list item defined above is reused here + // and we add a new property 'description' + return item; + }) + ) + ); + + ctx.state.data = { + // channel title + title: `Ekantipur - ${channel}`, + // channel link + link: `${baseUrl}/${channel}`, + // each feed item + item: items, + }; +}; \ No newline at end of file diff --git a/lib/v2/ekantipur/maintainer.js b/lib/v2/ekantipur/maintainer.js new file mode 100644 index 00000000000000..e96a3817c2d451 --- /dev/null +++ b/lib/v2/ekantipur/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:channel?': ['maniche04'], +}; \ No newline at end of file diff --git a/lib/v2/ekantipur/radar.js b/lib/v2/ekantipur/radar.js new file mode 100644 index 00000000000000..756d7e967d815f --- /dev/null +++ b/lib/v2/ekantipur/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'ekantipur.com': { + _name: 'Ekantipur', + '.': [ + { + title: 'Full Article RSS', + docs: 'https://docs.rsshub.app/routes/traditional-media#ekantipur-%E0%A4%95%E0%A4%BE%E0%A4%A8%E0%A5%8D%E0%A4%A4%E0%A4%BF%E0%A4%AA%E0%A5%81%E0%A4%B0-nepal', + source: ['/:channel'], + target: '/ekantipur/:channel', + }, + ], + }, +}; \ No newline at end of file diff --git a/lib/v2/ekantipur/router.js b/lib/v2/ekantipur/router.js new file mode 100644 index 00000000000000..77f4234df1d756 --- /dev/null +++ b/lib/v2/ekantipur/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:channel?', require('./issue')); +}; \ No newline at end of file diff --git a/website/docs/routes/traditional-media.mdx b/website/docs/routes/traditional-media.mdx index 28cb8c45c11aaf..f76ce0aa663423 100644 --- a/website/docs/routes/traditional-media.mdx +++ b/website/docs/routes/traditional-media.mdx @@ -177,6 +177,18 @@ ::: +## Ekantipur / कान्तिपुर (Nepal) + +### Full Article RSS {#ekantipur-rss} + + + Channels: + + | समाचार | अर्थ / वाणिज्य | विचार | खेलकुद | उपत्यका | मनोरञ्जन | फोटोफिचर | फिचर | विश्व | ब्लग | + | --------- | --------- | ----- | ------------- | ------ | ----- | --------- | --------- | -------- | ----- | + | news | business | opinion | sports | national | entertainment | photo_feature | feature | world | blog | + + ## Financial Times {#financial-times} ### FT 中文网 {#financial-times-ft-zhong-wen-wang} From f8a432e830de4719a984bc58da804a722d02da54 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 03:07:01 +0000 Subject: [PATCH 15/15] style: auto format --- lib/v2/ekantipur/issue.js | 2 +- lib/v2/ekantipur/maintainer.js | 2 +- lib/v2/ekantipur/radar.js | 2 +- lib/v2/ekantipur/router.js | 2 +- website/docs/routes/traditional-media.mdx | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/v2/ekantipur/issue.js b/lib/v2/ekantipur/issue.js index 2028b9b03537bd..0df7b094edd73d 100644 --- a/lib/v2/ekantipur/issue.js +++ b/lib/v2/ekantipur/issue.js @@ -61,4 +61,4 @@ module.exports = async (ctx) => { // each feed item item: items, }; -}; \ No newline at end of file +}; diff --git a/lib/v2/ekantipur/maintainer.js b/lib/v2/ekantipur/maintainer.js index e96a3817c2d451..a8d2de20dc92eb 100644 --- a/lib/v2/ekantipur/maintainer.js +++ b/lib/v2/ekantipur/maintainer.js @@ -1,3 +1,3 @@ module.exports = { '/:channel?': ['maniche04'], -}; \ No newline at end of file +}; diff --git a/lib/v2/ekantipur/radar.js b/lib/v2/ekantipur/radar.js index 756d7e967d815f..b0ecd84e3d1809 100644 --- a/lib/v2/ekantipur/radar.js +++ b/lib/v2/ekantipur/radar.js @@ -10,4 +10,4 @@ module.exports = { }, ], }, -}; \ No newline at end of file +}; diff --git a/lib/v2/ekantipur/router.js b/lib/v2/ekantipur/router.js index 77f4234df1d756..b472b8643ddc54 100644 --- a/lib/v2/ekantipur/router.js +++ b/lib/v2/ekantipur/router.js @@ -1,3 +1,3 @@ module.exports = (router) => { router.get('/:channel?', require('./issue')); -}; \ No newline at end of file +}; diff --git a/website/docs/routes/traditional-media.mdx b/website/docs/routes/traditional-media.mdx index f76ce0aa663423..b09385418a0ecb 100644 --- a/website/docs/routes/traditional-media.mdx +++ b/website/docs/routes/traditional-media.mdx @@ -177,16 +177,16 @@ ::: -## Ekantipur / कान्तिपुर (Nepal) +## Ekantipur / कान्तिपुर (Nepal) {#ekantipur-%E0%A4%95%E0%A4%BE%E0%A4%A8%E0%A5%8D%E0%A4%A4%E0%A4%BF%E0%A4%AA%E0%A5%81%E0%A4%B0-nepal} -### Full Article RSS {#ekantipur-rss} +### Full Article RSS {#ekantipur-%E0%A4%95%E0%A4%BE%E0%A4%A8%E0%A5%8D%E0%A4%A4%E0%A4%BF%E0%A4%AA%E0%A5%81%E0%A4%B0-nepal-full-article-rss} Channels: - | समाचार | अर्थ / वाणिज्य | विचार | खेलकुद | उपत्यका | मनोरञ्जन | फोटोफिचर | फिचर | विश्व | ब्लग | - | --------- | --------- | ----- | ------------- | ------ | ----- | --------- | --------- | -------- | ----- | - | news | business | opinion | sports | national | entertainment | photo_feature | feature | world | blog | + | समाचार | अर्थ / वाणिज्य | विचार | खेलकुद | उपत्यका | मनोरञ्जन | फोटोफिचर | फिचर | विश्व | ब्लग | + | ---- | -------- | ------- | ------ | -------- | ------------- | -------------- | ------- | ----- | ---- | + | news | business | opinion | sports | national | entertainment | photo\_feature | feature | world | blog | ## Financial Times {#financial-times}