feat(route): add route for skebetter (#17181)
* feat(route): add route for skebetter * feat: add radar * Update lib/routes/skebetter/index.ts Co-authored-by: Tony <TonyRL@users.noreply.github.com> * Update lib/routes/skebetter/manga.ts Co-authored-by: Tony <TonyRL@users.noreply.github.com> * Update lib/routes/skebetter/illust.ts Co-authored-by: Tony <TonyRL@users.noreply.github.com> * fix: import config ---------
This commit is contained in:
parent
69a35d2f56
commit
ff76aa7267
|
|
@ -0,0 +1,83 @@
|
|||
import { Data, DataItem, Route } from '@/types';
|
||||
import cache from '@/utils/cache';
|
||||
import { processItems, fetchData } from './utils';
|
||||
import { config } from '@/config';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/illust/:type',
|
||||
categories: ['anime'],
|
||||
example: '/skebetter/illust/hot',
|
||||
parameters: { type: 'Type, see below' },
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
name: 'Illust',
|
||||
maintainers: ['SnowAgar25'],
|
||||
handler,
|
||||
radar: [
|
||||
{
|
||||
title: 'Illust - Hot',
|
||||
source: ['skebetter.com/illust'],
|
||||
target: '/illust/hot',
|
||||
},
|
||||
{
|
||||
title: 'Illust - Week',
|
||||
source: ['skebetter.com/illust'],
|
||||
target: '/illust/week',
|
||||
},
|
||||
{
|
||||
title: 'Illust - Month',
|
||||
source: ['skebetter.com/illust'],
|
||||
target: '/illust/month',
|
||||
},
|
||||
{
|
||||
title: 'Illust - Latest',
|
||||
source: ['skebetter.com/illust'],
|
||||
target: '/illust/latest',
|
||||
},
|
||||
],
|
||||
description: `
|
||||
| 急上昇 | 週間 | 月間 | 新着 |
|
||||
| ----- | ---- | ---- | ---- |
|
||||
| hot | week | month| latest |`,
|
||||
};
|
||||
|
||||
async function handler(ctx): Promise<Data> {
|
||||
const type = ctx.req.param('type');
|
||||
const baseUrl = 'https://api.twieromanga.com/api/illust/hot';
|
||||
const typeMap = {
|
||||
hot: '急上昇',
|
||||
week: '週間',
|
||||
month: '月間',
|
||||
latest: '新着',
|
||||
};
|
||||
const linkMap = {
|
||||
hot: '',
|
||||
week: '?term=week',
|
||||
month: '?term=month',
|
||||
latest: '?term=latest',
|
||||
};
|
||||
|
||||
const url = `${baseUrl}?type=${type}`;
|
||||
|
||||
const items = await cache.tryGet(
|
||||
url,
|
||||
async () => {
|
||||
const data = await fetchData(url);
|
||||
return processItems(data, 'illust');
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
false
|
||||
);
|
||||
|
||||
return {
|
||||
title: `Skebetter Illust - ${typeMap[type]}`,
|
||||
link: `https://skebetter.com/illust${linkMap[type]}`,
|
||||
item: items as DataItem[],
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import { Data, DataItem, Route } from '@/types';
|
||||
import cache from '@/utils/cache';
|
||||
import { processItems, fetchData } from './utils';
|
||||
import { config } from '@/config';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/:type',
|
||||
categories: ['anime'],
|
||||
example: '/skebetter/hot',
|
||||
parameters: { type: 'Type, see below' },
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
name: 'Hot',
|
||||
maintainers: ['SnowAgar25'],
|
||||
handler,
|
||||
radar: [
|
||||
{
|
||||
title: 'Skebetter - Hot',
|
||||
source: ['skebetter.com'],
|
||||
target: '/hot',
|
||||
},
|
||||
{
|
||||
title: 'Skebetter - Week',
|
||||
source: ['skebetter.com'],
|
||||
target: '/week',
|
||||
},
|
||||
{
|
||||
title: 'Skebetter - Month',
|
||||
source: ['skebetter.com'],
|
||||
target: '/month',
|
||||
},
|
||||
{
|
||||
title: 'Skebetter - Latest',
|
||||
source: ['skebetter.com'],
|
||||
target: '/latest',
|
||||
},
|
||||
],
|
||||
description: `
|
||||
| 急上昇 | 週間 | 月間 | 新着 |
|
||||
| ----- | ---- | ---- | ---- |
|
||||
| hot | week | month| latest |`,
|
||||
};
|
||||
|
||||
async function handler(ctx): Promise<Data> {
|
||||
const type = ctx.req.param('type');
|
||||
const baseUrl = 'https://api.twieromanga.com/api/hotv2';
|
||||
const typeMap = {
|
||||
hot: '急上昇',
|
||||
week: '週間',
|
||||
month: '月間',
|
||||
latest: '新着',
|
||||
};
|
||||
const linkMap = {
|
||||
hot: '',
|
||||
week: '?term=week',
|
||||
month: '?term=month',
|
||||
latest: '?term=latest',
|
||||
};
|
||||
|
||||
const url = `${baseUrl}?type=${type}`;
|
||||
|
||||
const items = await cache.tryGet(
|
||||
url,
|
||||
async () => {
|
||||
const data = await fetchData(url);
|
||||
return processItems(data, 'index');
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
false
|
||||
);
|
||||
|
||||
return {
|
||||
title: `Skebetter - ${typeMap[type]}`,
|
||||
link: `https://skebetter.com/${linkMap[type]}`,
|
||||
item: items as DataItem[],
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import { Data, DataItem, Route } from '@/types';
|
||||
import cache from '@/utils/cache';
|
||||
import { processItems, fetchData } from './utils';
|
||||
import { config } from '@/config';
|
||||
|
||||
export const route: Route = {
|
||||
path: '/manga/:order',
|
||||
categories: ['anime'],
|
||||
example: '/skebetter/manga/1',
|
||||
parameters: { order: 'Order, see below.' },
|
||||
features: {
|
||||
requireConfig: false,
|
||||
requirePuppeteer: false,
|
||||
antiCrawler: false,
|
||||
supportBT: false,
|
||||
supportPodcast: false,
|
||||
supportScihub: false,
|
||||
},
|
||||
name: 'Manga',
|
||||
maintainers: ['SnowAgar25'],
|
||||
handler,
|
||||
radar: [
|
||||
{
|
||||
title: 'Manga - Latest',
|
||||
source: ['skebetter.com/series'],
|
||||
target: '/manga/1',
|
||||
},
|
||||
{
|
||||
title: 'Manga - Hot',
|
||||
source: ['skebetter.com/series'],
|
||||
target: '/manga/2',
|
||||
},
|
||||
],
|
||||
description: `
|
||||
| 新着 (Latest) | 人気 (Hot) |
|
||||
| ---- | ---- |
|
||||
| 1 | 2 |`,
|
||||
};
|
||||
|
||||
async function handler(ctx): Promise<Data> {
|
||||
const order = ctx.req.param('order') ?? '1';
|
||||
const baseUrl = 'https://api.twieromanga.com/api/mangaseries';
|
||||
const orderMap = {
|
||||
'1': '新着',
|
||||
'2': '人気',
|
||||
};
|
||||
|
||||
const url = `${baseUrl}?order=${order}`;
|
||||
|
||||
const items = await cache.tryGet(
|
||||
url,
|
||||
async () => {
|
||||
const data = await fetchData(url, true);
|
||||
return processItems(data, 'manga');
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
false
|
||||
);
|
||||
|
||||
return {
|
||||
title: `Skebetter Manga - ${orderMap[order]}`,
|
||||
link: `https://skebetter.com/series?order=${order}`,
|
||||
item: items as DataItem[],
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import type { Namespace } from '@/types';
|
||||
|
||||
export const namespace: Namespace = {
|
||||
name: 'Skebetter',
|
||||
url: 'skebetter.com',
|
||||
};
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import { DataItem } from '@/types';
|
||||
import { ofetch } from 'ofetch';
|
||||
|
||||
export interface MediaUrl {
|
||||
h: number;
|
||||
w: number;
|
||||
sh: number;
|
||||
sw: number;
|
||||
type: string;
|
||||
media_id: string | null;
|
||||
media_uri: string;
|
||||
media_index: number;
|
||||
}
|
||||
|
||||
export interface Tweet {
|
||||
id: string;
|
||||
screen_name: string;
|
||||
series_id?: number;
|
||||
text: string;
|
||||
date: string;
|
||||
img: string;
|
||||
user_name: string;
|
||||
fav: string;
|
||||
retweet: string;
|
||||
user_id: string;
|
||||
media_url: string;
|
||||
media_count: number;
|
||||
hashtags?: Record<string, unknown>;
|
||||
media_urls: MediaUrl[];
|
||||
score: string;
|
||||
rank: number;
|
||||
}
|
||||
|
||||
export const processItems = (data: Tweet[], type: 'index' | 'illust' | 'manga'): DataItem[] =>
|
||||
data.map((item) => {
|
||||
const baseAuthorUrl = `https://skebetter.com/author/${item.user_id}`;
|
||||
const description = `
|
||||
<p>❤${item.fav} 🔁${item.retweet}</p>
|
||||
${item.media_urls.map((media) => `<img src="${media.media_uri}" />`).join('')}
|
||||
`;
|
||||
|
||||
if (type === 'manga') {
|
||||
return {
|
||||
title: item.text,
|
||||
description,
|
||||
author: item.user_name,
|
||||
link: `https://skebetter.com/series/${item.series_id}`,
|
||||
};
|
||||
}
|
||||
|
||||
if (type === 'illust') {
|
||||
return {
|
||||
title: item.text,
|
||||
description,
|
||||
author: item.user_name,
|
||||
link: `${baseAuthorUrl}/illust/${item.id}`,
|
||||
};
|
||||
}
|
||||
|
||||
// type === 'index'
|
||||
return {
|
||||
title: item.text,
|
||||
description,
|
||||
author: item.user_name,
|
||||
link: item.series_id ? `https://skebetter.com/series/${item.series_id}` : `${baseAuthorUrl}/manga/${item.id}`,
|
||||
};
|
||||
});
|
||||
|
||||
export const fetchData = async (url: string, isManga: boolean = false) => {
|
||||
const response = await ofetch(url);
|
||||
return isManga ? (response as Tweet[]) : (response.tweet as Tweet[]);
|
||||
};
|
||||
Loading…
Reference in New Issue