feat(route): Add 3kns(3k-Switch游戏库) (#14907)

* feat(route): Add 3kns(3k-Switch游戏库)

* feat(route): 3kns merge route parameters & apply suggestions from code review

* fix: typings

---------
This commit is contained in:
Mg Pig 2024-03-26 01:36:32 +08:00 committed by GitHub
parent f1b8eb3cbc
commit 6f477d053d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 136 additions and 0 deletions

121
lib/routes/3kns/index.ts Normal file
View File

@ -0,0 +1,121 @@
import { Data, DataItem, Route } from '@/types';
import got from '@/utils/got';
import { getCurrentPath } from '@/utils/helpers';
import { parseDate } from '@/utils/parse-date';
import { art } from '@/utils/render';
import { load } from 'cheerio';
import { Context } from 'hono';
import * as path from 'node:path';
const __dirname = getCurrentPath(import.meta.url);
export const route: Route = {
path: '/:filters?/:order?',
categories: ['game'],
example: '/3kns/category=all&lang=all',
parameters: {
filters: '过滤器,可用参数见下表',
order: '排序,按高分排序:desc;按低分排序:asc',
},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
name: '3k-Switch游戏库',
maintainers: ['xzzpig'],
handler,
url: 'www.3kns.com/',
description: `游戏类型(category)
| | | | | | | | | | | | | | |
| ---- | -------- | -------- | -------- | -------- | -------- | ------ | -------- | -------- | -------- | -------- | ------ | -------- | -------- |
| all | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
(language)
| | | | | | | |
| ---- | ---- | ---- | ---- | ---- | -------- | ---- |
| all | 1 | 2 | 3 | 4 | 5 | 6 |
(tag)
| | | | | | | | | RPG | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | xci | | |
| ---- | ---- | -------- | ---- | ---- | ---- | ---- | ---- | --- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | -------- | ---- | ---- | ---- | ---- | ---- | ---- | -------- | ---- | ---- | ---- | ---- | -------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | -------- | ---- | ---- |
| all | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
(pubDate)
| | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 |
| ---- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |
| all | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
(collection)
| | | | | | | | | | | | | | | |
| ---- | -------- | ------ | -------- | -------- | -------- | ------ | ------ | ---------- | ------ | -------- | ------ | -------- | -------- | -------- |
| all | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |`,
};
async function handler(ctx: Context): Promise<Data> {
const filters = new URLSearchParams(ctx.req.param('filters'));
const order = ctx.req.param('order');
const category = filters.get('category') ?? 'all';
const language = filters.get('language') ?? 'all';
const tag = filters.get('tag') ?? 'all';
const pubDate = filters.get('pubDate') ?? 'all';
const collection = filters.get('collection') ?? 'all';
const baseUrl = 'https://www.3kns.com/';
const currentUrl = new URL(`${baseUrl}forum.php?mod=forumdisplay&fid=2&filter=sortid&typeid=0&sortid=1&searchsort=1&orderbystr=0`);
currentUrl.searchParams.set('dztgeshi', category);
currentUrl.searchParams.set('dztfenlei', language);
currentUrl.searchParams.set('nex_sg_tags', tag);
currentUrl.searchParams.set('deanbgbs', pubDate);
currentUrl.searchParams.set('nex_sg_stars', collection);
if (order !== undefined) {
currentUrl.searchParams.set('ascdescstr', order);
currentUrl.searchParams.set('orderbystr', 'nex_sg_score');
}
const response = await got(currentUrl);
const $ = load(response.data as any);
const selector = `form .newItem`;
const items: DataItem[] = $(selector)
.toArray()
.map((item) => {
const $item = $(item);
const title = $item.find('.showname a').text().trim();
const category = $item.find('.showtype').text().trim();
const pubDate = ($item.find('.showdate').contents()[0] as any).data.trim();
return {
title,
link: baseUrl + $item.find('.entry-media a').attr('href')!,
pubDate: parseDate(pubDate ?? ''),
category: [category],
description:
art(path.join(__dirname, 'templates/description.art'), {
cover: $item.find('.entry-media img').attr('src')?.trim().replace('.', baseUrl),
title,
tid: $item.find('.jb-chakan').text().trim(),
category,
language: $item.find('.jb-new').text().trim(),
pubDate,
system: $item.find('.jb-youxxx').text().trim(),
score: $item.find('.shownamep').text().trim(),
version: $item.find('.jb-youxbb').text().trim(),
}) ?? '',
};
});
return {
title: $('title').text(),
link: currentUrl.toString(),
allowEmpty: true,
item: items,
};
}

View File

@ -0,0 +1,6 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: '3k-Switch游戏库',
url: 'www.3kns.com',
};

View File

@ -0,0 +1,9 @@
<img src="{{ cover }}">
<h1>{{ title }}</h1>
<p>游戏TID{{ tid }}</p>
<p>类型:{{ category }}</p>
<p>语言:{{ language }}</p>
<p>更新日期:{{ pubDate }}</p>
<p>系统要求:{{ system }}</p>
<p>{{ score }}</p>
<p>游戏版本:{{ version }}</p>