rsshub
Version:
Make RSS Great Again!
294 lines (289 loc) • 12.9 kB
JavaScript
import { t as rofetch } from "./ofetch-W1aeTHCo.mjs";
import { t as parseDate } from "./parse-date-CjhZE69i.mjs";
import { t as cache_default } from "./cache-CiDoUSLo.mjs";
import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
import { load } from "cheerio";
import { renderToString } from "hono/jsx/dom/server";
import { raw } from "hono/html";
//#region lib/routes/deeplearning/templates/description.tsx
const Description = ({ images, intro, description }) => /* @__PURE__ */ jsxs(Fragment, { children: [
images?.map((image, index) => image?.src ? /* @__PURE__ */ jsx("figure", { children: /* @__PURE__ */ jsx("img", {
src: image.src,
alt: image.alt
}) }, `${image.src}-${index}`) : null),
intro ? /* @__PURE__ */ jsx("blockquote", { children: intro }) : null,
description ? /* @__PURE__ */ jsx(Fragment, { children: raw(description) }) : null
] });
const renderDescription = (props) => renderToString(/* @__PURE__ */ jsx(Description, { ...props }));
//#endregion
//#region lib/routes/deeplearning/the-batch.ts
const parseFlightData = (buf) => {
const rows = /* @__PURE__ */ new Map();
let i = 0;
while (i < buf.length) {
const colon = buf.indexOf(58, i);
const id = buf.toString("utf8", i, colon);
let end, value;
if (buf[colon + 1] === 84) {
const comma = buf.indexOf(44, colon);
const length = Number.parseInt(buf.toString("utf8", colon + 2, comma), 16);
value = buf.toString("utf8", comma + 1, comma + 1 + length);
end = comma + 1 + length;
} else {
end = buf.indexOf(10, colon);
value = buf.toString("utf8", colon + 1, end);
}
rows.set(id, value);
i = end + 1;
}
return rows;
};
async function handler(ctx) {
const { tag } = ctx.req.param();
const limit = ctx.req.query("limit") ? Number(ctx.req.query("limit")) : 16;
const rootUrl = "https://www.deeplearning.ai";
const currentUrl = new URL(`the-batch${tag ? `/tag/${tag.replace(/^tag\//, "").replace(/\/$/, "")}` : ""}`, rootUrl).href;
const $ = load(await rofetch(currentUrl));
const language = $("html").prop("lang");
const cardsRow = $("script:contains(\"self.__next_f\")").toArray().map((script) => $(script).text().match(/^self\.__next_f\.push\(\[1,(".*")\]\)$/s)).filter(Boolean).map((m) => JSON.parse(m[1])).join("").split("\n").find((row) => row.includes("\"cards\":["));
if (!cardsRow) throw new Error("No cards found in flight payload");
const { cards } = JSON.parse(cardsRow.replace(/^[0-9a-f]+:/, ""))[3];
let items = cards.slice(0, limit).map((card) => {
const title = card.title;
const description = renderDescription({
images: card.image?.src ? [{
src: card.image.src,
alt: card.image.alt
}] : void 0,
intro: card.excerpt
});
const image = card.image?.src;
const guid = `the-batch-${card.href.split("/").pop()}`;
return {
title,
description,
link: new URL(card.href, rootUrl).href,
guid,
id: guid,
content: {
html: description,
text: card.excerpt
},
image,
banner: image,
language
};
});
items = await Promise.all(items.map((item) => cache_default.tryGet(item.link, async () => {
const detailResponse = await rofetch(item.link, {
headers: { rsc: "1" },
responseType: "arrayBuffer"
});
const rows = parseFlightData(Buffer.from(detailResponse));
const bodyId = rows.values().find((row) => row.includes("\"prose"))?.match(/"__html":"\$(\w+)"/)?.[1];
if (!bodyId || !rows.has(bodyId)) throw new Error("No article body found in flight payload");
const $$ = load(rows.get(bodyId));
$$("#elevenlabs-audionative-widget").remove();
$$("a").each((_, ele) => {
if (!ele.attribs.href?.includes("utm_campaign")) return;
const url = new URL(ele.attribs.href);
url.searchParams.delete("utm_campaign");
url.searchParams.delete("utm_source");
url.searchParams.delete("utm_medium");
url.searchParams.delete("_hsenc");
ele.attribs.href = url.href;
});
const metaProps = JSON.parse(rows.values().find((row) => row.includes("\"og:title\""))).filter((element) => element[1] === "meta").map((element) => element[3]);
const meta = (property) => metaProps.find((props) => props.property === property)?.content;
const title = meta("og:title");
const intro = meta("og:description");
const image = meta("og:image");
const description = renderDescription({
images: image ? [{
src: image,
alt: title
}] : void 0,
intro,
description: $$.html()
});
item.title = title;
item.description = description;
item.pubDate = parseDate(meta("article:published_time"));
item.category = metaProps.filter((props) => props.property === "article:tag").map((props) => props.content);
item.author = meta("article:author");
item.content = {
html: description,
text: intro
};
item.image = image;
item.banner = image;
item.updated = parseDate(meta("article:modified_time"));
return item;
})));
return {
title: $("title").text(),
description: $("meta[property=\"og:description\"]").prop("content"),
link: currentUrl,
item: items,
allowEmpty: true,
image: `${rootUrl}/favicon.ico`,
author: $("meta[property=\"og:site_name\"]").prop("content"),
language
};
}
const route = {
path: "/the-batch/:tag{.+}?",
name: "The Batch",
url: "www.deeplearning.ai",
maintainers: [
"nczitzk",
"juvenn",
"TonyRL"
],
handler,
example: "/deeplearning/the-batch",
parameters: { tag: "Tag, Weekly Issues by default" },
description: `::: tip
If you subscribe to [Data Points](https://www.deeplearning.ai/the-batch/tag/data-points/),where the URL is \`https://www.deeplearning.ai/the-batch/tag/data-points/\`, extract the part \`https://www.deeplearning.ai/the-batch/tag\` to the end, which is \`data-points\`, and use it as the parameter to fill in. Therefore, the route will be [\`/deeplearning/the-batch/data-points\`](https://rsshub.app/deeplearning/the-batch/data-points).
:::
| Tag | ID |
| ---------------------------------------------------------------------- | -------------------------------------------------------------------- |
| [Weekly Issues](https://www.deeplearning.ai/the-batch/) | [*null*](https://rsshub.app/deeplearning/the-batch) |
| [Andrew's Letters](https://www.deeplearning.ai/the-batch/tag/letters/) | [letters](https://rsshub.app/deeplearning/the-batch/letters) |
| [Data Points](https://www.deeplearning.ai/the-batch/tag/data-points/) | [data-points](https://rsshub.app/deeplearning/the-batch/data-points) |
| [ML Research](https://www.deeplearning.ai/the-batch/tag/research/) | [research](https://rsshub.app/deeplearning/the-batch/research) |
| [Business](https://www.deeplearning.ai/the-batch/tag/business/) | [business](https://rsshub.app/deeplearning/the-batch/business) |
| [Science](https://www.deeplearning.ai/the-batch/tag/science/) | [science](https://rsshub.app/deeplearning/the-batch/science) |
| [AI & Society](https://www.deeplearning.ai/the-batch/tag/ai-society/) | [ai-society](https://rsshub.app/deeplearning/the-batch/ai-society) |
| [Culture](https://www.deeplearning.ai/the-batch/tag/culture/) | [culture](https://rsshub.app/deeplearning/the-batch/culture) |
| [Hardware](https://www.deeplearning.ai/the-batch/tag/hardware/) | [hardware](https://rsshub.app/deeplearning/the-batch/hardware) |
| [AI Careers](https://www.deeplearning.ai/the-batch/tag/ai-careers/) | [ai-careers](https://rsshub.app/deeplearning/the-batch/ai-careers) |
#### [Letters from Andrew Ng](https://www.deeplearning.ai/the-batch/tag/letters/)
| Tag | ID |
| --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| [All](https://www.deeplearning.ai/the-batch/tag/letters/) | [letters](https://rsshub.app/deeplearning/the-batch/letters) |
| [Personal Insights](https://www.deeplearning.ai/the-batch/tag/personal-insights/) | [personal-insights](https://rsshub.app/deeplearning/the-batch/personal-insights) |
| [Technical Insights](https://www.deeplearning.ai/the-batch/tag/technical-insights/) | [technical-insights](https://rsshub.app/deeplearning/the-batch/technical-insights) |
| [Business Insights](https://www.deeplearning.ai/the-batch/tag/business-insights/) | [business-insights](https://rsshub.app/deeplearning/the-batch/business-insights) |
| [Tech & Society](https://www.deeplearning.ai/the-batch/tag/tech-society/) | [tech-society](https://rsshub.app/deeplearning/the-batch/tech-society) |
| [DeepLearning.AI News](https://www.deeplearning.ai/the-batch/tag/deeplearning-ai-news/) | [deeplearning-ai-news](https://rsshub.app/deeplearning/the-batch/deeplearning-ai-news) |
| [AI Careers](https://www.deeplearning.ai/the-batch/tag/ai-careers/) | [ai-careers](https://rsshub.app/deeplearning/the-batch/ai-careers) |
| [Just For Fun](https://www.deeplearning.ai/the-batch/tag/just-for-fun/) | [just-for-fun](https://rsshub.app/deeplearning/the-batch/just-for-fun) |
| [Learning & Education](https://www.deeplearning.ai/the-batch/tag/learning-education/) | [learning-education](https://rsshub.app/deeplearning/the-batch/learning-education) |`,
categories: ["programming"],
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportRadar: true,
supportBT: false,
supportPodcast: false,
supportScihub: false
},
radar: [
{
source: ["www.deeplearning.ai/the-batch", "www.deeplearning.ai/the-batch/tag/:tag/"],
target: (params) => {
const tag = params.tag;
return `/the-batch${tag ? `/${tag}` : ""}`;
}
},
{
title: "Weekly Issues",
source: ["www.deeplearning.ai/the-batch/"],
target: "/the-batch"
},
{
title: "Andrew's Letters",
source: ["www.deeplearning.ai/the-batch/tag/letters/"],
target: "/the-batch/letters"
},
{
title: "Data Points",
source: ["www.deeplearning.ai/the-batch/tag/data-points/"],
target: "/the-batch/data-points"
},
{
title: "ML Research",
source: ["www.deeplearning.ai/the-batch/tag/research/"],
target: "/the-batch/research"
},
{
title: "Business",
source: ["www.deeplearning.ai/the-batch/tag/business/"],
target: "/the-batch/business"
},
{
title: "Science",
source: ["www.deeplearning.ai/the-batch/tag/science/"],
target: "/the-batch/science"
},
{
title: "AI & Society",
source: ["www.deeplearning.ai/the-batch/tag/ai-society/"],
target: "/the-batch/ai-society"
},
{
title: "Culture",
source: ["www.deeplearning.ai/the-batch/tag/culture/"],
target: "/the-batch/culture"
},
{
title: "Hardware",
source: ["www.deeplearning.ai/the-batch/tag/hardware/"],
target: "/the-batch/hardware"
},
{
title: "AI Careers",
source: ["www.deeplearning.ai/the-batch/tag/ai-careers/"],
target: "/the-batch/ai-careers"
},
{
title: "Letters from Andrew Ng - All",
source: ["www.deeplearning.ai/the-batch/tag/letters/"],
target: "/the-batch/letters"
},
{
title: "Letters from Andrew Ng - Personal Insights",
source: ["www.deeplearning.ai/the-batch/tag/personal-insights/"],
target: "/the-batch/personal-insights"
},
{
title: "Letters from Andrew Ng - Technical Insights",
source: ["www.deeplearning.ai/the-batch/tag/technical-insights/"],
target: "/the-batch/technical-insights"
},
{
title: "Letters from Andrew Ng - Business Insights",
source: ["www.deeplearning.ai/the-batch/tag/business-insights/"],
target: "/the-batch/business-insights"
},
{
title: "Letters from Andrew Ng - Tech & Society",
source: ["www.deeplearning.ai/the-batch/tag/tech-society/"],
target: "/the-batch/tech-society"
},
{
title: "Letters from Andrew Ng - DeepLearning.AI News",
source: ["www.deeplearning.ai/the-batch/tag/deeplearning-ai-news/"],
target: "/the-batch/deeplearning-ai-news"
},
{
title: "Letters from Andrew Ng - AI Careers",
source: ["www.deeplearning.ai/the-batch/tag/ai-careers/"],
target: "/the-batch/ai-careers"
},
{
title: "Letters from Andrew Ng - Just For Fun",
source: ["www.deeplearning.ai/the-batch/tag/just-for-fun/"],
target: "/the-batch/just-for-fun"
},
{
title: "Letters from Andrew Ng - Learning & Education",
source: ["www.deeplearning.ai/the-batch/tag/learning-education/"],
target: "/the-batch/learning-education"
}
]
};
//#endregion
export { route };