UNPKG

rsshub

Version:
143 lines (141 loc) • 5.34 kB
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs"; import "./config-C37vj7VH.mjs"; import { t as ViewType } from "./types-D84BRIt4.mjs"; import "./dist-BInvbO1W.mjs"; import "./logger-Czu8UMNd.mjs"; import { t as ofetch_default } from "./ofetch-BIyrKU3Y.mjs"; import { t as parseDate } from "./parse-date-BrP7mxXf.mjs"; import { t as art } from "./render-BQo6B4tL.mjs"; import path from "node:path"; import { load } from "cheerio"; //#region lib/routes/scoop/apps.ts init_esm_shims(); const orderbys = (desc) => { const base = { 0: "search.score() desc, Metadata/OfficialRepositoryNumber desc, NameSortable asc", 1: "NameSortable asc, Metadata/OfficialRepositoryNumber desc, Metadata/RepositoryStars desc, Metadata/Committed desc", 2: "Metadata/Committed desc, Metadata/OfficialRepositoryNumber desc, Metadata/RepositoryStars desc" }; if (desc === "1") return base; const inverted = {}; for (const key in base) inverted[key] = base[key].replaceAll(/\b(desc|asc)\b/gi, (match) => match.toLowerCase() === "desc" ? "asc" : "desc"); return inverted; }; const filters = { o: "Metadata/OfficialRepositoryNumber eq 1", dm: "Metadata/DuplicateOf eq null" }; const handler = async (ctx) => { const { query = "s=2&d=1&n=true&dm=true&o=true" } = ctx.req.param(); const limit = Number.parseInt(ctx.req.query("limit") ?? "50", 10); const baseUrl = "https://scoop.sh"; const apiBaseUrl = "https://scoopsearch.search.windows.net"; const targetUrl = new URL(`/#/apps?${query}`, baseUrl).href; const apiUrl = new URL("indexes/apps/docs/search", apiBaseUrl).href; const targetResponse = await ofetch_default(targetUrl); const language = load(targetResponse)("html").attr("lang") ?? "en"; const scriptRegExp = /<script type="module" crossorigin src="(.*?)"><\/script>/; const scriptUrl = scriptRegExp.test(targetResponse) ? new URL(targetResponse.match(scriptRegExp)?.[1], baseUrl).href : ""; if (!scriptUrl) throw new Error("JavaScript file not found."); const key = (await ofetch_default(scriptUrl, { parseResponse: (txt) => txt })).match(/VITE_APP_AZURESEARCH_KEY:"(.*?)"/)?.[1]; if (!key) throw new Error("Key not found."); const isOffcial = !query.includes("o=false"); const isDistinct = !query.includes("dm=false"); const sort = query.match(/s=(\d+)/)?.[1] ?? "2"; const desc = query.match(/d=(\d+)/)?.[1] ?? "1"; const response = await ofetch_default(apiUrl, { method: "post", query: { "api-version": "2020-06-30" }, headers: { "api-key": key, origin: baseUrl, referer: baseUrl }, body: { count: true, search: "", searchMode: "all", filter: [isOffcial ? filters.o : void 0, isDistinct ? filters.dm : void 0].filter(Boolean).join(" and "), orderby: orderbys(desc)[sort], skip: 0, top: limit, select: "Id,Name,NamePartial,NameSuffix,Description,Notes,Homepage,License,Version,Metadata/Repository,Metadata/FilePath,Metadata/OfficialRepository,Metadata/RepositoryStars,Metadata/Committed,Metadata/Sha", highlight: "Name,NamePartial,NameSuffix,Description,Version,License,Metadata/Repository", highlightPreTag: "<mark>", highlightPostTag: "</mark>" } }); let items = []; items = response.value.slice(0, limit).map((item) => { const repositoryName = item.Metadata.Repository.split(/\//).slice(-2).join("/"); const title = `${item.Name} ${item.Version} in ${repositoryName}`; const description = art(path.join(__dirname, "templates/description-fe4e5583.art"), { item }); const pubDate = item.Metadata.Committed; const linkUrl = item.Homepage; const authors = [{ name: repositoryName, url: item.Metadata.Repository, avatar: void 0 }]; const guid = `scoop-${item.Name}-${item.Version}-${item.Metadata.Sha}`; const updated = pubDate; return { title, description, pubDate: pubDate ? parseDate(pubDate) : void 0, link: linkUrl, author: authors, guid, id: guid, content: { html: description, text: description }, updated: updated ? parseDate(updated) : void 0, language }; }); const author = "Scoop"; return { title: `${author} - Apps`, description: void 0, link: targetUrl, item: items, allowEmpty: true, author, language, id: targetUrl }; }; const route = { path: "/apps/:query?", name: "Apps", url: "scoop.sh", maintainers: ["nczitzk"], handler, example: "/scoop/apps", parameters: { query: { description: "Query, `s=2&d=1&n=true&dm=true&o=true` by default" } }, description: `::: tip To subscribe to [Apps](https://scoop.sh/#/apps?s=2&d=1&n=true&dm=true&o=true), where the source URL is \`https://scoop.sh/#/apps?s=2&d=1&n=true&dm=true&o=true\`, extract the certain parts from this URL to be used as parameters, resulting in the route as [\`/scoop/apps/s=2&d=1&n=true&dm=true&o=true\`](https://rsshub.app/scoop/apps/s=2&d=1&n=true&dm=true&o=true). :::`, categories: ["program-update"], features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportRadar: true, supportBT: false, supportPodcast: false, supportScihub: false }, radar: [{ source: ["scoop.sh/#/apps", "scoop.sh"], target: (_, url) => { const query = new URL(url).searchParams.toString() ?? void 0; return `/scoop/apps${query ? `/${query}` : ""}`; } }], view: ViewType.Notifications }; //#endregion export { handler, route };