rsshub
Version:
Make RSS Great Again!
170 lines (165 loc) • 6.38 kB
JavaScript
import "./dist-Bog6z_OM.mjs";
import "./config-MQ-7ebJ_.mjs";
import "./logger-C4avouvV.mjs";
import { t as ofetch_default } from "./ofetch-DKl_Ma9g.mjs";
import "./is-worker-DESPicPc.mjs";
import { t as cache_default } from "./cache-SV6W5EPy.mjs";
import { t as rss_parser_default } from "./rss-parser-Cnh4NKwh.mjs";
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
import { load } from "cheerio";
import { renderToString } from "hono/jsx/dom/server";
//#region lib/routes/bbc/utils.tsx
const processImageAttributes = ($img) => {
if (!$img.attr("src") && $img.attr("srcSet")) {
const lastSrc = $img.attr("srcSet").split(", ").at(-1);
if (lastSrc) $img.attr("src", lastSrc.split(" ")[0]);
}
$img.removeAttr("srcset").removeAttr("sizes");
};
const buildCleanFigure = (src, alt, figcaptionContent) => renderToString(/* @__PURE__ */ jsxs("figure", { children: [/* @__PURE__ */ jsx("img", {
src,
alt,
referrerpolicy: "no-referrer"
}), figcaptionContent && /* @__PURE__ */ jsx("figcaption", { children: figcaptionContent })] }));
const cleanFigureElement = ($, figure) => {
const $figure = $(figure);
const $img = $figure.find("img");
if ($img.length === 0) return;
processImageAttributes($img);
let sourceText = "";
let captionText = "";
const $sourceP = $figure.find("p[class*=\"css-\"]").first();
if ($sourceP.length > 0) {
const sourceSpans = $sourceP.find("span");
if (sourceSpans.length >= 2) sourceText = sourceSpans.eq(1).text().trim();
}
let $figcaption = $figure.find("figcaption");
if ($figcaption.length === 0) {
const $next = $figure.next();
if ($next.length > 0) {
$figcaption = $next.find("figcaption");
if ($figcaption.length > 0) $next.remove();
}
}
if ($figcaption.length > 0) {
const $captionParagraph = $figcaption.find("[data-testid=\"caption-paragraph\"]");
if ($captionParagraph.length > 0) captionText = $captionParagraph.text().trim();
else {
const $figcaptionClone = $figcaption.clone();
$figcaptionClone.find(".visually-hidden, [class*=\"VisuallyHidden\"]").remove();
captionText = $figcaptionClone.text().trim();
}
}
const figcaptionContent = [sourceText, captionText].filter(Boolean).join(" / ");
$figure.replaceWith(buildCleanFigure($img.attr("src"), $img.attr("alt") || "", figcaptionContent));
};
const ProcessFeed = ($) => {
let content = $("#main-content article");
if (content.length === 0) content = $("div.story-body");
if (content.length === 0) content = $("main[role=\"main\"]");
content.find("header, section, [data-testid=\"bbc-logo-wrapper\"]").remove();
content.find("h1").remove();
content.find("noscript").each((i, e) => {
$(e).parent().html($(e).html());
});
content.find("figure").each((i, figure) => cleanFigureElement($, figure));
content.find("img").not("figure img").each((i, img) => {
const $img = $(img);
processImageAttributes($img);
const $next = $img.next();
if ($next.length > 0 && $next.find("figcaption").length > 0) {
const captionText = $next.find("figcaption").first().text().trim();
if (captionText) {
$img.replaceWith(buildCleanFigure($img.attr("src"), $img.attr("alt") || "", captionText));
$next.remove();
}
}
});
content.find("[data-component=\"media-block\"] figcaption").prepend("<span>View video in browser: </span>");
return content.html();
};
var utils_default = { ProcessFeed };
//#endregion
//#region lib/routes/bbc/index.ts
const route = {
path: "/:site?/:channel?",
name: "News",
maintainers: [
"HenryQW",
"DIYgod",
"pseudoyu"
],
handler,
example: "/bbc/world-asia",
parameters: {
site: "语言,简体或繁体中文",
channel: "channel, default to `top stories`"
},
categories: ["traditional-media"],
description: `Provides a better reading experience (full text articles) over the official ones.
Support major channels, refer to [BBC RSS feeds](https://www.bbc.co.uk/news/10628494). Eg, \`business\` for \`https://feeds.bbci.co.uk/news/business/rss.xml\`.
- Channel contains sub-directories, such as \`https://feeds.bbci.co.uk/news/world/asia/rss.xml\`, replace \`/\` with \`-\`, \`/bbc/world-asia\`.`
};
async function handler(ctx) {
let feed, title, link;
const { site, channel } = ctx.req.param();
if (site) switch (site.toLowerCase()) {
case "chinese":
title = "BBC News 中文网";
feed = await (channel ? rss_parser_default.parseURL(`https://www.bbc.co.uk/zhongwen/simp/${channel}/index.xml`) : rss_parser_default.parseURL("https://www.bbc.co.uk/zhongwen/simp/index.xml"));
break;
case "traditionalchinese":
title = "BBC News 中文網";
feed = await (channel ? rss_parser_default.parseURL(`https://www.bbc.co.uk/zhongwen/trad/${channel}/index.xml`) : rss_parser_default.parseURL("https://www.bbc.co.uk/zhongwen/trad/index.xml"));
link = "https://www.bbc.com/zhongwen/trad";
break;
default:
feed = await rss_parser_default.parseURL(`https://feeds.bbci.co.uk/news/${site.split("-").join("/")}/rss.xml`);
title = `BBC News ${site}`;
link = `https://www.bbc.co.uk/news/${site.split("-").join("/")}`;
break;
}
else {
feed = await rss_parser_default.parseURL("https://feeds.bbci.co.uk/news/rss.xml");
title = "BBC News Top Stories";
link = "https://www.bbc.co.uk/news";
}
const items = await Promise.all(feed.items.filter((item) => item && item.link).map((item) => cache_default.tryGet(item.link, async () => {
try {
const linkURL = new URL(item.link);
if (linkURL.hostname === "www.bbc.com") linkURL.hostname = "www.bbc.co.uk";
const $ = load(await ofetch_default(linkURL.href, { retryStatusCodes: [403] }));
const path = linkURL.pathname;
let description;
switch (true) {
case path.startsWith("/sport"):
description = item.content;
break;
case path.startsWith("/sounds/play"):
description = item.content;
break;
case path.startsWith("/news/live"):
description = item.content;
break;
default: description = utils_default.ProcessFeed($);
}
return {
title: item.title || "",
description: description || "",
pubDate: item.pubDate || (/* @__PURE__ */ new Date()).toUTCString(),
link: item.link
};
} catch {
return {};
}
})));
return {
title,
link,
image: "https://www.bbc.com/favicon.ico",
description: title,
item: items.filter((item) => Object.keys(item).length > 0)
};
}
//#endregion
export { route };