mirror of https://github.com/louislam/uptime-kuma
				
				
				
			[WIP] Checking maintenance time using maintenance_timeslot table
							parent
							
								
									3f63cb246b
								
							
						
					
					
						commit
						4002b9f577
					
				|  | @ -0,0 +1,46 @@ | ||||||
|  | const { BeanModel } = require("redbean-node/dist/bean-model"); | ||||||
|  | const { R } = require("redbean-node"); | ||||||
|  | const dayjs = require("dayjs"); | ||||||
|  | 
 | ||||||
|  | class MaintenanceTimeslot extends BeanModel { | ||||||
|  | 
 | ||||||
|  |     async toPublicJSON() { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     async toJSON() { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * | ||||||
|  |      * @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 {boolean} removeExist Remove existing timeslot before create | ||||||
|  |      * @returns {Promise<void>} | ||||||
|  |      */ | ||||||
|  |     static async generateTimeslot(maintenance, startFrom = null, removeExist = false) { | ||||||
|  |         if (!startFrom) { | ||||||
|  |             startFrom = dayjs(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (removeExist) { | ||||||
|  |             await R.exec("DELETE FROM maintenance_timeslot WHERE maintenance_id = ? ", [ | ||||||
|  |                 maintenance.id | ||||||
|  |             ]); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (maintenance.strategy === "single") { | ||||||
|  |             let bean = R.dispense("maintenance_timeslot"); | ||||||
|  |             bean.maintenance_id = maintenance.id; | ||||||
|  |             bean.start_date = maintenance.start_datetime; | ||||||
|  |             bean.end_date = maintenance.end_datetime; | ||||||
|  |             bean.generated_next = true; | ||||||
|  |             await R.store(bean); | ||||||
|  |         } else { | ||||||
|  |             throw new Error("Unknown maintenance strategy"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = MaintenanceTimeslot; | ||||||
|  | @ -1105,7 +1105,17 @@ class Monitor extends BeanModel { | ||||||
|      * @returns {Promise<boolean>} |      * @returns {Promise<boolean>} | ||||||
|      */ |      */ | ||||||
|     static async isUnderMaintenance(monitorID) { |     static async isUnderMaintenance(monitorID) { | ||||||
|         const maintenance = await R.getRow("SELECT COUNT(*) AS count FROM monitor_maintenance mm JOIN maintenance ON mm.maintenance_id = maintenance.id WHERE mm.monitor_id = ? AND datetime(maintenance.start_date) <= datetime('now') AND datetime(maintenance.end_date) >= datetime('now') LIMIT 1", [ monitorID ]); |         const maintenance = await R.getRow(` | ||||||
|  |             SELECT COUNT(*) AS count | ||||||
|  |             FROM monitor_maintenance mm | ||||||
|  |             JOIN maintenance | ||||||
|  |                 ON mm.maintenance_id = maintenance.id | ||||||
|  |             JOIN maintenance_timeslot | ||||||
|  |                 ON maintenance_timeslot.maintenance_id = maintenance.id | ||||||
|  |             WHERE mm.monitor_id = ? | ||||||
|  |                 AND maintenance_timeslot.start_date <= DATETIME('now') | ||||||
|  |                 AND maintenance_timeslot.end_date >= DATETIME('now') | ||||||
|  |             LIMIT 1`, [ monitorID ]);
 | ||||||
|         return maintenance.count !== 0; |         return maintenance.count !== 0; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -272,15 +272,15 @@ class StatusPage extends BeanModel { | ||||||
|             const publicMaintenanceList = []; |             const publicMaintenanceList = []; | ||||||
| 
 | 
 | ||||||
|             let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(` |             let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(` | ||||||
|             SELECT m.* |                 SELECT m.* | ||||||
|             FROM maintenance m |                 FROM maintenance m, maintenance_status_page msp, maintenance_timeslot | ||||||
|             JOIN maintenance_status_page msp |                 WHERE  msp.maintenance_id = m.id | ||||||
|             ON msp.maintenance_id = m.id |                 AND maintenance_timeslot.maintenance.id = m.id | ||||||
|             WHERE datetime(m.start_date) <= datetime('now') |                 AND maintenance_timeslot.start_date <= DATETIME('now') | ||||||
|               AND datetime(m.end_date) >= datetime('now') |                 AND maintenance_timeslot.end_date >= DATETIME('now') | ||||||
|               AND msp.status_page_id = ? |                 AND msp.status_page_id = ? | ||||||
|             ORDER BY m.end_date |                 ORDER BY m.end_date | ||||||
|         `, [ statusPageId ]));
 |             `, [ statusPageId ]));
 | ||||||
| 
 | 
 | ||||||
|             for (const bean of maintenanceBeanList) { |             for (const bean of maintenanceBeanList) { | ||||||
|                 publicMaintenanceList.push(await bean.toPublicJSON()); |                 publicMaintenanceList.push(await bean.toPublicJSON()); | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ const server = UptimeKumaServer.getInstance(); | ||||||
| const dayjs = require("dayjs"); | const dayjs = require("dayjs"); | ||||||
| const utc = require("dayjs/plugin/utc"); | const utc = require("dayjs/plugin/utc"); | ||||||
| let timezone = require("dayjs/plugin/timezone"); | let timezone = require("dayjs/plugin/timezone"); | ||||||
|  | const MaintenanceTimeslot = require("../model/maintenance_timeslot"); | ||||||
| dayjs.extend(utc); | dayjs.extend(utc); | ||||||
| dayjs.extend(timezone); | dayjs.extend(timezone); | ||||||
| 
 | 
 | ||||||
|  | @ -26,6 +27,7 @@ module.exports.maintenanceSocketHandler = (socket) => { | ||||||
|             let bean = Maintenance.jsonToBean(R.dispense("maintenance"), maintenance, timezone); |             let bean = Maintenance.jsonToBean(R.dispense("maintenance"), maintenance, timezone); | ||||||
|             bean.user_id = socket.userID; |             bean.user_id = socket.userID; | ||||||
|             let maintenanceID = await R.store(bean); |             let maintenanceID = await R.store(bean); | ||||||
|  |             await MaintenanceTimeslot.generateTimeslot(bean); | ||||||
| 
 | 
 | ||||||
|             await server.sendMaintenanceList(socket); |             await server.sendMaintenanceList(socket); | ||||||
| 
 | 
 | ||||||
|  | @ -57,6 +59,7 @@ module.exports.maintenanceSocketHandler = (socket) => { | ||||||
|             Maintenance.jsonToBean(bean, maintenance, timezone); |             Maintenance.jsonToBean(bean, maintenance, timezone); | ||||||
| 
 | 
 | ||||||
|             await R.store(bean); |             await R.store(bean); | ||||||
|  |             await MaintenanceTimeslot.generateTimeslot(bean, null, true); | ||||||
| 
 | 
 | ||||||
|             await server.sendMaintenanceList(socket); |             await server.sendMaintenanceList(socket); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ export default { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (this.status === 3) { |             if (this.status === 3) { | ||||||
|                 return this.$t("Maintenance"); |                 return this.$t("statusMaintenance"); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return this.$t("Unknown"); |             return this.$t("Unknown"); | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ export default { | ||||||
|         uptime() { |         uptime() { | ||||||
| 
 | 
 | ||||||
|             if (this.type === "maintenance") { |             if (this.type === "maintenance") { | ||||||
|                 return this.$t("Maintenance"); |                 return this.$t("statusMaintenance"); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             let key = this.monitor.id + "_" + this.type; |             let key = this.monitor.id + "_" + this.type; | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ export default { | ||||||
|     maxRedirectDescription: "Maximum number of redirects to follow. Set to 0 to disable redirects.", |     maxRedirectDescription: "Maximum number of redirects to follow. Set to 0 to disable redirects.", | ||||||
|     acceptedStatusCodesDescription: "Select status codes which are considered as a successful response.", |     acceptedStatusCodesDescription: "Select status codes which are considered as a successful response.", | ||||||
|     Maintenance: "Maintenance", |     Maintenance: "Maintenance", | ||||||
|  |     statusMaintenance: "Maintenance", | ||||||
|     "Schedule maintenance": "Schedule maintenance", |     "Schedule maintenance": "Schedule maintenance", | ||||||
|     "Affected Monitors": "Affected Monitors", |     "Affected Monitors": "Affected Monitors", | ||||||
|     "Pick Affected Monitors...": "Pick Affected Monitors...", |     "Pick Affected Monitors...": "Pick Affected Monitors...", | ||||||
|  |  | ||||||
|  | @ -380,4 +380,6 @@ export default { | ||||||
|     proxyDescription: "必須將代理伺服器指派給監測器才能運作。", |     proxyDescription: "必須將代理伺服器指派給監測器才能運作。", | ||||||
|     enableProxyDescription: "此代理伺服器在啟用前不會在監測器上生效,您可以藉由控制啟用狀態來暫時對所有的監測器停用代理伺服器。", |     enableProxyDescription: "此代理伺服器在啟用前不會在監測器上生效,您可以藉由控制啟用狀態來暫時對所有的監測器停用代理伺服器。", | ||||||
|     setAsDefaultProxyDescription: "預設情況下,新監測器將啟用此代理伺服器。您仍可分別停用各監測器的代理伺服器。", |     setAsDefaultProxyDescription: "預設情況下,新監測器將啟用此代理伺服器。您仍可分別停用各監測器的代理伺服器。", | ||||||
|  |     Maintenance: "維護", | ||||||
|  |     statusMaintenance: "維護中", | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -588,7 +588,7 @@ export default { | ||||||
| 
 | 
 | ||||||
|                 if (this.monitorList[monitorID].maintenance) { |                 if (this.monitorList[monitorID].maintenance) { | ||||||
|                     result[monitorID] = { |                     result[monitorID] = { | ||||||
|                         text: this.$t("Maintenance"), |                         text: this.$t("statusMaintenance"), | ||||||
|                         color: "maintenance", |                         color: "maintenance", | ||||||
|                     }; |                     }; | ||||||
|                 } else if (! lastHeartBeat) { |                 } else if (! lastHeartBeat) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Louis Lam
						Louis Lam