rsshub
Version:
Make RSS Great Again!
99 lines (97 loc) • 4.22 kB
JavaScript
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs";
import "./config-C37vj7VH.mjs";
import "./dist-BInvbO1W.mjs";
import "./logger-Czu8UMNd.mjs";
import "./ofetch-BIyrKU3Y.mjs";
import { t as parseDate } from "./parse-date-BrP7mxXf.mjs";
import { t as cache_default } from "./cache-Bo__VnGm.mjs";
import "./helpers-DxBp0Pty.mjs";
import { t as art } from "./render-BQo6B4tL.mjs";
import { t as got_default } from "./got-KxxWdaxq.mjs";
import path from "node:path";
import { load } from "cheerio";
//#region lib/routes/transcriptforest/index.ts
init_esm_shims();
const bakeTimestamp = (seconds) => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor(seconds % 3600 / 60);
const remainingSeconds = Math.floor(seconds % 60);
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(remainingSeconds).padStart(2, "0")}`;
};
const route = {
path: "/:channel?",
radar: [{
source: ["www.transcriptforest.com/en/channel"],
target: ""
}],
name: "Unknown",
maintainers: ["nczitzk"],
handler,
url: "www.transcriptforest.com/en/channel"
};
async function handler(ctx) {
const channel = ctx.req.param("channel");
const limit = ctx.req.query("limit") ? Number.parseInt(ctx.req.query("limit"), 10) : 10;
const rootUrl = "https://www.transcriptforest.com";
const { data: firstResponse } = await got_default(rootUrl);
const data = JSON.parse(firstResponse.match(/({"props".*"scriptLoader":\[]})<\/script>/)?.[1]);
const buildId = data.buildId;
const defaultLocale = data.defaultLocale;
const channels = data.props.pageProps.listChannel;
const selected = channel ? channels.find((c) => c.channel_id === channel || c.channel_name === channel) : void 0;
const apiUrl = new URL(`_next/data/${buildId}/en${selected ? `/channel/${selected.channel_id}` : ""}.json`, rootUrl).href;
const currentUrl = new URL(selected ? `${defaultLocale}/channel/${selected.channel_id}` : "", rootUrl).href;
const { data: response } = await got_default(apiUrl, { searchParams: {
channelName: selected ? selected.channel_id : "",
offset: 0
} });
let items = response.pageProps.listEpisode.data.slice(0, limit).map((item) => ({
title: item.episode_name,
link: new URL(`${defaultLocale}/${item.channel_id}/${item.episode_id}`, rootUrl).href,
detailUrl: new URL(`_next/data/${buildId}/${defaultLocale}/${item.channel_id}/${item.episode_id}.json`, rootUrl).href,
description: art(path.join(__dirname, "templates/description-e0151c0f.art"), { texts: item.episode_description.split(/\n\n/).map((text) => ({ text })) }),
author: item.channel_name,
guid: item.id,
pubDate: parseDate(item.published_at),
updated: parseDate(item.updated_at),
itunes_item_image: item.episode_cover.split(/\?/)[0],
itunes_duration: item.episode_duration,
enclosure_url: item.source_media,
enclosure_type: "audio/mpeg"
}));
items = await Promise.all(items.map((item) => cache_default.tryGet(item.link, async () => {
const { data: detailResponse } = await got_default(item.detailUrl);
const { data: textResponse } = await got_default(detailResponse.pageProps.currentEpisode.ps4_url);
item.description = art(path.join(__dirname, "templates/description-e0151c0f.art"), { audios: [{
src: detailResponse.pageProps.currentEpisode.media,
type: "audio/mpeg"
}] }) + item.description + art(path.join(__dirname, "templates/description-e0151c0f.art"), { texts: textResponse.map((t) => ({
startTime: bakeTimestamp(t.startTime),
endTime: bakeTimestamp(t.endTime),
text: t.readOnlyText
})) });
delete item.detailUrl;
return item;
})));
const { data: currentResponse } = await got_default(currentUrl);
const $ = load(currentResponse);
const title = $("title").text();
const image = $("meta[property=\"og:image\"]").prop("content");
const icon = new URL($("link[rel=\"apple-touch-icon\"]").prop("href"), rootUrl).href;
const author = title.split(/\|/)[0].trim();
return {
item: items,
title,
link: currentUrl,
description: $("meta[name=\"description\"]").prop("content"),
language: $("html").prop("lang"),
image,
icon,
logo: icon,
author,
itunes_author: author,
allowEmpty: true
};
}
//#endregion
export { route };