mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-30 18:24:03 +00:00
Implement generateTimeslot() for recurring interval type
This commit is contained in:
parent
8cc3e4b7c1
commit
2faf866e9e
6 changed files with 87 additions and 24 deletions
|
@ -1,5 +1,5 @@
|
||||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||||
const { parseTimeObject, parseTimeFromTimeObject, utcToLocal, localToUTC } = require("../../src/util");
|
const { parseTimeObject, parseTimeFromTimeObject, utcToLocal, localToUTC, log } = require("../../src/util");
|
||||||
const { isArray } = require("chart.js/helpers");
|
const { isArray } = require("chart.js/helpers");
|
||||||
const { timeObjectToUTC, timeObjectToLocal } = require("../util-server");
|
const { timeObjectToUTC, timeObjectToLocal } = require("../util-server");
|
||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
|
@ -62,8 +62,15 @@ class Maintenance extends BeanModel {
|
||||||
} else if (obj.strategy === "manual") {
|
} else if (obj.strategy === "manual") {
|
||||||
obj.status = "under-maintenance";
|
obj.status = "under-maintenance";
|
||||||
} else if (obj.timeslotList.length > 0) {
|
} else if (obj.timeslotList.length > 0) {
|
||||||
|
let currentTimestamp = dayjs().unix();
|
||||||
|
|
||||||
for (let timeslot of obj.timeslotList) {
|
for (let timeslot of obj.timeslotList) {
|
||||||
if (dayjs.utc(timeslot.start_date) <= dayjs.utc() && dayjs.utc(timeslot.end_date) >= dayjs.utc()) {
|
if (dayjs.utc(timeslot.startDate).unix() <= currentTimestamp && dayjs.utc(timeslot.endDate).unix() >= currentTimestamp) {
|
||||||
|
log.debug("timeslot", "Timeslot ID: " + timeslot.id);
|
||||||
|
log.debug("timeslot", "currentTimestamp:" + currentTimestamp);
|
||||||
|
log.debug("timeslot", "timeslot.start_date:" + dayjs.utc(timeslot.startDate).unix());
|
||||||
|
log.debug("timeslot", "timeslot.end_date:" + dayjs.utc(timeslot.endDate).unix());
|
||||||
|
|
||||||
obj.status = "under-maintenance";
|
obj.status = "under-maintenance";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
const dayjs = require("dayjs");
|
const dayjs = require("dayjs");
|
||||||
const { log, utcToLocal, SQL_DATETIME_FORMAT_WITHOUT_SECOND } = require("../../src/util");
|
const { log, utcToLocal, SQL_DATETIME_FORMAT_WITHOUT_SECOND, localToUTC } = require("../../src/util");
|
||||||
const { UptimeKumaServer } = require("../uptime-kuma-server");
|
const { UptimeKumaServer } = require("../uptime-kuma-server");
|
||||||
|
|
||||||
class MaintenanceTimeslot extends BeanModel {
|
class MaintenanceTimeslot extends BeanModel {
|
||||||
|
@ -26,17 +26,12 @@ class MaintenanceTimeslot extends BeanModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param {Maintenance} maintenance
|
* @param {Maintenance} maintenance
|
||||||
* @param {dayjs} startFrom (For recurring type only) Generate Timeslot from this date, if it is smaller than the current date, it will use the current date instead. As generating a passed timeslot is meaningless.
|
* @param {dayjs} minDate (For recurring type only) Generate a next timeslot from this date.
|
||||||
* @param {boolean} removeExist Remove existing timeslot before create
|
* @param {boolean} removeExist Remove existing timeslot before create
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<MaintenanceTimeslot>}
|
||||||
*/
|
*/
|
||||||
static async generateTimeslot(maintenance, startFrom = null, removeExist = false) {
|
static async generateTimeslot(maintenance, minDate = null, removeExist = false) {
|
||||||
if (!startFrom) {
|
|
||||||
startFrom = dayjs();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeExist) {
|
if (removeExist) {
|
||||||
await R.exec("DELETE FROM maintenance_timeslot WHERE maintenance_id = ? ", [
|
await R.exec("DELETE FROM maintenance_timeslot WHERE maintenance_id = ? ", [
|
||||||
maintenance.id
|
maintenance.id
|
||||||
|
@ -51,9 +46,67 @@ class MaintenanceTimeslot extends BeanModel {
|
||||||
bean.start_date = maintenance.start_date;
|
bean.start_date = maintenance.start_date;
|
||||||
bean.end_date = maintenance.end_date;
|
bean.end_date = maintenance.end_date;
|
||||||
bean.generated_next = true;
|
bean.generated_next = true;
|
||||||
await R.store(bean);
|
return await R.store(bean);
|
||||||
} else if (maintenance.strategy === "recurring-interval") {
|
} else if (maintenance.strategy === "recurring-interval") {
|
||||||
// TODO
|
let bean = R.dispense("maintenance_timeslot");
|
||||||
|
|
||||||
|
// Prevent dead loop, in case interval_day is not set
|
||||||
|
if (!maintenance.interval_day || maintenance.interval_day <= 0) {
|
||||||
|
maintenance.interval_day = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let startOfTheDay = dayjs.utc(maintenance.start_date).format("HH:mm");
|
||||||
|
log.debug("timeslot", "startOfTheDay: " + startOfTheDay);
|
||||||
|
|
||||||
|
// Start Time
|
||||||
|
let startTimeSecond = dayjs.utc(maintenance.start_time, "HH:mm").diff(dayjs.utc(startOfTheDay, "HH:mm"), "second");
|
||||||
|
log.debug("timeslot", "startTime: " + startTimeSecond);
|
||||||
|
|
||||||
|
// Duration
|
||||||
|
let duration = dayjs.utc(maintenance.end_time, "HH:mm").diff(dayjs.utc(maintenance.start_time, "HH:mm"), "second");
|
||||||
|
// Add 24hours if it is across day
|
||||||
|
if (duration < 0) {
|
||||||
|
duration += 24 * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bake StartDate + StartTime = Start DateTime
|
||||||
|
let startDateTime = dayjs.utc(maintenance.start_date).add(startTimeSecond, "second");
|
||||||
|
let endDateTime;
|
||||||
|
|
||||||
|
// Keep generating from the first possible date, until it is ok
|
||||||
|
while (true) {
|
||||||
|
log.debug("timeslot", "startDateTime: " + startDateTime.format());
|
||||||
|
|
||||||
|
// Handling out of effective date range
|
||||||
|
if (startDateTime.diff(dayjs.utc(maintenance.end_date)) > 0) {
|
||||||
|
log.debug("timeslot", "Out of effective date range");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
endDateTime = startDateTime.add(duration, "second");
|
||||||
|
|
||||||
|
// If endDateTime is out of effective date range, use the end datetime from effective date range
|
||||||
|
if (endDateTime.diff(dayjs.utc(maintenance.end_date)) > 0) {
|
||||||
|
endDateTime = dayjs.utc(maintenance.end_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If minDate is set, the endDateTime must be bigger than it.
|
||||||
|
// And the endDateTime must be bigger current time
|
||||||
|
if (
|
||||||
|
(!minDate || endDateTime.diff(minDate) > 0) &&
|
||||||
|
endDateTime.diff(dayjs()) > 0
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
startDateTime = startDateTime.add(maintenance.interval_day, "day");
|
||||||
|
}
|
||||||
|
|
||||||
|
bean.maintenance_id = maintenance.id;
|
||||||
|
bean.start_date = localToUTC(startDateTime);
|
||||||
|
bean.end_date = localToUTC(endDateTime);
|
||||||
|
bean.generated_next = false;
|
||||||
|
return await R.store(bean);
|
||||||
} else if (maintenance.strategy === "recurring-weekday") {
|
} else if (maintenance.strategy === "recurring-weekday") {
|
||||||
// TODO
|
// TODO
|
||||||
} else if (maintenance.strategy === "recurring-day-of-month") {
|
} else if (maintenance.strategy === "recurring-day-of-month") {
|
||||||
|
|
|
@ -9,6 +9,7 @@ console.log("Welcome to Uptime Kuma");
|
||||||
const dayjs = require("dayjs");
|
const dayjs = require("dayjs");
|
||||||
dayjs.extend(require("dayjs/plugin/utc"));
|
dayjs.extend(require("dayjs/plugin/utc"));
|
||||||
dayjs.extend(require("dayjs/plugin/timezone"));
|
dayjs.extend(require("dayjs/plugin/timezone"));
|
||||||
|
dayjs.extend(require("dayjs/plugin/customParseFormat"));
|
||||||
|
|
||||||
// Check Node.js Version
|
// Check Node.js Version
|
||||||
const nodeVersion = parseInt(process.versions.node.split(".")[0]);
|
const nodeVersion = parseInt(process.versions.node.split(".")[0]);
|
||||||
|
@ -1110,6 +1111,7 @@ let needSetup = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
sendInfo(socket);
|
sendInfo(socket);
|
||||||
|
server.sendMaintenanceList(socket);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
callback({
|
callback({
|
||||||
|
|
|
@ -671,18 +671,20 @@ function timeObjectConvertTimezone(obj, timezone, timeObjectToUTC = true) {
|
||||||
obj.minutes += minutes;
|
obj.minutes += minutes;
|
||||||
|
|
||||||
// Handle out of bound
|
// Handle out of bound
|
||||||
|
if (obj.minutes < 0) {
|
||||||
|
obj.minutes += 60;
|
||||||
|
obj.hours--;
|
||||||
|
} else if (obj.minutes > 60) {
|
||||||
|
obj.minutes -= 60;
|
||||||
|
obj.hours++;
|
||||||
|
}
|
||||||
|
|
||||||
if (obj.hours < 0) {
|
if (obj.hours < 0) {
|
||||||
obj.hours += 24;
|
obj.hours += 24;
|
||||||
} else if (obj.hours > 24) {
|
} else if (obj.hours > 24) {
|
||||||
obj.hours -= 24;
|
obj.hours -= 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.minutes < 0) {
|
|
||||||
obj.minutes += 24;
|
|
||||||
} else if (obj.minutes > 24) {
|
|
||||||
obj.minutes -= 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="timeslot">
|
<div>
|
||||||
<div v-if="maintenance.strategy === 'manual'">
|
<div v-if="maintenance.strategy === 'manual'" class="timeslot">
|
||||||
{{ $t("Manual") }}
|
{{ $t("Manual") }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="maintenance.timeslotList.length > 0">
|
<div v-else-if="maintenance.timeslotList.length > 0" class="timeslot">
|
||||||
{{ maintenance.timeslotList[0].startDateServerTimezone }}
|
{{ maintenance.timeslotList[0].startDateServerTimezone }}
|
||||||
<span class="to">-</span>
|
<span class="to">-</span>
|
||||||
{{ maintenance.timeslotList[0].endDateServerTimezone }}
|
{{ maintenance.timeslotList[0].endDateServerTimezone }}
|
||||||
|
|
|
@ -199,8 +199,7 @@
|
||||||
range datePicker
|
range datePicker
|
||||||
:monthChangeOnScroll="false"
|
:monthChangeOnScroll="false"
|
||||||
:minDate="minDate"
|
:minDate="minDate"
|
||||||
:enableTimePicker="false"
|
format="yyyy-MM-dd HH:mm:ss"
|
||||||
format="yyyy-MM-dd"
|
|
||||||
modelType="yyyy-MM-dd HH:mm:ss"
|
modelType="yyyy-MM-dd HH:mm:ss"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue