diff --git a/lib/router.js b/lib/router.js index 25b935f614..9d7cff3553 100644 --- a/lib/router.js +++ b/lib/router.js @@ -4103,8 +4103,8 @@ router.get('/ehentai/tag/:tag/:page?/:bittorrent?', lazyloadRouteHandler('./rout // 字型故事 router.get('/fontstory', lazyloadRouteHandler('./routes/fontstory/tw')); -// HKEPC -router.get('/hkepc/:category?', lazyloadRouteHandler('./routes/hkepc/index')); +// HKEPC migrated to v2 +// router.get('/hkepc/:category?', lazyloadRouteHandler('./routes/hkepc/index')); // 海南大学 router.get('/hainanu/ssszs', lazyloadRouteHandler('./routes/hainanu/ssszs')); diff --git a/lib/routes/hkepc/index.js b/lib/routes/hkepc/index.js deleted file mode 100644 index 4b0e088072..0000000000 --- a/lib/routes/hkepc/index.js +++ /dev/null @@ -1,164 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const { parseDate } = require('@/utils/parse-date'); -const timezone = require('@/utils/timezone'); - -module.exports = async (ctx) => { - const category = ctx.params.category || ''; - const baseUrl = `https://www.hkepc.com`; - - let itemResponse; - if (category === 'price' || category === 'review' || category === 'coverStory' || category === 'news' || category === 'press' || category === 'member') { - itemResponse = await ctx.cache.tryGet(`${baseUrl}/news`, async () => { - const resp = await got({ - method: 'get', - url: `${baseUrl}/news`, - headers: { - Referer: baseUrl, - }, - }); - return resp.data; - }); - } else if (category === 'digital' || category === 'entertainment' || category === 'latest' || category === '') { - itemResponse = await ctx.cache.tryGet(baseUrl, async () => { - const resp = await got(baseUrl); - return resp.data; - }); - } else { - itemResponse = await ctx.cache.tryGet(`${baseUrl}/${category}`, async () => { - const resp = await got({ - method: 'get', - url: `${baseUrl}/${category}`, - headers: { - Referer: baseUrl, - }, - }); - return resp.data; - }); - } - - const $ = cheerio.load(itemResponse); - - let title = '電腦領域 HKEPC'; - let articleList; - switch (category) { - case 'price': - title += ' - 腦場新聞'; - articleList = $('#sidebar > div:nth-child(1) > div.content > ul > li'); - break; - case 'review': - title += ' - 新品快遞'; - articleList = $('#sidebar > div:nth-child(2) > div.content > ul > li'); - break; - case 'coverStory': - title += ' - 專題報導'; - articleList = $('#sidebar > div:nth-child(3) > div.content > ul > li'); - break; - case 'news': - title += ' - 新聞中心'; - articleList = $('#sidebar > div:nth-child(4) > div.content > ul > li'); - break; - case 'press': - title += ' - 專題報導'; - articleList = $('#sidebar > div:nth-child(5) > div.content > ul > li'); - break; - case 'member': - title += ' - 會員消息'; - articleList = $('#sidebar > div:nth-child(6) > div.content > ul > li'); - break; - case 'digital': - title += ' - 流動數碼'; - articleList = $('#contentR5 > div.left > div.article > div.heading'); - break; - case 'entertainment': - title += ' - 生活娛樂'; - articleList = $('#contentR5 > div.right > div.article > div.heading'); - break; - case 'latest': - case '': - title += ' - 最新消息'; - articleList = $('div .item'); - break; - case 'ocLab': - title += ' - 超頻領域'; - articleList = $('.heading'); - break; - default: - break; - } - - const ProcessFeed = async (link) => { - const resp = await got({ - method: 'get', - url: link, - headers: { - Referer: baseUrl, - }, - }); - return cheerio.load(resp.data)('#article').html(); - }; - - const items = await Promise.all( - articleList.get().map(async (item) => { - const $ = cheerio.load(item); - const $a = $('a').html($('a').html().replace(/
/g, ' ')); - const title = $a.text().trim(); - const link = baseUrl + $a.attr('href'); - - const cache = await ctx.cache.get(link); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - - const categories = []; - const $article = cheerio.load(await ProcessFeed(link)); - - // remove unwanted elements - $article('#view > div.advertisement').remove(); - $article('#view > p').each((i, e) => { - if ( - //   =   - $(e) - .html() - .replace(/ /g, '').length === 0 - ) { - $(e).remove(); - } - }); - - // extract categories - $article('#articleHead > div.tags > a').each((i, e) => { - categories.push($article(e).text().trim()); - }); - - // fix lazyload image - $article('#view > p > img').each((i, e) => { - $(e).after(`${$(e).attr('alt')}`); - $(e).remove(); - }); - - const description = $article('#view').html(); - - const single = { - title, - author: $article('.newsAuthor').text().trim() || $article('#articleHead div.author').text().trim(), - category: categories, - description, - pubDate: timezone(parseDate($article('.publishDate').text()), +8), - guid: link.substring(0, link.lastIndexOf('/')), - link, - }; - - ctx.cache.set(link, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - - ctx.state.data = { - title, - link: `https://www.hkepc.com/${category}`, - description: '電腦領域 HKEPC Hardware - 全港 No.1 PC網站', - language: 'zh-hk', - item: items, - }; -}; diff --git a/lib/v2/hkepc/index.js b/lib/v2/hkepc/index.js new file mode 100644 index 0000000000..2d9fab1f46 --- /dev/null +++ b/lib/v2/hkepc/index.js @@ -0,0 +1,198 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const timezone = require('@/utils/timezone'); +const path = require('path'); +const { art } = require('@/utils/render'); + +module.exports = async (ctx) => { + const category = ctx.params.category ?? ''; + const baseUrl = `https://www.hkepc.com`; + + let response; + if (category === 'price' || category === 'review' || category === 'coverStory' || category === 'news' || category === 'press' || category === 'member') { + response = await got({ + url: `${baseUrl}/news`, + headers: { + Referer: baseUrl, + }, + }); + } else if (category === 'digital' || category === 'entertainment' || category === 'latest' || category === '') { + response = await got(baseUrl); + } else { + // category === ocLab + response = await got({ + url: `${baseUrl}/${category}`, + headers: { + Referer: baseUrl, + }, + }); + } + + const $ = cheerio.load(response.data); + + let feedTitle = '電腦領域 HKEPC'; + let items; + switch (category) { + case 'price': + feedTitle += ' - 腦場新聞'; + items = $('#sidebar > div:nth-child(1) > div.content > ul > li') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'review': + feedTitle += ' - 新品快遞'; + items = $('#sidebar > div:nth-child(2) > div.content > ul > li') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'coverStory': + feedTitle += ' - 專題報導'; + items = $('#sidebar > div:nth-child(3) > div.content > ul > li') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'news': + feedTitle += ' - 新聞中心'; + items = $('#sidebar > div:nth-child(4) > div.content > ul > li') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'press': + feedTitle += ' - 業界資訊'; + items = $('#sidebar > div:nth-child(5) > div.content > ul > li') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'member': + feedTitle += ' - 會員消息'; + items = $('#sidebar > div:nth-child(6) > div.content > ul > li') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'digital': + feedTitle += ' - 流動數碼'; + items = $('#contentR5 > div.left > div.article > div.heading') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'entertainment': + feedTitle += ' - 生活娛樂'; + items = $('#contentR5 > div.right > div.article > div.heading') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'latest': + case '': + feedTitle += ' - 最新消息'; + items = $('div .item') + .find('a') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + case 'ocLab': + feedTitle += ' - 超頻領域'; + items = $('.heading') + .toArray() + .map((item) => ({ + title: $(item).text(), + link: baseUrl + $(item).attr('href'), + })); + break; + default: + break; + } + + items = await Promise.all( + items.map((item) => + ctx.cache.tryGet(item.link, async () => { + const detailResponse = await got({ + url: item.link, + headers: { + Referer: baseUrl, + }, + }); + + const content = cheerio.load(detailResponse.data); + + // remove unwanted elements + content('#view > div.advertisement').remove(); + content('div#comments').remove(); + content('div#share_btn').remove(); + + // Non-breaking space U+00A0, ` ` in html + // Taken from /caixin/blog.js + content('#view > p') + .filter((_, e) => e.children[0].data === String.fromCharCode(160)) + .remove(); + + // fix lazyload image + content('#view > p > img').each((_, e) => { + e = content(e); + e.after( + art(path.join(__dirname, 'templates/image.art'), { + src: e.attr('rel') ?? e.attr('src'), + alt: e.attr('alt'), + }) + ); + e.remove(); + }); + + item.author = content('.newsAuthor').text().trim() ?? content('#articleHead div.author').text().trim(); + item.category = content('div#relatedArticles div.tags a') + .toArray() + .map((e) => content(e).text().trim()); + item.description = art(path.join(__dirname, 'templates/description.art'), { + desc: content('#view').html(), + }); + item.pubDate = timezone(parseDate(content('.publishDate').text()), +8); + item.guid = item.link.substring(0, item.link.lastIndexOf('/')); + + return item; + }) + ) + ); + + ctx.state.data = { + title: feedTitle, + link: `https://www.hkepc.com/${category}`, + description: '電腦領域 HKEPC Hardware - 全港 No.1 PC網站', + language: 'zh-hk', + item: items, + }; +}; diff --git a/lib/v2/hkepc/maintainer.js b/lib/v2/hkepc/maintainer.js new file mode 100644 index 0000000000..9644afe025 --- /dev/null +++ b/lib/v2/hkepc/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:category?': ['TonyRL'], +}; diff --git a/lib/v2/hkepc/radar.js b/lib/v2/hkepc/radar.js new file mode 100644 index 0000000000..bbfd687412 --- /dev/null +++ b/lib/v2/hkepc/radar.js @@ -0,0 +1,19 @@ +module.exports = { + 'hkepc.com': { + _name: 'HKEPC', + '.': [ + { + title: 'HKEPC 电脑领域', + docs: 'https://docs.rsshub.app/new-media.html#hkepc', + source: ['/:category?'], + target: '/hkepc/:category?', + }, + { + title: 'HKEPC 电脑领域', + docs: 'https://docs.rsshub.app/new-media.html#hkepc', + source: ['/'], + target: '/hkepc', + }, + ], + }, +}; diff --git a/lib/v2/hkepc/router.js b/lib/v2/hkepc/router.js new file mode 100644 index 0000000000..cf781366fd --- /dev/null +++ b/lib/v2/hkepc/router.js @@ -0,0 +1,3 @@ +module.exports = function (router) { + router.get('/:category?', require('./index')); +}; diff --git a/lib/v2/hkepc/templates/description.art b/lib/v2/hkepc/templates/description.art new file mode 100644 index 0000000000..7755ee9f6b --- /dev/null +++ b/lib/v2/hkepc/templates/description.art @@ -0,0 +1 @@ +{{@ desc }} diff --git a/lib/v2/hkepc/templates/image.art b/lib/v2/hkepc/templates/image.art new file mode 100644 index 0000000000..40140a947e --- /dev/null +++ b/lib/v2/hkepc/templates/image.art @@ -0,0 +1 @@ +{{ alt }}