mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-08-08 17:13:08 +08:00
[status page] many update and save group list
This commit is contained in:
@@ -18,7 +18,7 @@ exports.startInterval = () => {
|
||||
|
||||
// For debug
|
||||
if (process.env.TEST_CHECK_VERSION === "1") {
|
||||
res.data.version = "1000.0.0"
|
||||
res.data.version = "1000.0.0";
|
||||
}
|
||||
|
||||
exports.latestVersion = res.data.version;
|
||||
|
@@ -30,11 +30,10 @@ class Database {
|
||||
static patchList = {
|
||||
"patch-setting-value-type.sql": true,
|
||||
"patch-improve-performance.sql": true,
|
||||
"patch-monitor-public.sql": true,
|
||||
"patch-2fa.sql": true,
|
||||
"patch-add-retry-interval-monitor.sql": true,
|
||||
"patch-monitor-public-weight.sql": true,
|
||||
"patch-incident-table.sql": true,
|
||||
"patch-group-table.sql": true,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +64,7 @@ class Database {
|
||||
}
|
||||
|
||||
// Auto map the model to a bean object
|
||||
R.freeze(true)
|
||||
R.freeze(true);
|
||||
await R.autoloadModels("./server/model");
|
||||
|
||||
// Change to WAL
|
||||
@@ -92,7 +91,7 @@ class Database {
|
||||
} else if (version > this.latestVersion) {
|
||||
console.info("Warning: Database version is newer than expected");
|
||||
} else {
|
||||
console.info("Database patch is needed")
|
||||
console.info("Database patch is needed");
|
||||
|
||||
this.backup(version);
|
||||
|
||||
@@ -107,11 +106,12 @@ class Database {
|
||||
}
|
||||
} catch (ex) {
|
||||
await Database.close();
|
||||
this.restore();
|
||||
|
||||
console.error(ex)
|
||||
console.error("Start Uptime-Kuma failed due to patch db failed")
|
||||
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues")
|
||||
console.error(ex);
|
||||
console.error("Start Uptime-Kuma failed due to patch db failed");
|
||||
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues");
|
||||
|
||||
this.restore();
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,7 @@ class Database {
|
||||
|
||||
try {
|
||||
for (let sqlFilename in this.patchList) {
|
||||
await this.patch2Recursion(sqlFilename, databasePatchedFiles)
|
||||
await this.patch2Recursion(sqlFilename, databasePatchedFiles);
|
||||
}
|
||||
|
||||
if (this.patched) {
|
||||
@@ -145,11 +145,13 @@ class Database {
|
||||
|
||||
} catch (ex) {
|
||||
await Database.close();
|
||||
this.restore();
|
||||
|
||||
console.error(ex)
|
||||
console.error(ex);
|
||||
console.error("Start Uptime-Kuma failed due to patch db failed");
|
||||
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues");
|
||||
|
||||
this.restore();
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -189,7 +191,7 @@ class Database {
|
||||
console.log(sqlFilename + " is patched successfully");
|
||||
|
||||
} else {
|
||||
console.log(sqlFilename + " is already patched, skip");
|
||||
debug(sqlFilename + " is already patched, skip");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,12 +209,12 @@ class Database {
|
||||
// Remove all comments (--)
|
||||
let lines = text.split("\n");
|
||||
lines = lines.filter((line) => {
|
||||
return ! line.startsWith("--")
|
||||
return ! line.startsWith("--");
|
||||
});
|
||||
|
||||
// Split statements by semicolon
|
||||
// Filter out empty line
|
||||
text = lines.join("\n")
|
||||
text = lines.join("\n");
|
||||
|
||||
let statements = text.split(";")
|
||||
.map((statement) => {
|
||||
@@ -220,7 +222,7 @@ class Database {
|
||||
})
|
||||
.filter((statement) => {
|
||||
return statement !== "";
|
||||
})
|
||||
});
|
||||
|
||||
for (let statement of statements) {
|
||||
await R.exec(statement);
|
||||
@@ -266,7 +268,7 @@ class Database {
|
||||
*/
|
||||
static backup(version) {
|
||||
if (! this.backupPath) {
|
||||
console.info("Backup the db")
|
||||
console.info("Backup the db");
|
||||
this.backupPath = this.dataDir + "kuma.db.bak" + version;
|
||||
fs.copyFileSync(Database.path, this.backupPath);
|
||||
|
||||
|
33
server/model/group.js
Normal file
33
server/model/group.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||
const { R } = require("redbean-node");
|
||||
|
||||
class Group extends BeanModel {
|
||||
|
||||
async toPublicJSON() {
|
||||
|
||||
let monitorBeanList = R.convertToBeans("monitor", await R.getAll(`
|
||||
SELECT * FROM monitor, monitor_group
|
||||
WHERE monitor.id = monitor_group.monitor_id
|
||||
AND group_id = ?
|
||||
`, [
|
||||
this.id,
|
||||
]));
|
||||
|
||||
console.log(monitorBeanList);
|
||||
|
||||
let monitorList = [];
|
||||
|
||||
for (let bean of monitorBeanList) {
|
||||
monitorList.push(await bean.toPublicJSON());
|
||||
}
|
||||
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
weight: this.weight,
|
||||
monitorList,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Group;
|
@@ -10,6 +10,7 @@ class Incident extends BeanModel {
|
||||
content: this.content,
|
||||
pin: this.pin,
|
||||
createdDate: this.createdDate,
|
||||
lastUpdatedDate: this.lastUpdatedDate,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -26,8 +26,10 @@ class Monitor extends BeanModel {
|
||||
* Only show necessary data to public
|
||||
*/
|
||||
async toPublicJSON() {
|
||||
// TODO Only show necessary
|
||||
return this.toJSON();
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -41,7 +41,7 @@ router.get("/api/status-page/incident", async (_, response) => {
|
||||
response.json({
|
||||
ok: true,
|
||||
incident: (await R.findOne("incident", " pin = 1 AND active = 1")).toPublicJSON(),
|
||||
})
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
send403(response, error.message);
|
||||
@@ -55,15 +55,14 @@ router.get("/api/status-page/monitor-list", async (_request, response) => {
|
||||
|
||||
try {
|
||||
await checkPublished();
|
||||
const monitorList = {};
|
||||
let list = await R.find("monitor", " public = 1 ORDER BY weight DESC, name ", [
|
||||
]);
|
||||
const publicGroupList = [];
|
||||
let list = await R.find("group", " public = 1 ORDER BY weight, name ");
|
||||
|
||||
for (let monitor of list) {
|
||||
monitorList[monitor.id] = await monitor.toJSON();
|
||||
for (let groupBean of list) {
|
||||
publicGroupList.push(await groupBean.toPublicJSON());
|
||||
}
|
||||
|
||||
response.json(monitorList);
|
||||
response.json(publicGroupList);
|
||||
|
||||
} catch (error) {
|
||||
send403(response, error.message);
|
||||
@@ -79,7 +78,7 @@ router.get("/api/status-page/heartbeat", async (_request, response) => {
|
||||
|
||||
const monitorList = {};
|
||||
let list = await R.find("", " ", [
|
||||
])
|
||||
]);
|
||||
|
||||
for (let monitor of list) {
|
||||
monitorList[monitor.id] = await monitor.toJSON();
|
||||
@@ -126,7 +125,7 @@ function send403(res, msg = "") {
|
||||
res.status(403).json({
|
||||
"status": "fail",
|
||||
"msg": msg,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = router;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
const { R } = require("redbean-node");
|
||||
const { checkLogin } = require("../util-server");
|
||||
const dayjs = require("dayjs");
|
||||
const { debug } = require("../../src/util");
|
||||
|
||||
module.exports.statusPageSocketHandler = (socket) => {
|
||||
|
||||
@@ -27,7 +28,13 @@ module.exports.statusPageSocketHandler = (socket) => {
|
||||
incidentBean.content = incident.content;
|
||||
incidentBean.style = incident.style;
|
||||
incidentBean.pin = true;
|
||||
incidentBean.createdDate = R.isoDateTime(dayjs.utc());
|
||||
|
||||
if (incident.id) {
|
||||
incidentBean.lastUpdatedDate = R.isoDateTime(dayjs.utc());
|
||||
} else {
|
||||
incidentBean.createdDate = R.isoDateTime(dayjs.utc());
|
||||
}
|
||||
|
||||
await R.store(incidentBean);
|
||||
|
||||
callback({
|
||||
@@ -58,4 +65,67 @@ module.exports.statusPageSocketHandler = (socket) => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Save Status Page
|
||||
socket.on("saveStatusPage", async (publicGroupList, callback) => {
|
||||
|
||||
try {
|
||||
checkLogin(socket);
|
||||
|
||||
await R.transaction(async (trx) => {
|
||||
const groupIDList = [];
|
||||
let groupOrder = 1;
|
||||
|
||||
for (let group of publicGroupList) {
|
||||
let groupBean;
|
||||
if (group.id) {
|
||||
groupBean = await trx.findOne("group", " id = ? AND public = 1 ", [
|
||||
group.id
|
||||
]);
|
||||
} else {
|
||||
groupBean = R.dispense("group");
|
||||
}
|
||||
|
||||
groupBean.name = group.name;
|
||||
groupBean.public = true;
|
||||
groupBean.weight = groupOrder++;
|
||||
|
||||
await trx.store(groupBean);
|
||||
|
||||
await trx.exec("DELETE FROM monitor_group WHERE group_id = ? ", [
|
||||
groupBean.id
|
||||
]);
|
||||
|
||||
let monitorOrder = 1;
|
||||
for (let monitor of group.monitorList) {
|
||||
let relationBean = R.dispense("monitor_group");
|
||||
relationBean.weight = monitorOrder++;
|
||||
relationBean.group_id = groupBean.id;
|
||||
relationBean.monitor_id = monitor.id;
|
||||
await trx.store(relationBean);
|
||||
}
|
||||
|
||||
groupIDList.push(groupBean.id);
|
||||
group.id = groupBean.id;
|
||||
}
|
||||
|
||||
// Delete groups that not in the list
|
||||
debug("Delete groups that not in the list");
|
||||
const slots = groupIDList.map(() => "?").join(",");
|
||||
await trx.exec(`DELETE FROM \`group\` WHERE id NOT IN (${slots})`, groupIDList);
|
||||
|
||||
callback({
|
||||
ok: true,
|
||||
publicGroupList,
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
callback({
|
||||
ok: false,
|
||||
msg: error.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
Reference in New Issue
Block a user