diff --git a/lib/routes/423down/index.ts b/lib/routes/423down/index.ts index dd754109ae..d2daf55baa 100644 --- a/lib/routes/423down/index.ts +++ b/lib/routes/423down/index.ts @@ -1,123 +1,280 @@ import { Route } from '@/types'; +import { getCurrentPath } from '@/utils/helpers'; +const __dirname = getCurrentPath(import.meta.url); + import cache from '@/utils/cache'; import got from '@/utils/got'; import { load } from 'cheerio'; import { parseDate } from '@/utils/parse-date'; +import { art } from '@/utils/render'; +import path from 'node:path'; -const rootUrl = 'https://www.423down.com'; +export const handler = async (ctx) => { + const { category = '' } = ctx.req.param(); + const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 18; -const categeoryMap = { - index: { - all: '', - }, - android: { - apk: 'apk', - }, - computer: { - originalsoft: 'zd423', - multimedia: 'multimedia', - browser: 'browser', - image: 'image', - im: 'im', - work: 'work', - down: 'down', - systemsoft: 'systemsoft', - systemplus: 'systemplus', - security: 'security', - patch: 'patch', - hardware: 'hardware', - }, - os: { - win11: 'win11', - win10: 'win10', - win7: 'win7', - winxp: 'winxp', - winpe: 'pe-system', - }, -}; + const domain = '423down.com'; + const rootUrl = `https://www.${domain}`; + const currentUrl = new URL(category, rootUrl).href; -const titleMap = { - index: { - all: '首页', - }, - android: { - apk: '安卓软件', - }, - computer: { - originalsoft: '原创软件', - multimedia: '媒体播放', - browser: '网页浏览', - image: '图形图像', - im: '聊天软件', - work: '办公软件', - down: '上传下载', - systemsoft: '系统辅助', - systemplus: '系统必备', - security: '安全软件', - patch: '补丁相关', - hardwork: '硬件相关', - }, - os: { - win11: 'windows 11', - win10: 'Windows 10', - win7: 'Windows 7', - winxp: 'Windows XP', - winpe: 'Windows PE', - }, + const { data: response } = await got(currentUrl); + + const $ = load(response); + + const language = $('html').prop('lang'); + + let items = $('ul.excerpt li') + .toArray() + .filter((item) => { + item = $(item); + + const link = item.find('h2 a').prop('href'); + + return new RegExp(domain).test(link); + }) + .slice(0, limit) + .map((item) => { + item = $(item); + + const title = item.find('h2').text(); + const image = item.find('a.pic img').prop('src'); + const description = art(path.join(__dirname, 'templates/description.art'), { + images: image + ? [ + { + src: image, + alt: title, + }, + ] + : undefined, + intro: item.find('div.note').text(), + }); + + return { + title, + description, + pubDate: parseDate(item.find('span.time').text(), 'MM-DD'), + link: item.find('h2 a').prop('href'), + category: item + .find('span.cat a') + .toArray() + .map((c) => $(c).text()), + content: { + html: description, + text: item.find('div.note').text(), + }, + image, + banner: image, + language, + enclosure_url: image, + enclosure_type: image ? `image/${image.split(/\./).pop()}` : undefined, + enclosure_title: title, + }; + }); + + items = await Promise.all( + items.map((item) => + cache.tryGet(item.link, async () => { + const { data: detailResponse } = await got(item.link); + + const $$ = load(detailResponse); + + const title = $$('h1.meta-tit a').text(); + const description = + item.description + + art(path.join(__dirname, 'templates/description.art'), { + description: $$('div.entry').html(), + }); + + item.title = title; + item.description = description; + item.pubDate = parseDate($$('p.meta-info').contents().first().text().trim().split(/\s/)[0], 'YYYY-MM-DD'); + item.category = $$('p.meta-info a[rel="category tag"]') + .toArray() + .map((c) => $$(c).text()); + item.content = { + html: description, + text: $$('div.entry').text(), + }; + item.language = language; + + return item; + }) + ) + ); + + const title = $('title').first().text(); + const image = new URL('wp-content/themes/D7/img/423Down.png', rootUrl).href; + + return { + title, + description: $('title').last().text(), + link: currentUrl, + item: items, + allowEmpty: true, + image, + author: title.split(/-/).pop()?.trim(), + language, + }; }; export const route: Route = { - path: '/:category/:type?', - name: 'Unknown', - maintainers: [], + path: '/:category{.+}?', + name: '423Down', + url: '423down.com', + maintainers: ['nczitzk'], handler, + example: '/423down', + parameters: { category: '分类,默认为首页,可在对应分类页 URL 中找到' }, + description: `:::tip + 若订阅 [Android - 423Down](https://www.423down.com/apk),网址为 \`https://www.423down.com/apk\`。截取 \`https://www.423down.com/\` 到末尾的部分 \`apk\` 作为参数填入,此时路由为 [\`/423down/apk\`](https://rsshub.app/423down/apk)。 + ::: + + #### [安卓软件](https://www.423down.com/apk) + + | [安卓软件](https://www.423down.com/apk) | + | --------------------------------------- | + | [apk](https://rsshub.app/423down/apk) | + + #### 电脑软件 + + | [原创软件](https://www.423down.com/zd423) | [媒体播放](https://www.423down.com/multimedia) | [网页浏览](https://www.423down.com/browser) | [图形图像](https://www.423down.com/image) | [聊天软件](https://www.423down.com/im) | + | ----------------------------------------- | --------------------------------------------------- | --------------------------------------------- | ----------------------------------------- | -------------------------------------- | + | [zd423](https://rsshub.app/423down/zd423) | [multimedia](https://rsshub.app/423down/multimedia) | [browser](https://rsshub.app/423down/browser) | [image](https://rsshub.app/423down/image) | [im](https://rsshub.app/423down/im) | + + | [办公软件](https://www.423down.com/work) | [上传下载](https://www.423down.com/down) | [实用软件](https://www.423down.com/softtool) | [系统辅助](https://www.423down.com/systemsoft) | [系统必备](https://www.423down.com/systemplus) | + | ---------------------------------------- | ---------------------------------------- | ----------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | + | [work](https://rsshub.app/423down/work) | [down](https://rsshub.app/423down/down) | [softtool](https://rsshub.app/423down/softtool) | [systemsoft](https://rsshub.app/423down/systemsoft) | [systemplus](https://rsshub.app/423down/systemplus) | + + | [安全软件](https://www.423down.com/security) | [补丁相关](https://www.423down.com/patch) | [硬件相关](https://www.423down.com/hardware) | + | ----------------------------------------------- | ----------------------------------------- | ----------------------------------------------- | + | [security](https://rsshub.app/423down/security) | [patch](https://rsshub.app/423down/patch) | [hardware](https://rsshub.app/423down/hardware) | + + #### 操作系统 + + | [Windows 11](https://www.423down.com/win11) | [Windows 10](https://www.423down.com/win10) | [Windows 7](https://www.423down.com/win7) | [Windows XP](https://www.423down.com/win7/winxp) | [WinPE](https://www.423down.com/pe-system) | + | ------------------------------------------- | ------------------------------------------- | ----------------------------------------- | --------------------------------------------------- | ------------------------------------------------- | + | [win11](https://rsshub.app/423down/win11) | [win10](https://rsshub.app/423down/win10) | [win7](https://rsshub.app/423down/win7) | [win7/winxp](https://rsshub.app/423down/win7/winxp) | [pe-system](https://rsshub.app/423down/pe-system) | + `, + categories: ['program-update'], + + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportRadar: true, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + radar: [ + { + source: ['423down.com/:category', '423down.com'], + target: (params) => { + const category = params.category; + + return `/423down${category ? `/${category}` : ''}`; + }, + }, + { + title: '首页', + source: ['www.423down.com'], + target: '/', + }, + { + title: '安卓软件', + source: ['www.423down.com/apk'], + target: '/apk', + }, + { + title: '电脑软件 - 原创软件', + source: ['www.423down.com/zd423'], + target: '/zd423', + }, + { + title: '电脑软件 - 媒体播放', + source: ['www.423down.com/multimedia'], + target: '/multimedia', + }, + { + title: '电脑软件 - 网页浏览', + source: ['www.423down.com/browser'], + target: '/browser', + }, + { + title: '电脑软件 - 图形图像', + source: ['www.423down.com/image'], + target: '/image', + }, + { + title: '电脑软件 - 聊天软件', + source: ['www.423down.com/im'], + target: '/im', + }, + { + title: '电脑软件 - 办公软件', + source: ['www.423down.com/work'], + target: '/work', + }, + { + title: '电脑软件 - 上传下载', + source: ['www.423down.com/down'], + target: '/down', + }, + { + title: '电脑软件 - 实用软件', + source: ['www.423down.com/softtool'], + target: '/softtool', + }, + { + title: '电脑软件 - 系统辅助', + source: ['www.423down.com/systemsoft'], + target: '/systemsoft', + }, + { + title: '电脑软件 - 系统必备', + source: ['www.423down.com/systemplus'], + target: '/systemplus', + }, + { + title: '电脑软件 - 安全软件', + source: ['www.423down.com/security'], + target: '/security', + }, + { + title: '电脑软件 - 补丁相关', + source: ['www.423down.com/patch'], + target: '/patch', + }, + { + title: '电脑软件 - 硬件相关', + source: ['www.423down.com/hardware'], + target: '/hardware', + }, + { + title: '操作系统 - Windows 11', + source: ['www.423down.com/win11'], + target: '/win11', + }, + { + title: '操作系统 - Windows 10', + source: ['www.423down.com/win10'], + target: '/win10', + }, + { + title: '操作系统 - Windows 7', + source: ['www.423down.com/win7'], + target: '/win7', + }, + { + title: '操作系统 - Windows XP', + source: ['www.423down.com/win7/winxp'], + target: '/win7/winxp', + }, + { + title: '操作系统 - WinPE', + source: ['www.423down.com/pe-system'], + target: '/pe-system', + }, + ], }; - -async function handler(ctx) { - const { category, type } = ctx.req.param(); - - const url = `${rootUrl}/${categeoryMap[category][type]}`; - - const response = await got.get(url); - const $ = load(response.data); - const list = $('div.content-wrap > div > ul > li > a') - .filter((_, item) => { - const notAnotherWebPage = $(item).attr('style') !== 'display: none !important;'; - return notAnotherWebPage; - }) - .map((_, item) => ({ - link: $(item).attr('href'), - })) - .get(); - - const items = await Promise.all( - list.map(async (item) => { - item = await cache.tryGet(item.link, async () => { - const detailResponse = await got.get(item.link); - const $ = load(detailResponse.data); - - const title = $('div.content-wrap > div > div.meta > h1 > a').text(); - const pageContent = $('div.content-wrap > div > div.entry').html(); - const pageComments = $('#postcomments > ol').html(); - const desc = pageContent + pageComments; - const date = $('div.content-wrap > div > div.meta > p').text(); - const categeory = $('div.content-wrap > div > div.meta > p > a:not(.comm)').text(); - - item.title = title; - item.description = desc; - item.categeory = categeory; - item.pubDate = parseDate(date.split(' ')[0], 'YYYY-MM-DD'); - - return item; - }); - - return item; - }) - ); - - return { - title: `423down-${titleMap[category][type]}`, - link: url, - item: items, - }; -} diff --git a/lib/routes/423down/namespace.ts b/lib/routes/423down/namespace.ts index f72c2e10fb..e04849800f 100644 --- a/lib/routes/423down/namespace.ts +++ b/lib/routes/423down/namespace.ts @@ -2,5 +2,7 @@ import type { Namespace } from '@/types'; export const namespace: Namespace = { name: '423Down', - url: 'www.423down.com', + url: '423down.com', + categories: ['program-update'], + description: '', }; diff --git a/lib/routes/423down/templates/description.art b/lib/routes/423down/templates/description.art new file mode 100644 index 0000000000..249654e7e6 --- /dev/null +++ b/lib/routes/423down/templates/description.art @@ -0,0 +1,21 @@ +{{ if images }} + {{ each images image }} + {{ if image?.src }} +
+ {{ image.alt }} +
+ {{ /if }} + {{ /each }} +{{ /if }} + +{{ if intro }} +
{{ intro }}
+{{ /if }} + +{{ if description }} + {{@ description }} +{{ /if }} \ No newline at end of file