feat(route): add gamersky.com user dynamics route (#21279)
* add user.ts * Replace substring with slice. * fix something
This commit is contained in:
parent
bcba35b41c
commit
4dec5ee309
|
|
@ -0,0 +1,39 @@
|
|||
import type { Context } from 'hono';
|
||||
import type { Route } from '@/types';
|
||||
import { getUserArticle, getUserArticleList, parseUserArticleList } from './utils';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/user/:userId/:detail?',
|
||||
categories: ['game'],
|
||||
example: '/gamersky/user/4009731/detail',
|
||||
parameters: {
|
||||
userId: '用户 ID。在用户个人主页,打开“开发者工具”中的“元素”标签页,搜索 data-userid 即可找到',
|
||||
detail: '是否获取文章详情。只要该参数不为空,就会获取全文内容',
|
||||
},
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
name: '用户动态',
|
||||
maintainers: ['hualiong'],
|
||||
handler,
|
||||
};
|
||||
|
||||
async function handler(ctx: Context) {
|
||||
const { userId, detail } = ctx.req.param();
|
||||
|
||||
const body = await getUserArticleList(userId);
|
||||
const articles = parseUserArticleList(body);
|
||||
if (detail) {
|
||||
articles.list = await Promise.all(articles.list.map((item) => getUserArticle(item)));
|
||||
}
|
||||
return {
|
||||
title: `${articles.uname}的动态 - 游民星空`,
|
||||
link: articles.link,
|
||||
item: articles.list,
|
||||
};
|
||||
}
|
||||
|
|
@ -12,12 +12,19 @@ interface idNameMap {
|
|||
nodeId: string;
|
||||
suffix?: string;
|
||||
}
|
||||
|
||||
interface ArticleList {
|
||||
status: string;
|
||||
totalPages: number;
|
||||
body: string;
|
||||
}
|
||||
|
||||
interface UserArticleList {
|
||||
status: string;
|
||||
body: string;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export const getArticleList = async (nodeId) => {
|
||||
const response = await ofetch<ArticleList>(
|
||||
`https://db2.gamersky.com/LabelJsonpAjax.aspx?${new URLSearchParams({
|
||||
|
|
@ -88,6 +95,47 @@ export const getArticle = (item) =>
|
|||
return item satisfies DataItem;
|
||||
}) as Promise<DataItem>;
|
||||
|
||||
export const getUserArticleList = async (userId: string) => {
|
||||
const response = await ofetch<UserArticleList>(
|
||||
`https://i.gamersky.com/u/api/v2/GetUserContent?${new URLSearchParams({
|
||||
jsondata: JSON.stringify({ pageIndex: 1, pageSize: 20, userId }),
|
||||
})}`,
|
||||
{
|
||||
parseResponse: (txt) =>
|
||||
JSON.parse(txt.slice(1, -2)),
|
||||
},
|
||||
);
|
||||
return response.body;
|
||||
};
|
||||
|
||||
export const parseUserArticleList = (body: string) => {
|
||||
const $ = load(body);
|
||||
const list = $(".cmt-list");
|
||||
const info = list.find(".uname").first();
|
||||
return {
|
||||
uname: info.text(),
|
||||
link: info.attr("href"),
|
||||
list: list.toArray().map((item) => {
|
||||
const e = $(item);
|
||||
const title = e.find(".qzcmt-content-tit a");
|
||||
return {
|
||||
title: title.text(),
|
||||
link: title.attr("href"),
|
||||
pubDate: parseDate(e.attr("data-time")!),
|
||||
description: e.find(".qzcmt-content-txt span").text(),
|
||||
};
|
||||
}) as DataItem[],
|
||||
};
|
||||
};
|
||||
|
||||
export const getUserArticle = (item: DataItem) =>
|
||||
cache.tryGet(item.link!, async () => {
|
||||
const response = await ofetch(item.link!);
|
||||
const $ = load(response);
|
||||
item.description = $(".qzcmt-content-txt").html() || item.description;
|
||||
return item;
|
||||
});
|
||||
|
||||
export function mdTableBuilder(data: idNameMap[]) {
|
||||
const table = '|' + data.map((item) => `${item.type}|`).join('') + '\n|' + Array.from({ length: data.length }).fill('---|').join('') + '\n|' + data.map((item) => `${item.name}|`).join('') + '\n';
|
||||
return table;
|
||||
|
|
|
|||
Loading…
Reference in New Issue