diff --git a/example.env.server b/example.env.server index 8c920c5..c42c760 100644 --- a/example.env.server +++ b/example.env.server @@ -1,5 +1,5 @@ -G_CLIENT_ID= -G_CLIENT_SECRET= -JWT_SECRET= +G_CLIENT_ID=Ov23liR8HcDsGdKHq2I8 +G_CLIENT_SECRET=7c9e75439e330488d3cdb2df963976d35f0e2bbf +JWT_SECRET=7c9e75439e330488d3cdb2df963976d35f0e2bbf INIT_TABLE=true -ENABLE_CACHE=true \ No newline at end of file +ENABLE_CACHE=true diff --git a/example.wrangler.toml b/example.wrangler.toml index 5f20b3b..d1da17b 100644 --- a/example.wrangler.toml +++ b/example.wrangler.toml @@ -4,5 +4,5 @@ compatibility_date = "2024-10-03" [[d1_databases]] binding = "NEWSNOW_DB" -database_name = "newsnow-db" -database_id = "" +database_name = "hot_news" +database_id = "5e83d319-1acf-4a26-b1e2-f9ca1868e157" diff --git a/public/icons/huxiu.png b/public/icons/huxiu.png new file mode 100644 index 0000000..eb85dda Binary files /dev/null and b/public/icons/huxiu.png differ diff --git a/server/api/s/index.ts b/server/api/s/index.ts index 8c2b94c..4ce010f 100644 --- a/server/api/s/index.ts +++ b/server/api/s/index.ts @@ -1,6 +1,6 @@ import type { SourceID, SourceResponse } from "@shared/types" -import { getters } from "#/getters" import { getCacheTable } from "#/database/cache" +import { getters } from "#/getters" import type { CacheInfo } from "#/types" export default defineEventHandler(async (event): Promise => { @@ -13,7 +13,7 @@ export default defineEventHandler(async (event): Promise => { if (isValid(id)) { const redirectID = sources?.[id]?.redirect if (redirectID) id = redirectID - if (isValid(id)) throw new Error("Invalid source id") + if (isValid(id)) throw new Error(`Invalid source ${id}`) } const cacheTable = await getCacheTable() diff --git a/server/glob.d.ts b/server/glob.d.ts index 9ccdbb2..d899aa7 100644 --- a/server/glob.d.ts +++ b/server/glob.d.ts @@ -12,6 +12,7 @@ declare module 'glob:./sources/{*.ts,**/index.ts}' { export const gelonghui: typeof import('./sources/gelonghui') export const github: typeof import('./sources/github') export const hackernews: typeof import('./sources/hackernews') + export const huxiu: typeof import('./sources/huxiu') export const ithome: typeof import('./sources/ithome') export const jin10: typeof import('./sources/jin10') export const kaopu: typeof import('./sources/kaopu') diff --git a/server/sources/_36kr.ts b/server/sources/_36kr.ts index c2dc9f2..6749b7f 100644 --- a/server/sources/_36kr.ts +++ b/server/sources/_36kr.ts @@ -28,8 +28,40 @@ const quick = defineSource(async () => { return news }) +const information = defineSource(async () => { + const baseURL = "https://www.36kr.com" + const url = `${baseURL}/information/web_news` + const response = await myFetch(url) as any + const $ = load(response) + const news: NewsItem[] = [] + + // 选择资讯页面的文章列表 + const $items = $(".information-flow-item") + $items.each((_, el) => { + const $el = $(el) + const $a = $el.find(".article-item-title.weight-bold") + const url = $a.attr("href") + const title = $a.text().trim() + const time = $el.find(".kr-flow-bar-time").text().trim() + + if (url && title && time) { + news.push({ + url: url.startsWith("http") ? url : `${baseURL}${url}`, + title, + id: url, + extra: { + date: parseRelativeDate(time, "Asia/Shanghai").valueOf(), + info: "36氪资讯", // 添加标识 + }, + }) + } + }) + + return news +}) export default defineSource({ "36kr": quick, "36kr-quick": quick, + "36kr-information": information, }) diff --git a/server/sources/huxiu.ts b/server/sources/huxiu.ts new file mode 100644 index 0000000..d6e8003 --- /dev/null +++ b/server/sources/huxiu.ts @@ -0,0 +1,49 @@ +import type { NewsItem } from "@shared/types" +import { load } from "cheerio" + +const quick24 = defineSource(async () => { + const baseURL = "https://www.huxiu.com" + const url = `${baseURL}/article` // or moment + const response = await myFetch(url) as any + const $ = load(response) + const news: NewsItem[] = [] + const $items = $(".article-item-wrap") + $items.each((_, el) => { + // 文字类 + const $el = $(el) + const $a = $el.find("a.content-wrap") + const url = $a.attr("href") + const title = $a.find(".two-lines").text() + const relativeDate = $el.find(".bottom-line__time").text() + if (url && title && relativeDate) { + news.push({ + url: `${url}`, + title, + id: url, + extra: { + date: parseRelativeDate(relativeDate, "Asia/Shanghai").valueOf(), + }, + }) + } + // 图片类 + const c_title = $el.find(".channel-title").text().trim() + const c_url = $el.find(".article-item-wrap a").first().attr("href") + if (c_url && c_title && relativeDate) { + news.push({ + url: `${c_url}`, + title: c_title, + id: c_url, + extra: { + date: parseRelativeDate(relativeDate, "Asia/Shanghai").valueOf(), + }, + }) + } + }) + + return news +}) + +export default defineSource({ + "huxiu": quick24, + "huxiu-quick": quick24, +}) diff --git a/shared/pinyin.json b/shared/pinyin.json index 5683474..a9f2789 100644 --- a/shared/pinyin.json +++ b/shared/pinyin.json @@ -1,5 +1,8 @@ { "v2ex-share": "V2EX-zuixinfenxiang", + "huxiu-quick": "huxiuwang-kuaixun", + "36kr-quick": "36ke-kuaixun", + "36kr-information": "36ke-zixun", "zhihu": "zhihu", "weibo": "weibo-shishiresou", "zaobao": "lianhezaobao", diff --git a/shared/sources.ts b/shared/sources.ts index d32d5dd..fac2ae8 100644 --- a/shared/sources.ts +++ b/shared/sources.ts @@ -23,6 +23,43 @@ export const originSources = { }, }, }, + "huxiu": { + name: "虎嗅网", + // type: "realtime", + type: "hottest", + color: "blue", + // cloudflare pages cannot access + // disable: true, + home: "https://huxiu.com", + sub: { + quick: { + title: "快讯", + column: "finance", + }, + }, + }, + "36kr": { + name: "36氪", + // type: "realtime", + type: "hottest", + color: "blue", + // cloudflare pages cannot access + // disable: true, + home: "https://36kr.com", + sub: { + quick: { + title: "快讯", + type: "hottest", + column: "finance", + + }, + information: { + title: "资讯", + type: "realtime", + column: "finance", + }, + }, + }, "zhihu": { name: "知乎", type: "hottest", @@ -77,19 +114,7 @@ export const originSources = { }, }, }, - "36kr": { - name: "36氪", - type: "realtime", - color: "blue", - // cloudflare pages cannot access - disable: true, - home: "https://36kr.com", - sub: { - quick: { - title: "快讯", - }, - }, - }, + "douyin": { name: "抖音", type: "hottest", @@ -218,6 +243,7 @@ export const originSources = { color: "orange", column: "tech", type: "hottest", + disable: true, home: "https://news.ycombinator.com/", }, "producthunt": { @@ -225,6 +251,7 @@ export const originSources = { color: "red", column: "tech", type: "hottest", + disable: true, home: "https://www.producthunt.com/", }, "github": { diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 4e496b6..fd00fc7 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -1,12 +1,12 @@ -/* prettier-ignore-start */ - /* eslint-disable */ // @ts-nocheck // noinspection JSUnusedGlobalSymbols -// This file is auto-generated by TanStack Router +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. // Import Routes @@ -90,8 +90,6 @@ export const routeTree = rootRoute ._addFileChildren(rootRouteChildren) ._addFileTypes() -/* prettier-ignore-end */ - /* ROUTE_MANIFEST_START { "routes": {