UNPKG

rsshub

Version:
77 lines (73 loc) 3.13 kB
import { t as rofetch } from "./ofetch-C3ts-Hud.mjs"; import { t as config } from "./config-CCmw1BNE.mjs"; import { t as parseDate } from "./parse-date-Cr0wQjV_.mjs"; import { t as processContent } from "./utils-BXldxNVQ.mjs"; import { load } from "cheerio"; //#region lib/routes/f95zone/thread.ts const route = { path: "/thread/:thread", name: "Thread", maintainers: ["wsmbsbbz"], example: "/f95zone/thread/ubermation-collection-2026-01-19-uebermation-uebermation.231247", categories: ["game"], description: `Track replies in a thread. Fetches the first page and the last page. URL format: \`https://f95zone.to/threads/{thread}/\` → use \`{thread}\` as the parameter. Example: \`https://f95zone.to/threads/ubermation-collection-2026-01-19-uebermation-uebermation.231247/\` → \`/f95zone/thread/ubermation-collection-2026-01-19-uebermation-uebermation.231247\` Note: If you want to track a specific post's content changes (e.g., first post with download links), use the \`/f95zone/post\` route instead.`, parameters: { thread: "Thread slug with ID, copy from browser URL after `/threads/`" }, features: { requireConfig: [{ name: "F95ZONE_COOKIE", optional: true, description: "F95zone cookie for accessing restricted content." }], requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false, nsfw: true }, radar: [{ source: ["f95zone.to/threads/:thread/*"], target: "/thread/:thread" }], handler: async (ctx) => { const { thread } = ctx.req.param(); const threadLink = `https://f95zone.to/threads/${thread}/`; const headers = { ...config.f95zone.cookie && { cookie: config.f95zone.cookie } }; const $firstPage = load(await rofetch(threadLink, { headers })); const title = $firstPage("h1.p-title-value").text(); const lastPageLink = $firstPage("ul.pageNav-main li.pageNav-page:last-child a").attr("href"); const totalPages = lastPageLink ? Number(lastPageLink.match(/page-(\d+)/)?.[1] || "1") : 1; const extractPosts = ($) => $("article.message").toArray().map((article) => { const $article = $(article); const postId = $article.attr("data-content")?.replace("post-", ""); if (!postId) return; const author = $article.find(".message-name a").text(); const postDate = $article.find("time.u-dt").attr("datetime"); const content = $article.find(".bbWrapper").html() || ""; const postLink = `${threadLink}post-${postId}`; return { title: `#${$article.find(".message-attribution-opposite--list li:last-child a").text().trim().replace("#", "") || postId} by ${author}`, link: postLink, guid: postLink, description: processContent(content), pubDate: postDate ? parseDate(postDate) : void 0, author }; }).filter(Boolean); const allPosts = [...extractPosts($firstPage)]; if (totalPages > 1) { const lastPageResponse = await rofetch(`${threadLink}page-${totalPages}`, { headers }); allPosts.push(...extractPosts(load(lastPageResponse))); } return { title: `[F95zone] ${title}`, link: threadLink, item: allPosts }; } }; //#endregion export { route };