feat(route): bc3ts (#15963)

This commit is contained in:
Tony 2024-06-22 03:26:31 +08:00 committed by GitHub
parent 55a0ececb4
commit f186a5833f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 207 additions and 0 deletions

72
lib/routes/bc3ts/list.ts Normal file
View File

@ -0,0 +1,72 @@
import { Route } from '@/types';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import { art } from '@/utils/render';
import path from 'node:path';
import { Media, PostResponse } from './types';
import { config } from '@/config';
import { getCurrentPath } from '@/utils/helpers';
const __dirname = getCurrentPath(import.meta.url);
export const route: Route = {
path: '/post/list/:sort?',
example: '/bc3ts/post/list',
parameters: {
sort: '排序方式,`1` 為最新,`2` 為熱門,默认為 `1`',
},
features: {
antiCrawler: true,
},
radar: [
{
source: ['web.bc3ts.net'],
},
],
name: '動態',
maintainers: ['TonyRL'],
handler,
};
const baseUrl = 'https://web.bc3ts.net';
const renderMedia = (media: Media[]) => art(path.join(__dirname, 'templates', 'media.art'), { media });
async function handler(ctx) {
const { sort = '1' } = ctx.req.param();
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 20;
const response = await ofetch<PostResponse>('https://app.bc3ts.net/post/list/v2', {
headers: {
apikey: 'zlF+kaPfem%23we$2@90irpE*_RGjdw',
app_version: '3.0.28',
version: '2.0.0',
'User-Agent': config.trueUA,
},
query: {
limits: limit,
sort_type: sort,
},
});
const items = response.data.map((p) => ({
title: p.title ?? p.content.split('\n')[0],
description: p.content.replaceAll('\n', '<br>') + (p.media.length && renderMedia(p.media)),
link: `${baseUrl}/post/${p.id}`,
author: p.user.name,
pubDate: parseDate(p.created_time, 'x'),
category: p.group.name,
upvotes: p.like_count,
comments: p.comment_count,
}));
return {
title: `爆料公社${sort === '1' ? '最新' : '熱門'}動態`,
link: baseUrl,
language: 'zh-TW',
image: 'https://img.bc3ts.net/image/web/main/logo-white-new-2023.png',
icon: 'https://img.bc3ts.net/image/web/main/logo/logo_icon_6th_2024_192x192.png',
item: items,
};
}

View File

@ -0,0 +1,7 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: '爆料公社',
url: 'web.bc3ts.net',
categories: ['new-media'],
};

View File

@ -0,0 +1,10 @@
<br>
{{ each media m }}
{{ if m.type === 0 }}
<img src="{{ m.media_url }}" alt="{{ m.name }}" />
{{ else if m.type === 3 }}
<video controls preload="metadata" poster="https://img.bc3ts.net/video/post/upload/{{ m.cover }}">
<source src="{{ m.media_url }}" type="video/mp4" />
</video>
{{ /if }}
{{ /each }}

118
lib/routes/bc3ts/types.ts Normal file
View File

@ -0,0 +1,118 @@
interface Medal {
id: number;
name: string;
image: string;
}
interface HeadFrame {
id: number;
image: string;
}
interface UsingItem {
medal: Medal | null;
head_frame: HeadFrame | null;
}
interface Relationship {
status: number;
that_status: number;
}
interface User {
id: string;
name: string;
badge: any[];
level: number;
using_item: UsingItem;
relationship: Relationship;
boom_verified: number;
}
interface SafeSearch {
racy: string;
adult: string;
spoof: string;
medical: string;
violence: string;
}
export interface Media {
id: number;
type: number;
name: string;
width: number;
height: number;
cover: string | null;
status: string;
safe_search: SafeSearch;
unlock_item: null;
media_url: string;
}
interface Group {
id: number;
name: string;
type: number;
god_id: string;
status: number;
privacy: number;
layout_type: number;
share_status: number;
post_can_use_anonymous: boolean;
approve_user_permission_status: number[];
}
interface Reward {
money: number;
diamond: number;
}
interface Post {
id: number;
user: User;
title: string | null;
content: string;
appendix: object;
created_time: number;
expired_time: number;
media: Media[];
like: number;
like_count: number;
collection: number;
top: number;
reference_reply_count: number;
reference_share_count: number;
comment_count: number;
group: Group;
block_user: any[];
tag_user_index: any[];
reward: Reward;
reference: null;
latitude: number | null;
longitude: number | null;
unique_like_count: number;
unique_exposure_count: number;
unique_priority_point: number;
unique_priority_time: string | null;
safe_search: number;
unlock_type: null;
unlock_item: object;
is_unlocked: null;
visibility: number;
is_anonymous: number;
is_me: number;
comment_can_use_anonymous: number;
who_can_read: number;
poll: null;
activity: null;
poll_status: null;
is_cache: boolean;
is_editor: boolean;
theme_id: null;
}
export interface PostResponse {
code: number;
data: Post[];
}