From e17a1ae3162625e3674a5cc04d1973f2eabb2cdd Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 30 Mar 2023 17:34:51 +0000 Subject: [PATCH] feat(route): line today publisher (#12208) * feat(route): line today publisher * fix: th parsing --- docs/en/new-media.md | 10 +++++--- docs/new-media.md | 10 +++++--- lib/v2/line/maintainer.js | 1 + lib/v2/line/publisher.js | 53 +++++++++++++++++++++++++++++++++++++++ lib/v2/line/radar.js | 10 ++++++-- lib/v2/line/router.js | 1 + lib/v2/line/today.js | 36 +++----------------------- lib/v2/line/utils.js | 43 +++++++++++++++++++++++++++++++ 8 files changed, 123 insertions(+), 41 deletions(-) create mode 100644 lib/v2/line/publisher.js create mode 100644 lib/v2/line/utils.js diff --git a/docs/en/new-media.md b/docs/en/new-media.md index b168c45cc7..7736e9a201 100644 --- a/docs/en/new-media.md +++ b/docs/en/new-media.md @@ -454,11 +454,11 @@ Provides a better reading experience (full text articles) over the official one. -## Line +## LINE -### Today +### TODAY - + Edition @@ -468,6 +468,10 @@ Edition +### TODAY - Channel + + + ## Macfilos ### Blog diff --git a/docs/new-media.md b/docs/new-media.md index 428754a12b..2984a616ee 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -816,11 +816,11 @@ Tag -## Line +## LINE -### Today +### TODAY - + Edition @@ -830,6 +830,10 @@ Edition +### TODAY - 频道 + + + ## LVV2 ### 频道 diff --git a/lib/v2/line/maintainer.js b/lib/v2/line/maintainer.js index ed80783719..2a8ca077d5 100644 --- a/lib/v2/line/maintainer.js +++ b/lib/v2/line/maintainer.js @@ -1,3 +1,4 @@ module.exports = { '/today/:edition?/:tab?': ['nczitzk'], + '/today/:edition/publisher/:id': ['TonyRL'], }; diff --git a/lib/v2/line/publisher.js b/lib/v2/line/publisher.js new file mode 100644 index 0000000000..15e4154042 --- /dev/null +++ b/lib/v2/line/publisher.js @@ -0,0 +1,53 @@ +const got = require('@/utils/got'); +const { baseUrl, parseList, parseItems } = require('./utils'); + +module.exports = async (ctx) => { + const { edition, id } = ctx.params; + + const { data: publisherInfo } = await got(`${baseUrl}/webapi/portal/page/setting`, { + searchParams: { + entityId: id, + country: edition, + pageType: 'CP', + }, + }); + + let cpLatest; + if (edition === 'th') { + const { data } = await got(`${baseUrl}/webapi/portal/embedded/page/cplatest`, { + searchParams: { + entityId: id, + pageType: 'CP', + country: edition, + }, + }); + cpLatest = data; + } + + const modules = edition !== 'th' ? publisherInfo.modules : cpLatest.modules; + const mod = modules.find((item) => item.source === 'CP_LATEST'); + const listing = mod.listings[0]; + + const { data: listResponse } = await got(`${baseUrl}/webapi/trending/cp/latest/listings/${mod.id}`, { + searchParams: { + offset: listing.offset, + length: listing.length, + country: edition, + targetContent: listing.params.targetContent, + cps: listing.params.cps, + publishedWithin: listing.params.publishedWithin, + }, + }); + + const list = parseList(listResponse.items); + + const items = await parseItems(list, ctx.cache.tryGet); + + ctx.state.data = { + title: `${publisherInfo.data.name} - Line Today`, + description: publisherInfo.data.introduction, + image: `https://obs.line-scdn.net/${publisherInfo.data.icon.hash}`, + link: `${baseUrl}/${edition}/v2/publisher/${id}`, + item: items, + }; +}; diff --git a/lib/v2/line/radar.js b/lib/v2/line/radar.js index cbd04d1eb2..5ffb4f77a7 100644 --- a/lib/v2/line/radar.js +++ b/lib/v2/line/radar.js @@ -1,13 +1,19 @@ module.exports = { 'line.me': { - _name: 'LINE Today', + _name: 'LINE', '.': [ { - title: 'LINE Today', + title: 'Today', docs: 'https://docs.rsshub.app/new-media.html#line-today', source: ['/'], target: '/line/today/:edition?/:tab?', }, + { + title: 'Today - 频道', + docs: 'https://docs.rsshub.app/new-media.html#line-today', + source: ['/:edition/v2/publisher/:id'], + target: '/line/today/:edition/publisher/:id', + }, ], }, }; diff --git a/lib/v2/line/router.js b/lib/v2/line/router.js index 5ea3e1edc9..fbe5ea3887 100644 --- a/lib/v2/line/router.js +++ b/lib/v2/line/router.js @@ -1,3 +1,4 @@ module.exports = function (router) { router.get('/today/:edition?/:tab?', require('./today')); + router.get('/today/:edition/publisher/:id', require('./publisher')); }; diff --git a/lib/v2/line/today.js b/lib/v2/line/today.js index a44a87c600..92ac773e8d 100644 --- a/lib/v2/line/today.js +++ b/lib/v2/line/today.js @@ -1,12 +1,10 @@ const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); +const { baseUrl: rootUrl, parseList, parseItems } = require('./utils'); module.exports = async (ctx) => { const edition = ctx.params.edition || 'tw'; const tab = ctx.params.tab || 'top'; - const rootUrl = 'https://today.line.me'; const tabUrl = `${rootUrl}/webapi/portal/page/${tab}?country=${edition}`; const recommendationUrl = `${rootUrl}/webapi/api/v6/recommendation/articles/listings/mytoday_rec:id?offset=0&length=50&country=${edition}&gender=&age=&excludeNoThumbnail=0&containMainSnapshot=0`; const currentUrl = `${rootUrl}/${edition}/v2/tab/${tab}`; @@ -34,37 +32,9 @@ module.exports = async (ctx) => { url: tab === 'recommendation' ? recommendationUrl : moduleUrl, }); - const list = response.data.items.map((item) => ({ - title: item.title, - link: `${rootUrl}/${edition}/v2/article/${item.url.hash}`, - pubDate: parseDate(item.publishTimeUnix), - hash: item.url.hash, - category: item.categoryName, - })); + const list = parseList(response.data.items); - const items = await Promise.all( - list.map((item) => - ctx.cache.tryGet(item.link, async () => { - const { data } = await got({ - method: 'get', - url: `${rootUrl}/webapi/portal/page/setting/article?country=${edition}&hash=${item.hash}&group=NA`, - }); - - const $ = cheerio.load(data.data.content, null, false); - - $('img').each((_, img) => { - delete img.attribs['data-hashid']; - img.attribs.src = img.attribs.src.replace(/\/w\d+$/, ''); - }); - - item.description = $.html(); - item.author = data.data.author; - item.category = [...new Set([item.category, ...data.data.exploreLinks.map((link) => link.name)])]; - - return item; - }) - ) - ); + const items = await parseItems(list, ctx.cache.tryGet); ctx.state.data = { title: `${title} - Line Today`, diff --git a/lib/v2/line/utils.js b/lib/v2/line/utils.js new file mode 100644 index 0000000000..90f925b945 --- /dev/null +++ b/lib/v2/line/utils.js @@ -0,0 +1,43 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +const baseUrl = 'https://today.line.me'; + +const parseList = (items) => + items.map((item) => ({ + title: item.title, + link: item.url.url, + pubDate: parseDate(item.publishTimeUnix), + hash: item.url.hash, + category: item.categoryName, + })); + +const parseItems = (list, tryGet) => + Promise.all( + list.map((item) => + tryGet(item.link, async () => { + const edition = item.link.match(/today\.line\.me\/(\w+?)\/v2\/.*$/)[1]; + const { data } = await got(`${baseUrl}/webapi/portal/page/setting/article?country=${edition}&hash=${item.hash}&group=NA`); + + const $ = cheerio.load(data.data.content, null, false); + + $('img').each((_, img) => { + delete img.attribs['data-hashid']; + img.attribs.src = img.attribs.src.replace(/\/w\d+$/, ''); + }); + + item.description = $.html(); + item.author = data.data.author; + item.category = [...new Set([item.category, ...data.data.exploreLinks.map((link) => link.name)])]; + + return item; + }) + ) + ); + +module.exports = { + baseUrl, + parseList, + parseItems, +};