diff --git a/docs/new-media.md b/docs/new-media.md index c47bda35e..ec9681ec4 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -2752,6 +2752,10 @@ others = 热点新闻 + 滚动新闻 +### 专题文章 + + + ### 播客 diff --git a/lib/v2/gcores/collection.js b/lib/v2/gcores/collection.js new file mode 100644 index 000000000..0714a6eed --- /dev/null +++ b/lib/v2/gcores/collection.js @@ -0,0 +1,136 @@ +/* refer to: ./tag.js (author: @StevenREC0) */ +const got = require('@/utils/got'); + +module.exports = async (ctx) => { + // get params + const { collection } = ctx.params; + + // feed info + const baseUrl = `https://www.gcores.com/gapi/v1/collections/${collection}`; + const baseRes = await got(baseUrl); + const feedTitle = baseRes.data.data.attributes.title; + const feedUrl = `https://www.gcores.com/collections/${collection}`; + + // resolve articles + const dataUrl = `${baseUrl}/articles?sort=-published-at`; + const res = await got(dataUrl); + const list = res.data.data; + + const items = list.map((item) => { + const articleUrl = `https://www.gcores.com/${item.type}/${item.id}`; + return ctx.cache.tryGet(articleUrl, () => { + let cover = ''; + if (item.attributes.cover) { + cover = ``; + } else if (item.attributes.thumb) { + cover = ``; + } + + const contentBlocks = JSON.parse(item.attributes.content); + const { blocks, entityMap } = contentBlocks; + + function wrapInlineTag(strArr, startIdx, endIdx, preString, sufString) { + if (startIdx === endIdx - 1) { + strArr[startIdx] = `${preString}${strArr[startIdx]}${sufString}`; + } else { + strArr[startIdx] = `${preString}${strArr[startIdx]}`; + strArr[endIdx - 1] = `${strArr[endIdx - 1]}${sufString}`; + } + } + + function convertBlockToContent(block) { + const { type, text, entityRanges, inlineStyleRanges } = block; + let formattedText = text; + if (entityRanges.length || inlineStyleRanges.length) { + // split string and insert HTML tag + const strArr = text.split(''); + let isMedia = false; + if (entityRanges.length) { + entityRanges.forEach((entityRange) => { + const { key, offset, length } = entityRange; + const startIdx = offset, + endIdx = offset + length; + const { data, type } = entityMap[key]; + switch (type) { + case 'LINK': + wrapInlineTag(strArr, startIdx, endIdx, ``, ``); + break; + case 'IMAGE': + formattedText = `
${data.caption ? `
${data.caption}
` : ''}
`; + isMedia = true; + break; + case 'EMBED': + formattedText = `
${data.content}${data.caption ? `
${data.caption}
` : ''}
`; + isMedia = true; + break; + case 'GALLERY': + formattedText = `
${data.images.map((image) => `
`).join('')}
`; + isMedia = true; + break; + default: + break; + } + }); + } + if (inlineStyleRanges.length) { + inlineStyleRanges.forEach((inlineStyleRange) => { + const { style, offset, length } = inlineStyleRange; + const startIdx = offset, + endIdx = offset + length; + switch (style) { + case 'BOLD': + wrapInlineTag(strArr, startIdx, endIdx, ``, ``); + break; + case 'UNDERLINE': + wrapInlineTag(strArr, startIdx, endIdx, ``, ``); + break; + case 'ITALIC': + wrapInlineTag(strArr, startIdx, endIdx, ``, ``); + break; + default: + break; + } + }); + } + formattedText = isMedia ? formattedText : strArr.join(''); + } + + /* 未兼容列表,仅展示为段落,有兴趣可以补全:unordered-list-item、ordered-list-item */ + switch (type) { + case 'unstyled': + return `

${formattedText}

`; + case 'header-one': + return `

${formattedText}

`; + case 'header-two': + return `

${formattedText}

`; + case 'header-three': + return `

${formattedText}

`; + case 'header-four': + return `

${formattedText}

`; + case 'header-five': + return `
${formattedText}
`; + case 'header-six': + return `
${formattedText}
`; + case 'atomic': + return formattedText; + default: + return `

${formattedText}

`; + } + } + const content = blocks.map((block) => convertBlockToContent(block)); + + return { + title: item.attributes.title, + description: cover + content.join(''), + link: articleUrl, + }; + }); + }); + + // return data + ctx.state.data = { + title: feedTitle, + link: feedUrl, + item: items, + }; +}; diff --git a/lib/v2/gcores/maintainer.js b/lib/v2/gcores/maintainer.js index 59e6ee703..6efd60dae 100644 --- a/lib/v2/gcores/maintainer.js +++ b/lib/v2/gcores/maintainer.js @@ -1,5 +1,6 @@ module.exports = { '/category/:category': ['MoguCloud', 'StevenRCE0'], + '/collections/:collection': ['kudryavka1013'], '/radios/:category?': ['eternasuno'], '/tag/:tag/:category?': ['StevenRCE0'], }; diff --git a/lib/v2/gcores/radar.js b/lib/v2/gcores/radar.js index b05708148..c04c2644f 100644 --- a/lib/v2/gcores/radar.js +++ b/lib/v2/gcores/radar.js @@ -26,6 +26,12 @@ module.exports = { source: ['/categories/:category'], target: '/gcores/radios/:category', }, + { + title: '专题', + docs: 'https://docs.rsshub.app/new-media.html#ji-he-wang-zhuan-ti', + source: ['/collections/:collection'], + target: '/gcores/collections/:collection', + }, ], }, }; diff --git a/lib/v2/gcores/router.js b/lib/v2/gcores/router.js index cf555d2e5..1f24d4dcf 100644 --- a/lib/v2/gcores/router.js +++ b/lib/v2/gcores/router.js @@ -1,5 +1,6 @@ module.exports = function (router) { router.get('/category/:category', require('./category')); + router.get('/collections/:collection', require('./collection')); router.get('/radios/:category?', require('./radio')); router.get('/tag/:tag/:category?', require('./tag')); };