🔨 Add settings for partial backup #33

This commit is contained in:
Sebastien Clement 2020-12-06 22:55:18 +01:00
parent 619aa80687
commit 310ecf1c17
5 changed files with 388 additions and 217 deletions

View File

@ -12,6 +12,7 @@ const humanFileSize = require("../tools/toolbox").humanFileSize;
const cronTools = require("../tools/cronTools");
const logger = require("../config/winston");
const { add } = require("../config/winston");
router.get("/status", (req, res, next) => {
cronTools.updatetNextDate();
@ -37,9 +38,9 @@ router.get("/formated-local-snap", function (req, res, next) {
res.send("");
}
);
});
});
router.get("/formated-backup-manual", function (req, res, next) {
router.get("/formated-backup-manual", function (req, res, next) {
webdav
.getFolderContent(webdav.getConf().back_dir + pathTools.manual)
.then((contents) => {
@ -52,9 +53,9 @@ router.get("/formated-backup-manual", function (req, res, next) {
.catch(() => {
res.send();
});
});
});
router.get("/formated-backup-auto", function (req, res, next) {
router.get("/formated-backup-auto", function (req, res, next) {
let url = webdav.getConf().back_dir + pathTools.auto;
webdav
.getFolderContent(url)
@ -68,9 +69,9 @@ router.get("/formated-backup-auto", function (req, res, next) {
.catch(() => {
res.send();
});
});
});
router.post("/nextcloud-settings", function (req, res, next) {
router.post("/nextcloud-settings", function (req, res, next) {
let settings = req.body;
if (settings.ssl != null && settings.host != null && settings.host != "" && settings.username != null && settings.password != null) {
webdav.setConf(settings);
@ -88,9 +89,9 @@ router.post("/nextcloud-settings", function (req, res, next) {
res.status(400);
res.send();
}
});
});
router.get("/nextcloud-settings", function (req, res, next) {
router.get("/nextcloud-settings", function (req, res, next) {
let conf = webdav.getConf();
if (conf == null) {
res.status(404);
@ -98,9 +99,9 @@ router.get("/nextcloud-settings", function (req, res, next) {
} else {
res.json(conf);
}
});
});
router.post("/manual-backup", function (req, res, next) {
router.post("/manual-backup", function (req, res, next) {
let id = req.query.id;
let name = req.query.name;
let status = statusTools.getStatus();
@ -121,9 +122,9 @@ router.post("/manual-backup", function (req, res, next) {
res.status(500);
res.send();
});
});
});
router.post("/new-backup", function (req, res, next) {
router.post("/new-backup", function (req, res, next) {
let status = statusTools.getStatus();
if (status.status === "creating" && status.status === "upload" && status.status === "download") {
res.status(503);
@ -150,13 +151,20 @@ router.post("/new-backup", function (req, res, next) {
res.status(201);
res.send();
});
});
router.get("/backup-settings", function (req, res, next) {
res.send(settingsTools.getSettings());
});
router.get("/backup-settings", function (req, res, next) {
hassioApiTools.getAddonList().then((addonList)=>{
let data = {};
data['folders'] = hassioApiTools.getFolderList();
data['addonList'] = addonList;
data['settings'] = settingsTools.getSettings();
res.send(data);
})
router.post("/backup-settings", function (req, res, next) {
});
router.post("/backup-settings", function (req, res, next) {
if (settingsTools.check(req.body)) {
settingsTools.setSettings(req.body);
cronTools.startCron();
@ -165,9 +173,9 @@ router.post("/backup-settings", function (req, res, next) {
res.status(400);
res.send();
}
});
});
router.post("/clean-now", function (req, res, next) {
router.post("/clean-now", function (req, res, next) {
webdav
.clean()
.then(() => {
@ -178,9 +186,9 @@ router.post("/clean-now", function (req, res, next) {
});
res.status(201);
res.send();
});
});
router.post("/restore", function (req, res, next) {
router.post("/restore", function (req, res, next) {
if (req.body["path"] != null) {
webdav.downloadFile(req.body["path"]).then((path) => {
hassioApiTools.uploadSnapshot(path);
@ -191,6 +199,7 @@ router.post("/restore", function (req, res, next) {
res.status(400);
res.send();
}
});
});
module.exports = router;
module.exports = router;

View File

@ -46,6 +46,75 @@ function getVersion() {
});
}
function getAddonList() {
return new Promise((resolve, reject) => {
let token = process.env.HASSIO_TOKEN;
let status = statusTools.getStatus();
let option = {
headers: { "X-HASSIO-KEY": token },
responseType: "json",
};
got("http://hassio/addons", option)
.then((result) => {
if (status.error_code === 1) {
status.status = "idle";
status.message = null;
status.error_code = null;
statusTools.setStatus(status);
}
let addons = result.body.data.addons;
let instaled = [];
for(let index in addons){
let current = addons[index];
if(current.installed == true){
instaled.push({slug:current.slug, name: current.name})
}
}
instaled.sort((a,b)=>{
var textA = a.name.toUpperCase();
var textB = b.name.toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});
resolve(instaled);
})
.catch((error) => {
status.status = "error";
status.message = "Fail to fetch addons list (" + error.message + ")";
status.error_code = 1;
statusTools.setStatus(status);
logger.error(status.message);
reject(error.message);
});
});
}
function getFolderList(){
return [
{
name: "Homme Assistant configuration",
slug: "homeassistant"
},
{
name: "SSL",
slug: "ssl"
},
{
name: "Share",
slug: "share"
},
{
name: "Media",
slug: "media"
},
{
name: "Local add-ons",
slug: "addons/local"
}
]
}
function getSnapshots() {
return new Promise((resolve, reject) => {
@ -302,6 +371,8 @@ function uploadSnapshot(path) {
}
exports.getVersion = getVersion;
exports.getAddonList = getAddonList;
exports.getFolderList = getFolderList;
exports.getSnapshots = getSnapshots;
exports.downloadSnapshot = downloadSnapshot;
exports.createNewBackup = createNewBackup;

View File

@ -28,6 +28,7 @@ function check_cron(conf){
function check(conf, fallback = false){
let needSave = false;
if(!check_cron(conf)){
if(fallback){
logger.warn("Bad value for cron settings, fallback to default ")
@ -92,7 +93,39 @@ function check(conf, fallback = false){
return false;
}
}
if(conf.exclude_addon == null){
if(fallback){
logger.warn("Bad value for 'exclude_addon', fallback to [] ")
conf.exclude_addon = []
}
else {
logger.error("Bad value for 'exclude_addon'")
return false;
}
}
if(conf.exclude_folder == null){
if(fallback){
logger.warn("Bad value for 'exclude_folder', fallback to [] ")
conf.exclude_folder = []
}
else {
logger.error("Bad value for 'exclude_folder'")
return false;
}
}
if(!Array.isArray(conf.exclude_folder)){
logger.debug("exclude_folder is not array (Empty value), reset...");
conf.exclude_folder = []
needSave = true;
}
if(!Array.isArray(conf.exclude_addon)){
logger.debug("exclude_addon is not array (Empty value), reset...");
conf.exclude_addon = []
needSave = true;
}
if(fallback || needSave){
setSettings(conf);
}
return true

View File

@ -98,7 +98,7 @@
<ul id="dropdown-settings" class="dropdown-content blue-grey darken-4">
<li><a href="#modal-settings-nextcloud" id="trigger-nextcloud-settings" class="modal-trigger center">Nextcloud</a>
</li>
<li><a href="#modal-settings-backup" id="trigger-backup-settings" class="modal-trigger center">Backup</a></li>
<li><a href="#" id="trigger-backup-settings" class="center">Backup</a></li>
</ul>
<div class="container ">
@ -263,6 +263,7 @@
var loadingModal = null;
document.addEventListener('DOMContentLoaded', function() {
$.ajaxSetup({traditional: true});
updateLocalSnaps();
update_status();
let tooltips = document.querySelectorAll('.tooltipped');
@ -596,30 +597,30 @@
}
}
changeSelect('#cron-drop-settings', data.cron_base);
changeSelect('#cron-drop-settings', data.settings.cron_base);
$('#cron-drop-settings').change(updateDropVisibility);
$('#name-template').val(data.name_template);
$('#name-template').val(data.settings.name_template);
$('#name-template + label').removeClass("active");
$('#name-template + label').addClass("active");
let timepicker = document.querySelector('#timepicker');
$('#timepicker').val(data.cron_hour);
$('#timepicker').val(data.settings.cron_hour);
$('#timepicker + label').removeClass("active");
$('#timepicker + label').addClass("active");
if (M.Timepicker.getInstance(timepicker) != null)
M.Timepicker.getInstance(timepicker).destroy();
M.Timepicker.init(timepicker, { defaultTime: data.cron_hour, twelveHour: false, container: 'body' });
$('#cron-drop-day-month-read').val(data.cron_month_day);
$('#cron-drop-day-month').val(data.cron_month_day);
M.Timepicker.init(timepicker, { defaultTime: data.settings.cron_hour, twelveHour: false, container: 'body' });
$('#cron-drop-day-month-read').val(data.settings.cron_month_day);
$('#cron-drop-day-month').val(data.settings.cron_month_day);
$('#cron-drop-day-month-read + label').removeClass("active");
$('#cron-drop-day-month-read + label').addClass("active");
$('#auto_clean_local').prop('checked', data.auto_clean_local == "true");
$('#local-snap-keep').val(data.auto_clean_local_keep);
$('#auto_clean_backup').prop('checked', data.auto_clean_backup == "true");
$('#backup-snap-keep').val(data.auto_clean_backup_keep);
$('#auto_clean_local').prop('checked', data.settings.auto_clean_local == "true");
$('#local-snap-keep').val(data.settings.auto_clean_local_keep);
$('#auto_clean_backup').prop('checked', data.settings.auto_clean_backup == "true");
$('#backup-snap-keep').val(data.settings.auto_clean_backup_keep);
$('#backup-snap-keep + label').removeClass("active");
@ -627,9 +628,26 @@
$('#local-snap-keep + label').removeClass("active");
$('#local-snap-keep + label').addClass("active");
changeSelect('#cron-drop-day', data.cron_weekday);
changeSelect('#cron-drop-day', data.settings.cron_weekday);
let folder_html = ""
for(let index in data.folders){
let thisFolder = data.folders[index];
let exclude = data.settings.exclude_folder.includes(thisFolder.slug);
folder_html += `<li><label><input type="checkbox" class="folders-box" id="${thisFolder.slug}" ${exclude ? "" : "checked=checked"}/><span>${thisFolder.name}</span></label></li>`
}
$("#folders-div").html(folder_html);
let addons_html = ""
for(let index in data.addonList){
let thisAddon = data.addonList[index];
let exclude = data.settings.exclude_addon.includes(thisAddon.slug);
addons_html += `<li><label><input type="checkbox" class="addons-box" id="${thisAddon.slug}" ${exclude ? "" : "checked=checked"}/><span>${thisAddon.name}</span></label></li>`
}
$("#addons-div").html(addons_html);
updateDropVisibility();
loadingModal.close();
M.Modal.getInstance(document.querySelector("#modal-settings-backup")).open()
});
}
@ -672,6 +690,19 @@
let auto_clean_local_keep = $("#local-snap-keep").val();
let auto_clean_backup_keep = $("#backup-snap-keep").val();
let name_template = $('#name-template').val();
let excluded_folders_nodes = document.querySelectorAll('.folders-box:not(:checked)');
let exclude_folder = [""];
for(let i of excluded_folders_nodes){
exclude_folder.push(i.id);
}
let excluded_addons_nodes = document.querySelectorAll('.addons-box:not(:checked)');
let exclude_addon = [""];
for(let i of excluded_addons_nodes){
exclude_addon.push(i.id);
}
loadingModal.open();
$.post('./api/backup-settings',
{
@ -684,6 +715,8 @@
auto_clean_local_keep: auto_clean_local_keep,
auto_clean_backup: auto_clean_backup,
auto_clean_backup_keep: auto_clean_backup_keep,
exclude_addon: exclude_addon,
exclude_folder: exclude_folder
})
.done(() => {
M.toast({ html: '<i class="material-icons" style="margin-right:10px">check_box</i> Backup settings saved !', classes: "green" });

View File

@ -64,8 +64,33 @@
</div>
<div class="row">
<div class="col s12">
<div class="col offset-xl1 xl5 l6 m12 s12">
<div class="row">
<div class="col s12 center">
<h5>Folders</h5>
</div>
</div>
<div class="row">
<div class="col offset-s1 s11 xl10 offset-xl2" >
<ul id="folders-div">
</ul>
</div>
</div>
</div>
<div class="col xl5 l6 m12 s12" >
<div class="row">
<div class="col s12 center">
<h5>Addons</h5>
</div>
</div>
<div class="row">
<div class="col offset-s1 s11 xl10 offset-xl2">
<ul id="addons-div">
</ul>
</div>
</div>
</div>
</div>
<div class="row" style="margin-bottom: 5px;">