Skip to content

Commit

Permalink
Support Github trending, hackernews and producthunt
Browse files Browse the repository at this point in the history
Now support source from Github Trending, hackernews and producthunt
  • Loading branch information
RoversX committed Jan 13, 2025
1 parent 0fa3108 commit 484b73c
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/router.types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,4 +385,29 @@ export type RouterType = {
desc: string;
timestamp: string;
};
hackernews: {
id: string;
title: string;
hot: number | undefined;
timestamp: number | undefined;
url: string;
mobileUrl: string;
};
github: {
id: string;
title: string;
desc?: string;
hot: number | undefined;
timestamp: number | undefined;
url: string;
mobileUrl: string;
};
producthunt: {
id: string;
title: string;
hot: number | undefined;
timestamp: number | undefined;
url: string;
mobileUrl: string;
};
};
61 changes: 61 additions & 0 deletions src/routes/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { RouterData } from "../types.js";
import { get } from "../utils/getData.js";
import { load } from "cheerio";
import type { RouterType } from "../router.types.js";

export const handleRoute = async (_: undefined, noCache: boolean) => {
const listData = await getList(noCache);
const routeData: RouterData = {
name: "github",
title: "GitHub",
type: "Trending",
description: "See what the GitHub community is most excited about today",
link: "https://github.com/trending",
total: listData.data?.length || 0,
...listData,
};
return routeData;
};

const getList = async (noCache: boolean) => {
const baseUrl = "https://github.com";
const result = await get({
url: `${baseUrl}/trending?spoken_language_code=`,
noCache,
headers: {
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
});

try {
const $ = load(result.data);
const stories: RouterType["github"][] = [];

$("main .Box div[data-hpc] > article").each((_, el) => {
const a = $(el).find(">h2 a");
const title = a.text().replace(/\n+/g, "").trim();
const path = 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 (path && title) {
stories.push({
id: path.slice(1), // 移除开头的 /
title,
desc,
hot: parseInt(star.replace(/,/g, "")) || undefined,
timestamp: undefined,
url: `${baseUrl}${path}`,
mobileUrl: `${baseUrl}${path}`,
});
}
});

return {
...result,
data: stories,
};
} catch (error) {
throw new Error(`Failed to parse GitHub Trending HTML: ${error}`);
}
};
63 changes: 63 additions & 0 deletions src/routes/hackernews.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { RouterData } from "../types.js";
import { get } from "../utils/getData.js";
import { load } from "cheerio";
import type { RouterType } from "../router.types.js";

export const handleRoute = async (_: undefined, noCache: boolean) => {
const listData = await getList(noCache);
const routeData: RouterData = {
name: "hackernews",
title: "Hacker News",
type: "Popular",
description: "News about hacking and startups",
link: "https://news.ycombinator.com/",
total: listData.data?.length || 0,
...listData,
};
return routeData;
};

const getList = async (noCache: boolean) => {
const baseUrl = "https://news.ycombinator.com";
const result = await get({
url: baseUrl,
noCache,
headers: {
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
});

try {
const $ = load(result.data);
const stories: RouterType["hackernews"][] = [];

$(".athing").each((_, el) => {
const item = $(el);
const id = item.attr("id") || "";
const title = item.find(".titleline a").first().text().trim();
const url = item.find(".titleline a").first().attr("href");

// 获取分数并转换为数字
const scoreText = $(`#score_${id}`).text().match(/\d+/)?.[0];
const hot = scoreText ? parseInt(scoreText, 10) : undefined;

if (id && title) {
stories.push({
id,
title,
hot,
timestamp: undefined,
url: url || `${baseUrl}/item?id=${id}`,
mobileUrl: url || `${baseUrl}/item?id=${id}`,
});
}
});

return {
...result,
data: stories,
};
} catch (error) {
throw new Error(`Failed to parse HackerNews HTML: ${error}`);
}
};
60 changes: 60 additions & 0 deletions src/routes/producthunt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { RouterData } from "../types.js";
import { get } from "../utils/getData.js";
import { load } from "cheerio";
import type { RouterType } from "../router.types.js";

export const handleRoute = async (_: undefined, noCache: boolean) => {
const listData = await getList(noCache);
const routeData: RouterData = {
name: "producthunt",
title: "Product Hunt",
type: "Today",
description: "The best new products, every day",
link: "https://www.producthunt.com/",
total: listData.data?.length || 0,
...listData,
};
return routeData;
};

const getList = async (noCache: boolean) => {
const baseUrl = "https://www.producthunt.com";
const result = await get({
url: baseUrl,
noCache,
headers: {
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
});

try {
const $ = load(result.data);
const stories: RouterType["producthunt"][] = [];

$("[data-test=homepage-section-0] [data-test^=post-item]").each((_, el) => {
const a = $(el).find("a").first();
const path = a.attr("href");
const title = $(el).find("a[data-test^=post-name]").text().trim();
const id = $(el).attr("data-test")?.replace("post-item-", "");
const vote = $(el).find("[data-test=vote-button]").text().trim();

if (path && id && title) {
stories.push({
id,
title,
hot: parseInt(vote) || undefined,
timestamp: undefined,
url: `${baseUrl}${path}`,
mobileUrl: `${baseUrl}${path}`,
});
}
});

return {
...result,
data: stories,
};
} catch (error) {
throw new Error(`Failed to parse Product Hunt HTML: ${error}`);
}
};

0 comments on commit 484b73c

Please sign in to comment.