UNPKG

rsshub

Version:
140 lines (136 loc) 4.38 kB
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 "./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/coomer/index.ts init_esm_shims(); const headers = { Accept: "text/css" }; const route = { path: "/:source?/:id?", categories: ["multimedia"], example: "/coomer", parameters: { source: "Source, see below, Posts by default", id: "User id, can be found in URL" }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false, nsfw: true }, radar: [{ source: ["coomer.st/"], target: "" }, { source: ["coomer.st/:source/user/:id"], target: "/:source/:id" }], name: "Posts", maintainers: ["nczitzk", "AiraNadih"], handler, description: `Sources | Posts | OnlyFans | Fansly | CandFans | | ----- | -------- | ------- | -------- | | posts | onlyfans | fansly | candfans | ::: tip When \`posts\` is selected as the value of the parameter **source**, the parameter **id** does not take effect. There is an optinal parameter **limit** which controls the number of posts to fetch, default value is 25. :::` }; async function handler(ctx) { const limit = ctx.req.query("limit") ? Number.parseInt(ctx.req.query("limit")) : 25; const source = ctx.req.param("source") ?? "posts"; const id = ctx.req.param("id"); const isPosts = source === "posts"; const rootUrl = "https://coomer.st"; const apiUrl = `${rootUrl}/api/v1`; const response = await got_default({ method: "get", url: isPosts ? `${apiUrl}/posts` : `${apiUrl}/${source}/user/${id}/posts`, headers }); const responseData = isPosts ? response.data.posts : response.data; const author = isPosts ? "" : await getAuthor(`${apiUrl}/${source}/user/${id}`); const title = isPosts ? "Coomer Posts" : `Posts of ${author} from ${source} | Coomer`; const image = isPosts ? `${rootUrl}/favicon.ico` : `https://img.coomer.st/icons/${source}/${id}`; const items = responseData.filter((i) => i.content || i.attachments).slice(0, limit).map((i) => { i.files = []; if ("path" in i.file) i.files.push({ name: i.file.name, path: i.file.path, extension: i.file.path.replace(/.*\./, "").toLowerCase() }); for (const attachment of i.attachments) i.files.push({ name: attachment.name, path: attachment.path, extension: attachment.path.replace(/.*\./, "").toLowerCase() }); let $ = load(art(path.join(__dirname, "templates/source-8cc27d8b.art"), { i })); const coomerFiles = $("img, a, audio, video").map(function() { return $(this).prop("outerHTML"); }); let desc = ""; if (i.content) desc += `<div>${i.content}</div>`; $ = load(desc); let count = 0; const regex = /downloads.fanbox.cc/; $("a").each(function() { const link = $(this).attr("href"); if (regex.test(link)) { count++; $(this).replaceWith(coomerFiles[count]); } }); desc = (coomerFiles.length > 0 ? coomerFiles[0] : "") + $.html(); for (const coomerFile of coomerFiles.slice(count + 1)) desc += coomerFile; let enclosureInfo = {}; load(desc)("audio source, video source").each(function() { const src = $(this).attr("src") ?? ""; const mimeType = { m4a: "audio/mp4", mp3: "audio/mpeg", mp4: "video/mp4" }[src.replace(/.*\./, "").toLowerCase()] || null; if (mimeType === null) return; enclosureInfo = { enclosure_url: new URL(src, rootUrl).toString(), enclosure_type: mimeType }; }); return { title: i.title || parseDate(i.published), description: desc, author, pubDate: parseDate(i.published), guid: `coomer:${i.service}:${i.user}:post:${i.id}`, link: `${rootUrl}/${i.service}/user/${i.user}/post/${i.id}`, ...enclosureInfo }; }); return { title, image, link: isPosts ? `${rootUrl}/posts` : `${rootUrl}/${source}/user/${id}`, item: items }; } async function getAuthor(currentUrl) { return (await got_default({ method: "get", url: `${currentUrl}/profile`, headers })).data.name; } //#endregion export { route };