diff --git a/lib/v2/chuanliu/maintainer.js b/lib/v2/chuanliu/maintainer.js new file mode 100644 index 00000000000000..0abf523583e0a6 --- /dev/null +++ b/lib/v2/chuanliu/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/nice': ['nczitzk'], +}; diff --git a/lib/v2/chuanliu/nice.js b/lib/v2/chuanliu/nice.js new file mode 100644 index 00000000000000..7d08ed3a071773 --- /dev/null +++ b/lib/v2/chuanliu/nice.js @@ -0,0 +1,76 @@ +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 md = require('markdown-it')({ + html: true, +}); + +module.exports = async (ctx) => { + const limit = ctx.query.limit ? Number.parseInt(ctx.query.limit, 10) : 100; + + const rootUrl = 'https://chuanliu.org'; + const apiRootUrl = 'https://s.chuanliu.org'; + const currentUrl = new URL('nice/', rootUrl).href; + const apiUrl = new URL('api/dis/api/v1/memo', apiRootUrl).href; + + const { data: response } = await got(apiUrl, { + searchParams: { + creatorId: 1, + offset: 0, + limit, + }, + }); + + const items = response.slice(0, limit).map((item) => { + const contents = item.content.split(/\n/); + + const category = contents?.[0].replace(/^#/, '') ?? undefined; + const title = contents?.[1] ?? undefined; + const link = contents?.[2] ?? undefined; + const author = contents?.[3] ?? undefined; + const isStar = (contents?.[5] && contents[5] === 'star') ?? false; + + if (isStar) { + contents.splice(5, 1); + } + + return { + title: `${isStar ? '[STAR] ' : ''}${title}`, + link, + description: art(path.join(__dirname, 'templates/description.art'), { + description: md.render(contents?.join('\n\n') ?? ''), + images: item.resourceList.map((i) => ({ + src: i.externalLink, + alt: i.filename, + type: i.type, + })), + }), + author, + category: [category, isStar ? 'STAR' : undefined].filter(Boolean), + guid: `chuanliu-nice#${item.id}`, + pubDate: parseDate(item.createdTs, 'X'), + updated: parseDate(item.updatedTs, 'X'), + }; + }); + + const { data: currentResponse } = await got(currentUrl); + + const $ = cheerio.load(currentResponse); + + const icon = new URL($('link[rel="shortcut icon"]').prop('href'), currentUrl).href; + + ctx.state.data = { + item: items, + title: $('title').text(), + link: currentUrl, + description: $('span.rainbow-text').first().text(), + language: $('html').prop('lang'), + icon, + logo: icon, + subtitle: $('title').text(), + author: $('meta[name="author"]').prop('content'), + allowEmpty: true, + }; +}; diff --git a/lib/v2/chuanliu/radar.js b/lib/v2/chuanliu/radar.js new file mode 100644 index 00000000000000..b8072da6d07496 --- /dev/null +++ b/lib/v2/chuanliu/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'chuanliu.org': { + _name: '川流', + '.': [ + { + title: '严选', + docs: 'https://docs.rsshub.app/routes/blog#chuan-liu-yan-xuan', + source: ['/nice'], + target: '/chuanliu/nice', + }, + ], + }, +}; diff --git a/lib/v2/chuanliu/router.js b/lib/v2/chuanliu/router.js new file mode 100644 index 00000000000000..d082d9a1c37c9f --- /dev/null +++ b/lib/v2/chuanliu/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/nice', require('./nice')); +}; diff --git a/lib/v2/chuanliu/templates/description.art b/lib/v2/chuanliu/templates/description.art new file mode 100644 index 00000000000000..dfd22a693d90ce --- /dev/null +++ b/lib/v2/chuanliu/templates/description.art @@ -0,0 +1,23 @@ +{{ if images }} + {{ each images image }} + {{ if image?.src }} +
+ {{ image.alt }} +
+ {{ /if }} + {{ /each }} +{{ /if }} + +{{ if description }} + {{@ description }} +{{ /if }} \ No newline at end of file diff --git a/website/docs/routes/blog.mdx b/website/docs/routes/blog.mdx index 04ef21213bdf59..b1ee3e6e55a4b7 100644 --- a/website/docs/routes/blog.mdx +++ b/website/docs/routes/blog.mdx @@ -284,6 +284,12 @@ 通过提取文章全文,以提供比官方源更佳的阅读体验. +## 川流 {#chuan-liu} + +### 严选 {#chuan-liu-yan-xuan} + + + ## 大侠阿木 {#da-xia-a-mu} ### 首页 {#da-xia-a-mu-shou-ye}