diff --git a/lib/routes-deprecated/p-articles/contributors.js b/lib/routes-deprecated/p-articles/contributors.js deleted file mode 100644 index 1d7dc09cf..000000000 --- a/lib/routes-deprecated/p-articles/contributors.js +++ /dev/null @@ -1,45 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const url = require('url'); -const utils = require('./utils'); - -const host = 'https://p-articles.com/'; - -module.exports = async (ctx) => { - const author = ctx.params.author; - - const link = `https://p-articles.com/contributors/${author}`; - - const response = await got.get(link); - const $ = cheerio.load(response.data); - - const list = $('div.contect_box_05in > a') - .map(function () { - const info = { - title: $(this).find('h3').text().trim(), - link: url.resolve(host, $(this).attr('href')), - }; - return info; - }) - .get(); - - const out = await Promise.all( - list.map(async (info) => { - const link = info.link; - - const cache = await ctx.cache.get(link); - if (cache) { - return JSON.parse(cache); - } - const response = await got.get(link); - - return utils.ProcessFeed(ctx, info, response.data); - }) - ); - - ctx.state.data = { - title: `虛詞作者-${author}`, - link, - item: out, - }; -}; diff --git a/lib/routes-deprecated/p-articles/section.js b/lib/routes-deprecated/p-articles/section.js deleted file mode 100644 index b0b5631e4..000000000 --- a/lib/routes-deprecated/p-articles/section.js +++ /dev/null @@ -1,53 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const url = require('url'); -const utils = require('./utils'); - -const host = 'https://p-articles.com/'; - -module.exports = async (ctx) => { - let section_name = ctx.params.section; - section_name = section_name.replace('-', '/'); - section_name += '/'; - - const link = url.resolve(host, section_name); - - const response = await got.get(link); - const $ = cheerio.load(response.data); - - const top_info = { - title: $('div.inner_top_title_01 > h1 > a').text(), - link: url.resolve(host, $('div.inner_top_title_01 > h1 > a').attr('href')), - }; - - const list = $('div.contect_box_04 > a') - .map(function () { - const info = { - title: $(this).find('h1').text().trim(), - link: url.resolve(host, $(this).attr('href')), - }; - return info; - }) - .get(); - - list.unshift(top_info); - - const out = await Promise.all( - list.map(async (info) => { - const link = info.link; - - const cache = await ctx.cache.get(link); - if (cache) { - return JSON.parse(cache); - } - const response = await got.get(link); - - return utils.ProcessFeed(ctx, info, response.data); - }) - ); - ctx.state.data = { - title: `虛詞版块-${section_name}`, - link, - item: out, - }; -}; diff --git a/lib/routes-deprecated/p-articles/utils.js b/lib/routes-deprecated/p-articles/utils.js deleted file mode 100644 index bb3552f6a..000000000 --- a/lib/routes-deprecated/p-articles/utils.js +++ /dev/null @@ -1,30 +0,0 @@ -const cheerio = require('cheerio'); -const { parseRelativeDate } = require('@/utils/parse-date'); -const timezone = require('@/utils/timezone'); - -const ProcessFeed = (ctx, info, data) => { - const title = info.title; - const itemUrl = info.link; - - const $ = cheerio.load(data); - - const author = $('div.detail_title_02 > h4 > a:nth-child(2)').text().trim(); - - const date_value = $('div.detail_title_02 > h4 ').text().trim(); - - const description = $('div.detail_contect_01').html(); - - const single = { - title, - link: itemUrl, - description, - author, - pubDate: timezone(parseRelativeDate(date_value), 8), - }; - ctx.cache.set(itemUrl, JSON.stringify(single)); - return Promise.resolve(single); -}; - -module.exports = { - ProcessFeed, -}; diff --git a/lib/routes/p-articles/contributors.ts b/lib/routes/p-articles/contributors.ts new file mode 100644 index 000000000..1e5a397be --- /dev/null +++ b/lib/routes/p-articles/contributors.ts @@ -0,0 +1,53 @@ +import { Route } from '@/types'; +import ofetch from '@/utils/ofetch'; +import { load } from 'cheerio'; +import cache from '@/utils/cache'; +import { rootUrl, ProcessFeed } from './utils'; + +export const route: Route = { + path: '/contributors/:author', + categories: ['reading'], + example: '/p-articles/contributors/黃衍仁', + parameters: { author: '虛詞作者, 可在作者页面 URL 找到' }, + name: '虛詞作者', + maintainers: ['Insomnia1437'], + handler, + radar: [ + { + source: ['p-articles.com/contributors/:author'], + }, + ], +}; + +async function handler(ctx) { + const authorName: string = ctx.req.param('author'); + const authorUrl = new URL(`/contributors/${authorName}`, rootUrl).href; + const response = await ofetch(authorUrl); + const $ = load(response); + + const list = $('div.contect_box_05in > a') + .map(function () { + const info = { + title: $(this).find('h3').text().trim(), + link: new URL($(this).attr('href'), rootUrl).href, + }; + return info; + }) + .get(); + + const items = await Promise.all( + list.map((info) => + cache.tryGet(info.link, async () => { + const response = await ofetch(info.link); + // const $ = load(response); + return ProcessFeed(info, response); + }) + ) + ); + return { + title: '虚词 p-articles', + link: authorUrl, + item: items, + language: 'zh-cn', + }; +} diff --git a/lib/routes/p-articles/namespace.ts b/lib/routes/p-articles/namespace.ts new file mode 100644 index 000000000..6488ca78d --- /dev/null +++ b/lib/routes/p-articles/namespace.ts @@ -0,0 +1,13 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: '虚词', + url: 'p-articles.com', + description: ` +:::tip +p-articles provides some official RSS feeds: + +- section: \`https://p-articles.com/section/:section\` +- contributors: \`https://p-articles.com/contributors/:author\` +:::`, +}; diff --git a/lib/routes/p-articles/section.ts b/lib/routes/p-articles/section.ts new file mode 100644 index 000000000..dbc3650c3 --- /dev/null +++ b/lib/routes/p-articles/section.ts @@ -0,0 +1,60 @@ +import { Route } from '@/types'; +import ofetch from '@/utils/ofetch'; +import { load } from 'cheerio'; +import cache from '@/utils/cache'; +import { rootUrl, ProcessFeed } from './utils'; + +export const route: Route = { + path: '/section/:section', + categories: ['reading'], + example: '/p-articles/section/critics', + parameters: { section: '版块名称, 可在对应版块 URL 中找到, 子版块链接用`-`连接' }, + name: '版块', + maintainers: ['Insomnia1437'], + handler, + radar: [ + { + source: ['p-articles.com/:section/'], + }, + ], +}; + +async function handler(ctx) { + let sectionName: string = ctx.req.param('section'); + sectionName = sectionName.replace('-', '/'); + sectionName += '/'; + const sectionUrl = new URL(sectionName, rootUrl).href; + const response = await ofetch(sectionUrl); + const $ = load(response); + const topInfo = { + title: $('div.inner_top_title_01 > h1 > a').text(), + link: new URL($('div.inner_top_title_01 > h1 > a').prop('href'), rootUrl).href, + }; + + const list = $('div.contect_box_04 > a') + .map(function () { + const info = { + title: $(this).find('h1').text().trim(), + link: new URL($(this).attr('href'), rootUrl).href, + }; + return info; + }) + .get(); + list.unshift(topInfo); + + const items = await Promise.all( + list.map((info) => + cache.tryGet(info.link, async () => { + const response = await ofetch(info.link); + // const $ = load(response); + return ProcessFeed(info, response); + }) + ) + ); + return { + title: '虚词 p-articles', + link: sectionUrl, + item: items, + language: 'zh-cn', + }; +} diff --git a/lib/routes/p-articles/utils.ts b/lib/routes/p-articles/utils.ts new file mode 100644 index 000000000..6645ad6c1 --- /dev/null +++ b/lib/routes/p-articles/utils.ts @@ -0,0 +1,21 @@ +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import timezone from '@/utils/timezone'; + +const rootUrl: string = 'https://p-articles.com'; + +const ProcessFeed = (info, data) => { + // const $ = cheerio.load(data); + const $ = load(data); + const author = $('div.detail_title_02 > h4 > a:nth-child(2)').text().trim(); + info.author = author; + + const dateValue = $('div.detail_title_02 > h4 ').text().trim(); + info.pubDate = timezone(parseDate(dateValue), +8); + + const description = $('div.detail_contect_01').html(); + info.description = description; + return info; +}; + +export { rootUrl, ProcessFeed };