feat: new source

This commit is contained in:
Ou 2024-10-21 17:00:51 +08:00
parent d285f37eeb
commit 3b66d0f081
13 changed files with 69 additions and 61 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -13,7 +13,7 @@ export default defineEventHandler(async (event): Promise<SourceResponse> => {
const isValid = (id: SourceID) => !id || !sources[id] || !sourcesGetters[id]
if (isValid(id)) {
const redirectID = sources?.[id].redirect
const redirectID = sources?.[id]?.redirect
if (redirectID) id = redirectID
if (isValid(id)) throw new Error("Invalid source id")
}

View File

@ -9,28 +9,12 @@ interface Res {
}
}
async function getDyCookies() {
try {
const cookisUrl = "https://www.douyin.com/passport/general/login_guiding_strategy/?aid=6383"
const data = await $fetch.raw(cookisUrl)
const pattern = /passport_csrf_token=(.*); Path/s
const matchResult = data.headers.get("set-cookie")?.[0]?.match(pattern)
if (matchResult && matchResult.length > 1) {
const cookieData = matchResult[1]
return cookieData
}
} catch (error) {
logger.error(`获取抖音 Cookie 出错: ${error}`)
return null
}
}
export default defineSource(async () => {
const url = "https://www.douyin.com/aweme/v1/web/hot/search/list/?device_platform=webapp&aid=6383&channel=channel_pc_web&detail_list=1"
const cookie = await getDyCookies()
const cookie = (await $fetch.raw("https://www.douyin.com/passport/general/login_guiding_strategy/?aid=6383")).headers.getSetCookie()
const res: Res = await $fetch(url, {
headers: {
Cookie: `passport_csrf_token=${cookie}`,
cookie: cookie.join("; "),
},
})
return res.data.word_list

View File

@ -12,7 +12,7 @@ export default defineSource(async () => {
// https://www.kzaobao.com/shiju/20241002/170659.html
const url = a.attr("href")
const title = a.find("h2").text()
const info = $(el).find(".about-stocks").text()
const info = $(el).find(".time > span:nth-child(1)").text()
// 第三个 p
const relatieveTime = $(el).find(".time > span:nth-child(3)").text()
if (url && title && relatieveTime) {
@ -27,5 +27,5 @@ export default defineSource(async () => {
})
}
})
return news.sort((m, n) => n.extra!.date > m.extra!.date ? 1 : -1)
return news
})

View File

@ -14,6 +14,8 @@ import cls from "./cls"
import sputniknewscn from "./sputniknewscn"
import xueqiu from "./xueqiu"
import gelonghui from "./gelonghui"
import tieba from "./tieba"
import thepaper from "./thepaper"
import type { SourceGetter } from "#/types"
export const sourcesGetters = {
@ -24,6 +26,7 @@ export const sourcesGetters = {
zhihu,
coolapk,
cankaoxiaoxi,
thepaper,
sputniknewscn,
...wallstreetcn,
...xueqiu,
@ -31,5 +34,6 @@ export const sourcesGetters = {
douyin,
...cls,
toutiao,
tieba,
...kr36,
} as Record<SourceID, SourceGetter> & Partial<Record<DisabledSourceID, SourceGetter>>

View File

@ -0,0 +1,23 @@
interface Res {
data: {
hotNews: {
contId: string
name: string
pubTimeLong: string
}[]
}
}
export default defineSource(async () => {
const url = "https://cache.thepaper.cn/contentapi/wwwIndex/rightSidebar"
const res: Res = await $fetch(url)
return res.data.hotNews
.map((k) => {
return {
id: k.contId,
title: k.name,
url: `https://www.thepaper.cn/newsDetail_forward_${k.contId}`,
mobileUrl: `https://m.thepaper.cn/newsDetail_forward_${k.contId}`,
}
})
})

26
server/sources/tieba.ts Normal file
View File

@ -0,0 +1,26 @@
interface Res {
data: {
bang_topic: {
topic_list: {
topic_id: string
topic_name: string
create_time: number
topic_url: string
}[]
}
}
}
export default defineSource(async () => {
const url = "https://tieba.baidu.com/hottopic/browse/topicList"
const res: Res = await $fetch(url)
return res.data.bang_topic.topic_list
.map((k) => {
return {
id: k.topic_id,
title: k.topic_name,
url: k.topic_url,
}
})
})

View File

@ -26,7 +26,7 @@ const hotstock = defineSource(async () => {
url: `https://xueqiu.com/s/${k.code}`,
title: k.name,
extra: {
info: `${k.percent}%`,
info: `${k.percent}% ${k.exchange}`,
},
}))
})

View File

@ -57,21 +57,4 @@ export interface SourceOption {
hiddenDate?: boolean
}
export interface FallbackResponse {
code: number
message: string
name: string
title: string
subtitle: string
total: number
updateTime: string
data: {
title: string
desc: string
time?: string
url: string
mobileUrl: string
}[]
}
export type SourceGetter = () => Promise<NewsItem[]>

View File

@ -141,6 +141,7 @@ function toDurations(matches: string[]) {
export const parseDate = (date: string | number, ...options: any) => dayjs(date, ...options).toDate()
export function parseRelativeDate(date: string, timezone: string = "Asia/Shanghai") {
if (date === "刚刚") return new Date()
// 预处理日期字符串 date
const theDate = toDate(date)

View File

@ -1,29 +1,12 @@
import type { AllSourceID, SourceID } from "@shared/types"
import type { AllSourceID } from "@shared/types"
import defu from "defu"
import type { FallbackResponse, RSSHubOption, RSSHubInfo as RSSHubResponse, SourceGetter, SourceOption } from "#/types"
import type { RSSHubOption, RSSHubInfo as RSSHubResponse, SourceGetter, SourceOption } from "#/types"
type X = SourceGetter | Partial<Record<AllSourceID, SourceGetter>>
export function defineSource<T extends X>(source: T): T {
return source
}
export function defineFallbackSource(id: SourceID, option?: SourceOption): SourceGetter {
return async () => {
const url = `https://smzdk.top/api/${id}/new`
const res: FallbackResponse = await $fetch(url)
if (res.code !== 200 || !res.data) throw new Error(res.message)
return res.data.map(item => ({
extra: {
date: !option?.hiddenDate && item.time,
},
id: item.url,
title: item.title,
url: item.url,
mobileUrl: item.mobileUrl,
}))
}
}
export function defineRSSSource(url: string, option?: SourceOption): SourceGetter {
return async () => {
const data = await rss2json(url)

View File

@ -7,7 +7,7 @@ export const columnIds = ["focus", "realtime", "hottest", "china", "world", "tec
const originMetadata: Metadata = {
china: {
name: "国内",
sources: ["weibo", "douyin", "toutiao", "zhihu"],
sources: ["zhihu", "thepaper"],
},
world: {
name: "国际",

View File

@ -96,7 +96,9 @@ export const originSources = {
},
"tieba": {
name: "百度贴吧",
disable: true,
title: "热议",
type: "hottest",
color: "blue",
home: "https://tieba.baidu.com",
},
"toutiao": {
@ -114,7 +116,9 @@ export const originSources = {
"thepaper": {
name: "澎湃新闻",
interval: Time.Common,
disable: true,
type: "hottest",
title: "热榜",
color: "gray",
home: "https://www.thepaper.cn",
},
"sputniknewscn": {