UNPKG

rsshub

Version:
100 lines (96 loc) 4.34 kB
import { t as rofetch } from "./ofetch-C3ts-Hud.mjs"; import { t as parseDate } from "./parse-date-Cr0wQjV_.mjs"; import { t as cache_default } from "./cache-BkqOokyU.mjs"; import { load } from "cheerio"; //#region lib/routes/rfa/index.ts const route = { path: "/:language?/:channel?/:subChannel?", categories: ["traditional-media"], example: "/rfa/english", parameters: { language: "language, English by default", channel: "channel", subChannel: "subchannel, where applicable" }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false }, name: "News", maintainers: ["zphw"], handler, description: `Delivers a better experience by supporting parameter specification. Parameters can be obtained from the official website, for instance: \`https://www.rfa.org/cantonese\` corresponds to \`/rfa/cantonese\` \`https://www.rfa.org/cantonese/htm\` corresponds to \`/rfa/cantonese/htm\`` }; const renderElement = (element) => { switch (element.type) { case "text": return `<p>${element.content}</p>`; case "header": return `<h${element.level ?? 2}>${element.content}</h${element.level ?? 2}>`; case "divider": return "<hr>"; case "image": return `<figure><img src="${element.url}" alt="${element.alt_text ?? ""}">${element.caption ? `<figcaption>${element.caption}</figcaption>` : ""}</figure>`; case "video": { const stream = element.streams?.find((s) => s.stream_type === "mp4"); return stream ? `<figure><video controls src="${stream.url}" poster="${element.promo_image?.url ?? ""}"></video>${element.headlines?.basic ? `<figcaption>${element.headlines.basic}</figcaption>` : ""}</figure>` : ""; } case "oembed_response": return element.raw_oembed?.html ?? ""; case "list": { const tag = element.list_type === "ordered" ? "ol" : "ul"; return `<${tag}>${element.items.map((el) => `<li>${el.content}</li>`).join("")}</${tag}>`; } case "gallery": return element.content_elements.map((el) => renderElement(el)).join(""); case "quote": return `<blockquote>${element.content_elements.map((el) => renderElement(el)).join("")}${element.citation?.content ? `<cite>${element.citation.content}</cite>` : ""}</blockquote>`; case "raw_html": return element.content; case "custom_embed": return ""; default: throw new Error(`Unsupported element type: ${element.type}`); } }; async function handler(ctx) { const { language = "english", channel, subChannel } = ctx.req.param(); const baseUrl = "https://www.rfa.org"; const link = `${baseUrl}/${[ language, channel, subChannel ].filter(Boolean).join("/")}/`; const response = await rofetch(link); const $ = load(response); const contentCache = JSON.parse(response.match(/Fusion\.contentCache=(\{.*?\});Fusion\.layout/)?.[1] ?? "{}"); const list = new Map(Object.values(contentCache["content-api-collections"] ?? {}).flatMap((entry) => entry.data?.content_elements ?? []).map((story) => [story._id, story])).values().toArray().map((story) => { const website = Object.values(story.websites)[0]; return { title: story.headlines.basic, description: story.description.basic, link: new URL(website.website_url, baseUrl).href, pubDate: parseDate(story.display_date), author: story.credits?.by?.map((author) => author.name).join(", "), category: website.website_section?.name, image: story.promo_items.basic.url }; }); const items = await Promise.all(list.map((item) => cache_default.tryGet(item.link, async () => { const response = await rofetch(item.link); const globalContent = JSON.parse(response.match(/Fusion\.globalContent=(\{.*?\});Fusion\.globalContentConfig/)?.[1] ?? "{}"); if (globalContent.content_elements) item.description = [globalContent.promo_items?.basic, ...globalContent.content_elements].filter(Boolean).map((element) => renderElement(element)).join(""); item.category = [...new Set([ item.category, ...globalContent.taxonomy?.sections?.map((section) => section.name) ?? [], ...globalContent.taxonomy?.tags?.map((tag) => tag.text) ?? [] ].filter(Boolean))]; return item; }))); return { title: $("head title").text(), link, image: $("meta[name=\"og:image\"]").attr("content"), language: $("html").attr("lang"), item: items }; } //#endregion export { route };