Skip to content

Commit fc5d346

Browse files
authored
fix(route): 8kcos selectors for latest/cat/tag pages (#21269)
* fix(route): 8kcos selectors for latest/cat/tag pages * fix: add maintainer info from #7237 * fix: use wordpress api --------- Co-authored-by: choury <choury@users.noreply.github.com>
1 parent 18548f8 commit fc5d346

File tree

6 files changed

+93
-94
lines changed

6 files changed

+93
-94
lines changed

lib/routes/8kcos/article.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

lib/routes/8kcos/cat.ts

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
import { load } from 'cheerio';
2-
31
import type { Route } from '@/types';
4-
import cache from '@/utils/cache';
5-
import got from '@/utils/got';
62

7-
import loadArticle from './article';
8-
import { SUB_NAME_PREFIX, SUB_URL } from './const';
3+
import { getCategoryInfo, getPosts } from './utils';
94

105
export const route: Route = {
11-
path: '/cat/:cat{.+}?',
6+
path: '/cat/:cat?',
7+
parameters: {
8+
cat: '默认值为 `8kasianidol`,将目录页面url中 /category/ 后面的部分填入。如:https://www.8kcosplay.com/category/8kchineseidol/%e9%a3%8e%e4%b9%8b%e9%a2%86%e5%9f%9f/ 对应的RSS页面为 /8kcos/cat/%e9%a3%8e%e4%b9%8b%e9%a2%86%e5%9f%9f。',
9+
},
10+
example: '/8kcos/cat/8kasianidol',
1211
radar: [
1312
{
14-
source: ['8kcosplay.com/'],
15-
target: '',
13+
source: ['8kcosplay.com/category/:mainCategory/:cat/', '8kcosplay.com/category/:cat/'],
14+
target: '/cat/:cat',
1615
},
1716
],
18-
name: 'Unknown',
19-
maintainers: [],
17+
name: '分类',
18+
maintainers: ['KotoriK'],
2019
handler,
2120
url: '8kcosplay.com/',
2221
features: {
@@ -25,20 +24,15 @@ export const route: Route = {
2524
};
2625

2726
async function handler(ctx) {
28-
const limit = Number.parseInt(ctx.req.query('limit'));
27+
const limit = Number.parseInt(ctx.req.query('limit') ?? 10, 10);
2928
const { cat = '8kasianidol' } = ctx.req.param();
30-
const url = `${SUB_URL}category/${cat}/`;
31-
const resp = await got(url);
32-
const $ = load(resp.body);
33-
const itemRaw = $('li.item').toArray();
29+
const categoryInfo = await getCategoryInfo(cat);
30+
const items = await getPosts(limit, { categories: categoryInfo.id });
31+
3432
return {
35-
title: `${SUB_NAME_PREFIX}-${$('span[property=name]:not(.hide)').text()}`,
36-
link: url,
37-
item: await Promise.all(
38-
(limit ? itemRaw.slice(0, limit) : itemRaw).map((e) => {
39-
const { href } = load(e)('h2 > a')[0].attribs;
40-
return cache.tryGet(href, () => loadArticle(href));
41-
})
42-
),
33+
title: categoryInfo.title,
34+
description: categoryInfo.description,
35+
link: categoryInfo.link,
36+
item: items,
4337
};
4438
}

lib/routes/8kcos/const.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

lib/routes/8kcos/latest.ts

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
1-
import { load } from 'cheerio';
2-
31
import type { Route } from '@/types';
4-
import cache from '@/utils/cache';
5-
import got from '@/utils/got';
6-
7-
import loadArticle from './article';
8-
import { SUB_NAME_PREFIX, SUB_URL } from './const';
92

10-
const url = SUB_URL;
3+
import { getPosts, SUB_NAME_PREFIX, SUB_URL } from './utils';
114

125
export const route: Route = {
136
path: '/',
147
categories: ['picture'],
15-
example: '/8kcos/',
8+
example: '/8kcos',
169
parameters: {},
1710
features: {
1811
requireConfig: false,
@@ -26,7 +19,6 @@ export const route: Route = {
2619
radar: [
2720
{
2821
source: ['8kcosplay.com/'],
29-
target: '',
3022
},
3123
],
3224
name: '最新',
@@ -36,19 +28,11 @@ export const route: Route = {
3628
};
3729

3830
async function handler(ctx) {
39-
const limit = Number.parseInt(ctx.req.query('limit'));
40-
const response = await got(url);
41-
const itemRaw = load(response.body)('ul.post-loop li.item').toArray();
31+
const limit = Number.parseInt(ctx.req.query('limit') ?? 10, 10);
32+
const items = await getPosts(limit);
4233
return {
4334
title: `${SUB_NAME_PREFIX}-最新`,
44-
link: url,
45-
item:
46-
response.body &&
47-
(await Promise.all(
48-
(limit ? itemRaw.slice(0, limit) : itemRaw).map((e) => {
49-
const { href } = load(e)('h2 > a')[0].attribs;
50-
return cache.tryGet(href, () => loadArticle(href));
51-
})
52-
)),
35+
link: SUB_URL,
36+
item: items,
5337
};
5438
}

lib/routes/8kcos/tag.ts

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
import { load } from 'cheerio';
2-
31
import type { Route } from '@/types';
4-
import cache from '@/utils/cache';
5-
import got from '@/utils/got';
62

7-
import loadArticle from './article';
8-
import { SUB_NAME_PREFIX, SUB_URL } from './const';
3+
import { getPosts, getTagInfo, SUB_URL } from './utils';
94

105
export const route: Route = {
116
path: '/tag/:tag',
@@ -33,21 +28,14 @@ export const route: Route = {
3328
};
3429

3530
async function handler(ctx) {
36-
const limit = Number.parseInt(ctx.req.query('limit'));
31+
const limit = Number.parseInt(ctx.req.query('limit') ?? 10, 10);
3732
const tag = ctx.req.param('tag');
38-
const url = `${SUB_URL}tag/${tag}/`;
39-
const resp = await got(url);
40-
const $ = load(resp.body);
41-
const itemRaw = $('li.item').toArray();
33+
const tagInfo = await getTagInfo(tag);
34+
const items = await getPosts(limit, { tags: tagInfo.id });
4235

4336
return {
44-
title: `${SUB_NAME_PREFIX}-${$('span[property=name]:not(.hide)').text()}`,
45-
link: url,
46-
item: await Promise.all(
47-
(limit ? itemRaw.slice(0, limit) : itemRaw).map((e) => {
48-
const { href } = load(e)('h2 > a')[0].attribs;
49-
return cache.tryGet(href, () => loadArticle(href));
50-
})
51-
),
37+
title: `${tagInfo.title}`,
38+
link: `${SUB_URL}/tag/${tag}/`,
39+
item: items,
5240
};
5341
}

lib/routes/8kcos/utils.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { DataItem } from '@/types';
2+
import cache from '@/utils/cache';
3+
import ofetch from '@/utils/ofetch';
4+
import { parseDate } from '@/utils/parse-date';
5+
6+
export const SUB_NAME_PREFIX = '8KCosplay';
7+
export const SUB_URL = 'https://www.8kcosplay.com';
8+
9+
export const getPosts = async (limit: number, options?: { categories?: number; tags?: number }) => {
10+
const data = await ofetch(`https://www.8kcosplay.com/wp-json/wp/v2/posts`, {
11+
query: {
12+
per_page: limit,
13+
_embed: '',
14+
...options,
15+
},
16+
});
17+
return data.map((item) => ({
18+
title: item.title.rendered,
19+
description: item.content.rendered,
20+
link: item.link,
21+
pubDate: parseDate(item.date_gmt),
22+
author: item._embedded?.['author']?.map((a) => a.name).join(', '),
23+
category: item._embedded?.['wp:term']?.flatMap((terms) => terms.map((t) => t.name)),
24+
})) satisfies DataItem[];
25+
};
26+
27+
export const getCategoryInfo = (category: string) =>
28+
cache.tryGet(`8kcosplay:category:${category}`, async () => {
29+
const data = await ofetch(`https://www.8kcosplay.com/wp-json/wp/v2/categories`, {
30+
query: {
31+
slug: category,
32+
},
33+
});
34+
const categoryInfo = data[0];
35+
if (!categoryInfo) {
36+
throw new Error('Category not found');
37+
}
38+
return {
39+
id: categoryInfo.id,
40+
title: categoryInfo.yoast_head_json.title,
41+
description: categoryInfo.description,
42+
link: categoryInfo.link,
43+
};
44+
});
45+
46+
export const getTagInfo = (tag: string) =>
47+
cache.tryGet(`8kcosplay:tag:${tag}`, async () => {
48+
const data = await ofetch(`https://www.8kcosplay.com/wp-json/wp/v2/tags`, {
49+
query: {
50+
slug: tag,
51+
},
52+
});
53+
const tagInfo = data[0];
54+
if (!tagInfo) {
55+
throw new Error('Tag not found');
56+
}
57+
return {
58+
id: tagInfo.id,
59+
title: tagInfo.yoast_head_json.title,
60+
description: tagInfo.description,
61+
};
62+
});

0 commit comments

Comments
 (0)