XClaim Stats Endpoint

node v18.11.0
version: 1.0.0
endpointsharetweet
const needle = require("needle"); const userAgent = "xc-stats; [email protected]"; const getJSON = ((url, gh) => { let headers = { "User-Agent": userAgent }; if (!!gh) { headers["Accept"] = "application/vnd.github+json"; headers["X-GitHub-Api-Version"] = "2022-11-28"; } return needle("get", url, { json: true, headers: headers }).then((res) => res.body); }); // type Stats = { downloads: number, stars: number } async function getStatsHangar() { const body = await getJSON("https://hangar.papermc.io/api/v1/projects/XClaim"); let { downloads, stars } = body["stats"]; if (typeof downloads !== "number") downloads = parseInt(downloads); if (typeof stars !== "number") stars = parseInt(stars); return { downloads, stars }; } async function getStatsSpigot() { const body = await getJSON("https://api.spiget.org/v2/resources/102843"); let { downloads, reviews } = body; if (typeof downloads !== "number") downloads = parseInt(downloads); let stars = 0; let len; if (Array.isArray(reviews) && (len = Math.min(reviews.length, 100)) > 0) { const detail = await getJSON("https://api.spiget.org/v2/resources/102843/reviews?size=" + len + "&page=0&fields=rating") for (let i=0; i < detail.length; i++) { stars += detail[i]["rating"]["average"]; } stars /= detail.length; } return { downloads, stars }; } const JAR_MIME_TYPES = { "application/x-java-archive": true, "application/java-archive": true }; async function getStatsGithub() { // I sure would prefer to not use the search API for this. Whatever. const body = await getJSON("https://api.github.com/search/repositories?q=WasabiThumb%2Fxclaim"); const item = body["items"][0]; let stars = item["stargazers_count"]; if (typeof stars !== "number") stars = parseInt(stars); const releasesBody = await getJSON("https://api.github.com/repos/WasabiThumb/xclaim/releases"); let downloads = 0; for (let i=0; i < releasesBody.length; i++) { let assets = releasesBody[i]["assets"]; if (!Array.isArray(assets)) continue; for (let asset of assets) { if (!JAR_MIME_TYPES[asset["content_type"]]) continue; let name = asset["name"]; if (typeof name !== "string") continue; if (name.startsWith("original")) continue; downloads += parseInt(asset["download_count"]); } } return { downloads, stars }; } const statFunctions = [ getStatsSpigot, getStatsGithub, getStatsHangar ]; async function getStats() { let promises = new Array(statFunctions.length); for (let i=0; i < statFunctions.length; i++) { promises[i] = statFunctions[i](); } let totalDownloads = 0; let totalStars = 0; const data = await Promise.allSettled(promises); for (let entry of data) { if (entry.status !== "fulfilled") continue; let { downloads, stars } = entry.value; if (!isNaN(downloads)) totalDownloads += downloads; if (!isNaN(stars)) totalStars += stars; } return { downloads: totalDownloads, stars: Math.round(totalStars) }; } exports.endpoint = async function (request, response) { let key = "Downloads"; if (request.url.toLowerCase().indexOf("stars") !== -1) key = "Stars"; const data = await getStats(); const metric = data[key.toLowerCase()]; response.end(JSON.stringify({ "schemaVersion": 1, "label": key, "message": metric.toString(), "color": "informational" })); }
Loading…

no comments

    sign in to comment