Fix recurring

This commit is contained in:
Louis Lam 2022-10-15 20:15:50 +08:00
parent d8a676abb6
commit 24cb212a37
3 changed files with 55 additions and 37 deletions

View file

@ -57,30 +57,37 @@ class MaintenanceTimeslot extends BeanModel {
return await this.handleRecurringType(maintenance, minDate, (startDateTime) => { return await this.handleRecurringType(maintenance, minDate, (startDateTime) => {
return startDateTime.add(maintenance.interval_day, "day"); return startDateTime.add(maintenance.interval_day, "day");
}, () => {
return true;
}); });
} else if (maintenance.strategy === "recurring-weekday") { } else if (maintenance.strategy === "recurring-weekday") {
let dayOfWeekList = maintenance.getDayOfWeekList(); let dayOfWeekList = maintenance.getDayOfWeekList();
log.debug("timeslot", dayOfWeekList);
if (dayOfWeekList.length <= 0) { if (dayOfWeekList.length <= 0) {
log.debug("timeslot", "No weekdays selected?"); log.debug("timeslot", "No weekdays selected?");
return null; return null;
} }
const isValid = (startDateTime) => {
log.debug("timeslot", "nextDateTime: " + startDateTime);
let day = startDateTime.local().day();
log.debug("timeslot", "nextDateTime.day(): " + day);
return dayOfWeekList.includes(day);
};
return await this.handleRecurringType(maintenance, minDate, (startDateTime) => { return await this.handleRecurringType(maintenance, minDate, (startDateTime) => {
while (true) { while (true) {
startDateTime = startDateTime.add(1, "day"); startDateTime = startDateTime.add(1, "day");
log.debug("timeslot", "nextDateTime: " + startDateTime); if (isValid(startDateTime)) {
let day = startDateTime.local().day();
log.debug("timeslot", "nextDateTime.day(): " + day);
if (dayOfWeekList.includes(day)) {
return startDateTime; return startDateTime;
} }
} }
}); }, isValid);
} else if (maintenance.strategy === "recurring-day-of-month") { } else if (maintenance.strategy === "recurring-day-of-month") {
let dayOfMonthList = maintenance.getDayOfMonthList(); let dayOfMonthList = maintenance.getDayOfMonthList();
@ -89,36 +96,38 @@ class MaintenanceTimeslot extends BeanModel {
return null; return null;
} }
const isValid = (startDateTime) => {
let day = parseInt(startDateTime.local().format("D"));
log.debug("timeslot", "day: " + day);
// Check 1-31
if (dayOfMonthList.includes(day)) {
return startDateTime;
}
// Check "lastDay1","lastDay2"...
let daysInMonth = startDateTime.daysInMonth();
let lastDayList = [];
// Small first, e.g. 28 > 29 > 30 > 31
for (let i = 4; i >= 1; i--) {
if (dayOfMonthList.includes("lastDay" + i)) {
lastDayList.push(daysInMonth - i + 1);
}
}
log.debug("timeslot", lastDayList);
return lastDayList.includes(day);
};
return await this.handleRecurringType(maintenance, minDate, (startDateTime) => { return await this.handleRecurringType(maintenance, minDate, (startDateTime) => {
while (true) { while (true) {
startDateTime = startDateTime.add(1, "day"); startDateTime = startDateTime.add(1, "day");
if (isValid(startDateTime)) {
let day = parseInt(startDateTime.local().format("D"));
log.debug("timeslot", "day: " + day);
// Check 1-31
if (dayOfMonthList.includes(day)) {
return startDateTime;
}
// Check "lastDay1","lastDay2"...
let daysInMonth = startDateTime.daysInMonth();
let lastDayList = [];
// Small first, e.g. 28 > 29 > 30 > 31
for (let i = 4; i >= 1; i--) {
if (dayOfMonthList.includes("lastDay" + i)) {
lastDayList.push(daysInMonth - i + 1);
}
}
log.debug("timeslot", "lastDayList: " + lastDayList);
if (lastDayList.includes(day)) {
return startDateTime; return startDateTime;
} }
} }
}); }, isValid);
} else { } else {
throw new Error("Unknown maintenance strategy"); throw new Error("Unknown maintenance strategy");
} }
@ -128,10 +137,11 @@ class MaintenanceTimeslot extends BeanModel {
* Generate a next timeslot for all recurring types * Generate a next timeslot for all recurring types
* @param maintenance * @param maintenance
* @param minDate * @param minDate
* @param nextDayCallback The logic how to get the next possible day * @param {function} nextDayCallback The logic how to get the next possible day
* @param {function} isValidCallback Check the day whether is matched the current strategy
* @returns {Promise<null|MaintenanceTimeslot>} * @returns {Promise<null|MaintenanceTimeslot>}
*/ */
static async handleRecurringType(maintenance, minDate, nextDayCallback) { static async handleRecurringType(maintenance, minDate, nextDayCallback, isValidCallback) {
let bean = R.dispense("maintenance_timeslot"); let bean = R.dispense("maintenance_timeslot");
let duration = maintenance.getDuration(); let duration = maintenance.getDuration();
@ -157,13 +167,14 @@ class MaintenanceTimeslot extends BeanModel {
// If minDate is set, the endDateTime must be bigger than it. // If minDate is set, the endDateTime must be bigger than it.
// And the endDateTime must be bigger current time // And the endDateTime must be bigger current time
// Is valid under current recurring strategy
if ( if (
(!minDate || endDateTime.diff(minDate) > 0) && (!minDate || endDateTime.diff(minDate) > 0) &&
endDateTime.diff(dayjs()) > 0 endDateTime.diff(dayjs()) > 0 &&
isValidCallback(startDateTime)
) { ) {
break; break;
} }
startDateTime = nextDayCallback(startDateTime); startDateTime = nextDayCallback(startDateTime);
} }

View file

@ -623,6 +623,8 @@ class Monitor extends BeanModel {
log.debug("monitor", `[${this.name}] apicache clear`); log.debug("monitor", `[${this.name}] apicache clear`);
apicache.clear(); apicache.clear();
UptimeKumaServer.getInstance().sendMaintenanceListByUserID(this.user_id);
} else { } else {
bean.important = false; bean.important = false;

View file

@ -10,6 +10,7 @@ const util = require("util");
const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent"); const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent");
const { Settings } = require("./settings"); const { Settings } = require("./settings");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
// DO NOT IMPORT HERE IF THE MODULES USED `UptimeKumaServer.getInstance()`
/** /**
* `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue. * `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue.
@ -130,8 +131,12 @@ class UptimeKumaServer {
* @returns {Object} * @returns {Object}
*/ */
async sendMaintenanceList(socket) { async sendMaintenanceList(socket) {
let list = await this.getMaintenanceJSONList(socket.userID); return await this.sendMaintenanceListByUserID(socket.userID);
this.io.to(socket.userID).emit("maintenanceList", list); }
async sendMaintenanceListByUserID(userID) {
let list = await this.getMaintenanceJSONList(userID);
this.io.to(userID).emit("maintenanceList", list);
return list; return list;
} }