UNPKG

rsshub

Version:
112 lines (111 loc) 4.18 kB
import { t as rofetch } from "./ofetch-W1aeTHCo.mjs"; import "./types-DNj6Etbg.mjs"; import { t as parseDate } from "./parse-date-CjhZE69i.mjs"; import { t as cache_default } from "./cache-CiDoUSLo.mjs"; import { load } from "cheerio"; import pMap from "p-map"; //#region lib/routes/rumble/channel.ts const rootUrl = "https://rumble.com"; const route = { path: "/c/:channel/:embed?", categories: ["multimedia"], view: 3, name: "Channel", maintainers: ["luckycold"], example: "/rumble/c/MikhailaPeterson", parameters: { channel: "Channel slug from `https://rumble.com/c/<channel>`", embed: "Default to not embed the video, set to `embed` to enable embedding" }, description: "Fetches full Rumble video descriptions without embedding the player by default.", features: { requireConfig: false, requirePuppeteer: false, antiCrawler: true, supportBT: false, supportPodcast: false, supportScihub: false }, radar: [{ source: ["rumble.com/c/:channel", "rumble.com/c/:channel/videos"], target: "/c/:channel" }], handler }; function parseDescription($, fallback) { return $("div[data-js=\"media_long_description_container\"] > p.media-description").toArray().map((element) => $.html(element)).filter(Boolean).join("") || $("meta[name=\"description\"]").attr("content") || fallback || void 0; } function parseStructuredVideoObject($) { const elements = $("script[type=\"application/ld+json\"]").toArray(); for (const element of elements) try { const parsed = JSON.parse($(element).text()); const videoObject = Array.isArray(parsed) ? parsed.find((item) => item?.["@type"] === "VideoObject") : parsed; if (videoObject?.["@type"] === "VideoObject") return videoObject; } catch { continue; } } function parseListVideos($) { const content = $("rum-videos-grid script[type=\"application/json\"]").text(); if (!content) return []; try { return JSON.parse(content).items; } catch { return []; } } function parseImage($, videoObject) { return videoObject?.thumbnailUrl || $("meta[property=\"og:image\"]").attr("content") || void 0; } function renderDescription(image, description, embedUrl, includeEmbed) { let descriptionHtml = ""; if (includeEmbed && embedUrl) descriptionHtml += `<iframe src="${embedUrl}" width="640" height="360" frameborder="0" allowfullscreen></iframe>`; else if (image) descriptionHtml += `<p><img src="${image}"></p>`; if (description) descriptionHtml += description; return descriptionHtml || void 0; } function getMedia(image) { return image ? { thumbnail: { url: image }, content: { url: image, medium: "image" } } : void 0; } async function buildItem(link, title, listImage, pubDate, includeEmbed) { const cookies = ((await rofetch.raw(link, { ignoreResponseError: true })).headers.getSetCookie?.() || []).map((cookie) => cookie.split(";", 1)[0]).join("; "); if (!cookies) throw new Error(`Failed to get Rumble page cookie from ${link}`); const $ = load(await rofetch(link, { headers: { Cookie: cookies } })); const videoObject = parseStructuredVideoObject($); const image = listImage || parseImage($, videoObject); return { title, image, link, description: renderDescription(image, parseDescription($, videoObject?.description), videoObject?.embedUrl, includeEmbed), itunes_item_image: image, media: getMedia(image), pubDate }; } async function handler(ctx) { const channel = ctx.req.param("channel"); const includeEmbed = ctx.req.param("embed") === "embed"; const videosUrl = `${new URL(`/c/${encodeURIComponent(channel)}`, rootUrl).href}/videos`; const $ = load(await rofetch(videosUrl)); const title = $("title").first().text() || "Rumble"; const items = await pMap(parseListVideos($), (video) => { const link = new URL(video.url || video.relative_url, rootUrl).href; const listImage = new URL(video.thumb, rootUrl).href; const pubDate = parseDate(video.upload_date); return cache_default.tryGet(`${link}:${includeEmbed ? "embed" : "noembed"}`, () => buildItem(link, video.title, listImage, pubDate, includeEmbed)); }, { concurrency: 5 }); return { title: `Rumble - ${title}`, link: videosUrl, item: items }; } //#endregion export { route };