UNPKG

rsshub

Version:
150 lines (132 loc) • 7.12 kB
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs"; import { t as config } from "./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/osu/beatmaps/latest-ranked.ts init_esm_shims(); const descriptionDoc = ` Subscribe to the new beatmaps on https://osu.ppy.sh/beatmapsets. #### Parameter Description Parameters allows you to: - Filter game mode - Limit beatmap difficulty - Show/hide game mode in feed title Below is a table of all allowed parameters passed to \`routeParams\` | Name | Default | Description | | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | \`includeMode\` | All mode | Could be \`osu\`, \`mania\`, \`fruits\` or \`taiko\`. Specify included game mode of beatmaps. Including this paramseter multiple times to specify multiple game modes, e.g.: \`includeMode=osu&includeMode=mania\`. Subscribe to all game modes if not specified | | \`difficultyLimit\` | None | Lower/upper limit of star rating of the beatmaps in the beatmapset item, e.g.:\`difficultyLimit=U6\`. Checkout tips in descriptions for detailed explaination and examples. | | \`modeInTitle\` | \`true\` | \`true\` or \`false\` Add mode info into feed title. This actual parameters should be passed as \`routeParams\` in URL Query String format without \`?\`, e.g.: /osu/latest-ranked/modeInTitle=true&includeMode=osu ::: tip You could make use of \`difficultyLimit\` paramters to create a "high difficulty/low difficulty only" only feed. For example, if you only wants to play low star rating beatmap like 1 or 2 star, you could subscribe to: /osu/latest-ranked/difficultyLimit=U2 This will filter out all beatmapsets that do not provide at least one beatmap with star rating<=\`2.00\`. Similarly, you could use lower bound to filter out beatmapsets which don't have at least one beatmap with star rating higher than a certain threshold. /osu/latest-ranked/difficultyLimit=L6 Now all beatmapsets that don't provided at least one beatmap with star rating higher than \`6.00\` will be filtered. :::`; const route = { path: "/latest-ranked/:routeParams?", categories: ["game"], example: "/osu/latest-ranked/includeMode=osu&difficultyLimit=L3&difficultyLimit=U7", features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false, supportRadar: true }, parameters: { routeParams: { description: "Used to pass route parameters in Query String format. Check out route description for more info.", default: "null" } }, name: "Latest Ranked Beatmap", description: descriptionDoc, maintainers: ["nfnfgo"], radar: [{ source: ["osu.ppy.sh/beatmapsets"] }], handler }; async function handler(ctx) { const pathParams = ctx.req.param("routeParams"); const searchParams = new URL(`https://osu.ppy.sh?${pathParams}`).searchParams; const includeModes = searchParams.getAll("includeMode"); const difficultyLimits = searchParams.getAll("difficultyLimit"); const modeInTitle = searchParams.get("modeInTitle") ?? "true"; let beatmapsetList = await cache_default.tryGet("https://osu.ppy.sh/beatmapsets:JSON", async () => { const $ = load((await got_default.get("https://osu.ppy.sh/beatmapsets")).data); const beatmapList = JSON.parse($("#json-beatmaps").text() ?? "{\"beatmapsets\": undefined}").beatmapsets; if (beatmapList === void 0) throw new Error("Failed to retrieve JSON beatmap info from osu! website"); return beatmapList; }, config.cache.routeExpire, false); for (const item of beatmapsetList) item.beatmaps.sort((a, b) => a.difficulty_rating - b.difficulty_rating); if (includeModes?.length && includeModes?.length > 0) beatmapsetList = beatmapsetList.filter((bm) => includeModes.includes(bm.beatmaps[0].mode)); let upperLimit = 99; let lowerLimit = 0; if (difficultyLimits && difficultyLimits.length > 0 && difficultyLimits.length < 2) { for (const dfLimit of difficultyLimits) if (dfLimit.startsWith("U")) upperLimit = Number.parseFloat(dfLimit.slice(1)); else if (dfLimit.startsWith("L")) lowerLimit = Number.parseFloat(dfLimit.slice(1)); const difficultyRateFilterFunc = (item) => { if (item.beatmaps.at(0).difficulty_rating > upperLimit) return false; if (item.beatmaps.at(-1).difficulty_rating < lowerLimit) return false; return true; }; beatmapsetList = beatmapsetList.filter((item) => difficultyRateFilterFunc(item)); } function getReadableFeedConfig() { if (!pathParams) return ""; let readableConf = "Feed Configurations:\n"; readableConf += `Game Mode: ${includeModes.length > 0 ? JSON.stringify(includeModes) : "All modes"}\n`; readableConf += `Star Rating Limit: Lower=${lowerLimit}, Upper=${upperLimit}`; return readableConf; } const rssItems = beatmapsetList.map((beatmapset) => { const pubDate = parseDate(beatmapset.ranked_date); const coverImage = beatmapset.covers["cover@2x"] || beatmapset.covers.cover; const bannerImage = beatmapset.covers["card@2x"] || beatmapset.covers.card; const readableTotalLength = `${Math.floor(beatmapset.beatmaps[0].total_length / 60).toString().padStart(2, "0")}:${(beatmapset.beatmaps[0].total_length % 60).toString().padStart(2, "0")}`; const modeLiteralToDisplayNameMap = { osu: "Osu!", fruits: "Osu!Catch", taiko: "Osu!Taiko", mania: "Osu!Mania" }; const description = art(path.join(__dirname, "templates/beatmapset-d6071e15.art"), { ...beatmapset, readableTotalLength, modeLiteralToDisplayNameMap }); return { title: `${modeInTitle === "true" ? `[${modeLiteralToDisplayNameMap[beatmapset.beatmaps[0].mode]}] ` : ``}${beatmapset.title_unicode ?? beatmapset.title}`, description, pubDate, link: `https://osu.ppy.sh/beatmapsets/${beatmapset.id}`, category: ["osu!", "game"], author: [{ name: beatmapset.creator }], image: coverImage, banner: bannerImage, updated: beatmapset.last_updated }; }); return { title: "Osu! Latest Ranked Map", link: "https://osu.ppy.sh/beatmapsets", description: `Newly ranked beatmaps at https://osu.ppy.sh/beatmapsets.\n${getReadableFeedConfig()}`, item: rssItems }; } //#endregion export { route };