feat(source): add github treading and product hunt

This commit is contained in:
Ou 2024-10-25 13:29:23 +08:00
parent 46b9f0e28f
commit ec0fca2324
8 changed files with 88 additions and 7 deletions

BIN
public/icons/github.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

2
server/glob.d.ts vendored
View File

@ -8,8 +8,10 @@ declare module 'glob:./sources/{*.ts,**/index.ts}' {
export const douyin: typeof import('./sources/douyin')
export const fastbull: typeof import('./sources/fastbull')
export const gelonghui: typeof import('./sources/gelonghui')
export const github: typeof import('./sources/github')
export const hackernews: typeof import('./sources/hackernews')
export const ithome: typeof import('./sources/ithome')
export const producthunt: typeof import('./sources/producthunt')
export const solidot: typeof import('./sources/solidot')
export const sputniknewscn: typeof import('./sources/sputniknewscn')
export const thepaper: typeof import('./sources/thepaper')

34
server/sources/github.ts Normal file
View File

@ -0,0 +1,34 @@
import * as cheerio from "cheerio"
import type { NewsItem } from "@shared/types"
const trending = defineSource(async () => {
const baseURL = "https://github.com"
const html: any = await $fetch("https://github.com/trending?spoken_language_code=")
const $ = cheerio.load(html)
const $main = $("main .Box div[data-hpc] > article")
const news: NewsItem[] = []
$main.each((_, el) => {
const a = $(el).find(">h2 a")
const title = a.text().replace(/\n+/g, "").trim()
const url = a.attr("href")
const star = $(el).find("[href$=stargazers]").text().replace(/\s+/g, "").trim()
const desc = $(el).find(">p").text().replace(/\n+/g, "").trim()
if (url && title) {
news.push({
url: `${baseURL}${url}`,
title,
id: url,
extra: {
info: `${star}`,
hover: desc,
},
})
}
})
return news
})
export default defineSource({
"github": trending,
"github-trending-today": trending,
})

View File

@ -0,0 +1,28 @@
import * as cheerio from "cheerio"
import type { NewsItem } from "@shared/types"
export default defineSource(async () => {
const baseURL = "https://www.producthunt.com/"
const html: any = await $fetch(baseURL)
const $ = cheerio.load(html)
const $main = $("[data-test^=post-item]")
const news: NewsItem[] = []
$main.each((_, el) => {
const a = $(el).find("a").first()
const url = a.attr("href")
const title = $(el).find("a[data-test^=post-name]").text()
const id = $(el).attr("data-test")?.replace("post-item-", "")
const vote = $(el).find("[data-test=vote-button]").text()
if (url && id && title) {
news.push({
url: `${baseURL}${url}`,
title,
id,
extra: {
info: `△︎ ${vote}`,
},
})
}
})
return news
})

View File

@ -15,7 +15,7 @@ const originMetadata: Metadata = {
},
tech: {
name: "科技",
sources: ["hackernews", "v2ex", "ithome", "coolapk", "solidot"],
sources: ["hackernews", "producthunt", "github-trending-today", "v2ex", "ithome", "coolapk", "solidot"],
},
finance: {
name: "财经",

View File

@ -197,6 +197,23 @@ export const originSources = {
type: "hottest",
home: "https://news.ycombinator.com/",
},
"producthunt": {
name: "Product Hunt",
color: "orange",
type: "hottest",
home: "https://www.producthunt.com/",
},
"github": {
name: "Github",
color: "gray",
home: "https://github.com/",
sub: {
"trending-today": {
title: "Today",
type: "hottest",
},
},
},
} as const satisfies Record<string, OriginSource>
export const sources = genSources()

View File

@ -15,12 +15,12 @@ export type SourceID = {
}[keyof SubSource] | Key : Key;
}[MainSourceID]
// export type AllSourceID = {
// [Key in MainSourceID]: ConstSources[Key] extends { sub?: infer SubSource } ? keyof {
// // @ts-expect-error >_<
// [SubKey in keyof SubSource as `${Key}-${SubKey}`]: never
// } | Key : Key
// }[MainSourceID]
export type AllSourceID = {
[Key in MainSourceID]: ConstSources[Key] extends { sub?: infer SubSource } ? keyof {
// @ts-expect-error >_<
[SubKey in keyof SubSource as `${Key}-${SubKey}`]: never
} | Key : Key
}[MainSourceID]
// export type DisabledSourceID = Exclude<SourceID, MainSourceID>