mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-08-09 23:16:32 +08:00
fix: 🐛 badge requestedDuration
This commit is contained in:
@@ -11,7 +11,17 @@ const { R } = require("redbean-node");
|
||||
const apicache = require("../modules/apicache");
|
||||
const Monitor = require("../model/monitor");
|
||||
const dayjs = require("dayjs");
|
||||
const { UP, MAINTENANCE, DOWN, PENDING, flipStatus, log, badgeConstants } = require("../../src/util");
|
||||
const {
|
||||
UP,
|
||||
MAINTENANCE,
|
||||
DOWN,
|
||||
PENDING,
|
||||
flipStatus,
|
||||
log,
|
||||
badgeConstants,
|
||||
durationUnits,
|
||||
isNumeric,
|
||||
} = require("../../src/util");
|
||||
const StatusPage = require("../model/status_page");
|
||||
const { UptimeKumaServer } = require("../uptime-kuma-server");
|
||||
const { makeBadge } = require("badge-maker");
|
||||
@@ -232,6 +242,11 @@ router.get("/api/badge/:id/uptime/:duration?", cache("5 minutes"), async (reques
|
||||
let requestedDuration = request.params.duration !== undefined ? request.params.duration : "24";
|
||||
const overrideValue = value && parseFloat(value);
|
||||
|
||||
if (isNumeric(requestedDuration)) { // all numeric only
|
||||
requestedDuration = `${requestedDuration}${durationUnits.HOUR}`;
|
||||
}
|
||||
const duration = requestedDuration.slice(0, -1);
|
||||
|
||||
let publicMonitor = await R.getRow(`
|
||||
SELECT monitor_group.monitor_id FROM monitor_group, \`group\`
|
||||
WHERE monitor_group.group_id = \`group\`.id
|
||||
@@ -249,7 +264,7 @@ router.get("/api/badge/:id/uptime/:duration?", cache("5 minutes"), async (reques
|
||||
badgeValues.color = badgeConstants.naColor;
|
||||
} else {
|
||||
const uptimeCalculator = await UptimeCalculator.getUptimeCalculator(requestedMonitorId);
|
||||
const uptime = overrideValue ?? uptimeCalculator.getDataByDuration(`${requestedDuration}h`).uptime;
|
||||
const uptime = overrideValue ?? uptimeCalculator.getDataByDuration(requestedDuration).uptime;
|
||||
|
||||
// limit the displayed uptime percentage to four (two, when displayed as percent) decimal digits
|
||||
const cleanUptime = (uptime * 100).toPrecision(4);
|
||||
@@ -261,7 +276,7 @@ router.get("/api/badge/:id/uptime/:duration?", cache("5 minutes"), async (reques
|
||||
// build a label string. If a custom label is given, override the default one (requestedDuration)
|
||||
badgeValues.label = filterAndJoin([
|
||||
labelPrefix,
|
||||
label ?? `Uptime (${requestedDuration}${labelSuffix})`,
|
||||
label ?? `Uptime (${duration}${labelSuffix})`,
|
||||
]);
|
||||
badgeValues.message = filterAndJoin([ prefix, cleanUptime, suffix ]);
|
||||
}
|
||||
@@ -298,13 +313,17 @@ router.get("/api/badge/:id/ping/:duration?", cache("5 minutes"), async (request,
|
||||
let requestedDuration = request.params.duration !== undefined ? request.params.duration : "24";
|
||||
const overrideValue = value && parseFloat(value);
|
||||
|
||||
if (isNumeric(requestedDuration)) { // all numeric only
|
||||
requestedDuration = `${requestedDuration}${durationUnits.HOUR}`;
|
||||
}
|
||||
const duration = requestedDuration.slice(0, -1);
|
||||
|
||||
// Check if monitor is public
|
||||
|
||||
const uptimeCalculator = await UptimeCalculator.getUptimeCalculator(requestedMonitorId);
|
||||
const publicAvgPing = uptimeCalculator.getDataByDuration(`${requestedDuration}h`).avgPing;
|
||||
const publicAvgPing = uptimeCalculator.getDataByDuration(requestedDuration).avgPing;
|
||||
|
||||
const badgeValues = { style };
|
||||
|
||||
if (!publicAvgPing) {
|
||||
// return a "N/A" badge in naColor (grey), if monitor is not public / not available / non exsitant
|
||||
|
||||
@@ -317,7 +336,7 @@ router.get("/api/badge/:id/ping/:duration?", cache("5 minutes"), async (request,
|
||||
// use a given, custom labelColor or use the default badge label color (defined by badge-maker)
|
||||
badgeValues.labelColor = labelColor ?? "";
|
||||
// build a lable string. If a custom label is given, override the default one (requestedDuration)
|
||||
badgeValues.label = filterAndJoin([ labelPrefix, label ?? `Avg. Ping (${requestedDuration}${labelSuffix})` ]);
|
||||
badgeValues.label = filterAndJoin([ labelPrefix, label ?? `Avg. Ping (${duration}${labelSuffix})` ]);
|
||||
badgeValues.message = filterAndJoin([ prefix, avgPing, suffix ]);
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,12 @@
|
||||
const dayjs = require("dayjs");
|
||||
const { UP, MAINTENANCE, DOWN, PENDING } = require("../src/util");
|
||||
const {
|
||||
UP,
|
||||
MAINTENANCE,
|
||||
DOWN,
|
||||
PENDING,
|
||||
durationUnits,
|
||||
isNumeric
|
||||
} = require("../src/util");
|
||||
const { LimitQueue } = require("./utils/limit-queue");
|
||||
const { log } = require("../src/util");
|
||||
const { R } = require("redbean-node");
|
||||
@@ -543,7 +550,9 @@ class UptimeCalculator {
|
||||
if (type === "minute" && num > 24 * 60) {
|
||||
throw new Error("The maximum number of minutes is 1440");
|
||||
}
|
||||
|
||||
if (type === "day" && num > 365) {
|
||||
throw new Error("The maximum number of days is 365");
|
||||
}
|
||||
// Get the current time period key based on the type
|
||||
let key = this.getKey(this.getCurrentDate(), type);
|
||||
|
||||
@@ -742,24 +751,36 @@ class UptimeCalculator {
|
||||
|
||||
/**
|
||||
* Get the uptime data for given duration.
|
||||
* @param {string} duration A string with a number and a unit (h, d, or y), such as 24h, 30d, 1y.
|
||||
* @param {string} duration A string with a number and a unit (m,h,d,w,M,y), such as 24h, 30d, 1y.
|
||||
* @returns {UptimeDataResult} UptimeDataResult
|
||||
* @throws {Error} Invalid duration
|
||||
* @throws {Error} Invalid duration / Unsupported unit
|
||||
*/
|
||||
getDataByDuration(duration) {
|
||||
const unit = duration.substring(duration.length - 1);
|
||||
const num = parseInt(duration.substring(0, duration.length - 1));
|
||||
const durationNumStr = duration.slice(0, -1);
|
||||
|
||||
const typeMap = {
|
||||
h: "hour",
|
||||
d: "day",
|
||||
y: "year"
|
||||
};
|
||||
|
||||
if (!Object.keys(typeMap).includes(unit)) {
|
||||
throw new Error("Invalid duration");
|
||||
if (!isNumeric(durationNumStr)) {
|
||||
throw new Error(`Invalid duration: ${duration}`);
|
||||
}
|
||||
const num = Number(durationNumStr);
|
||||
const unit = duration.slice(-1);
|
||||
|
||||
switch (unit) {
|
||||
case durationUnits.MINUTE:
|
||||
return this.getData(num, "minute");
|
||||
case durationUnits.HOUR:
|
||||
return this.getData(num, "hour");
|
||||
case durationUnits.DAY:
|
||||
return this.getData(num, "day");
|
||||
case durationUnits.WEEK:
|
||||
return this.getData(7 * num, "day");
|
||||
case durationUnits.MONTH:
|
||||
return this.getData(30 * num, "day");
|
||||
case durationUnits.YEAR:
|
||||
return this.getData(365 * num, "day");
|
||||
default:
|
||||
throw new Error(`Unsupported unit (${unit}) for badge duration ${duration}`
|
||||
);
|
||||
}
|
||||
return this.getData(num, typeMap[unit]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user