mirror of
https://github.com/Sebclem/hassio-nextcloud-backup.git
synced 2024-08-18 05:44:54 +02:00
🔨 Add clean functionality only for Cloud
This commit is contained in:
parent
bf8d271f4d
commit
c1a7016209
@ -4,4 +4,5 @@
|
|||||||
- `2` => Nextcloud config invalid
|
- `2` => Nextcloud config invalid
|
||||||
- `3` => Can't connect to nextcloud
|
- `3` => Can't connect to nextcloud
|
||||||
- `4` => Upload snap fail
|
- `4` => Upload snap fail
|
||||||
- `5` => Fail create new snap
|
- `5` => Fail create new snap
|
||||||
|
- `6` => Fail to clean
|
@ -5,7 +5,7 @@ const statusTools = require('../tools/status');
|
|||||||
const WebdavTools = require('../tools/webdavTools')
|
const WebdavTools = require('../tools/webdavTools')
|
||||||
const webdav = new WebdavTools().getInstance();
|
const webdav = new WebdavTools().getInstance();
|
||||||
const settingsTools = require('../tools/settingsTools');
|
const settingsTools = require('../tools/settingsTools');
|
||||||
|
const pathTools = require('../tools/pathTools');
|
||||||
const hassioApiTools = require('../tools/hassioApiTools');
|
const hassioApiTools = require('../tools/hassioApiTools');
|
||||||
|
|
||||||
const cronTools = require('../tools/cronTools');
|
const cronTools = require('../tools/cronTools');
|
||||||
@ -44,7 +44,7 @@ router.get('/formated-local-snap', function(req, res, next) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get('/formated-backup-manual', function(req, res, next) {
|
router.get('/formated-backup-manual', function(req, res, next) {
|
||||||
webdav.getFolderContent('/Hassio Backup/Manual/')
|
webdav.getFolderContent(pathTools.manual)
|
||||||
.then((contents) => {
|
.then((contents) => {
|
||||||
contents.sort((a, b) => {
|
contents.sort((a, b) => {
|
||||||
if (moment(a.lastmod).isBefore(moment(b.lastmod)))
|
if (moment(a.lastmod).isBefore(moment(b.lastmod)))
|
||||||
@ -58,8 +58,14 @@ router.get('/formated-backup-manual', function(req, res, next) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get('/formated-backup-auto', function(req, res, next) {
|
router.get('/formated-backup-auto', function(req, res, next) {
|
||||||
webdav.getFolderContent('/Hassio Backup/Auto/')
|
webdav.getFolderContent(pathTools.auto)
|
||||||
.then((contents) => {
|
.then((contents) => {
|
||||||
|
contents.sort((a, b) => {
|
||||||
|
if (moment(a.lastmod).isBefore(moment(b.lastmod)))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
})
|
||||||
res.render('backupSnaps',{backups: contents, moment: moment});
|
res.render('backupSnaps',{backups: contents, moment: moment});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -111,7 +117,7 @@ router.post('/manual-backup', function(req, res, next) {
|
|||||||
|
|
||||||
hassioApiTools.downloadSnapshot(id)
|
hassioApiTools.downloadSnapshot(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
webdav.uploadFile(id, '/Hassio Backup/Manual/' + name + '.tar');
|
webdav.uploadFile(id, pathTools.manual + name + '.tar');
|
||||||
res.status(201);
|
res.status(201);
|
||||||
res.send();
|
res.send();
|
||||||
})
|
})
|
||||||
@ -134,7 +140,7 @@ router.post('/new-backup', function(req, res, next) {
|
|||||||
hassioApiTools.createNewBackup(name).then((id) => {
|
hassioApiTools.createNewBackup(name).then((id) => {
|
||||||
hassioApiTools.downloadSnapshot(id)
|
hassioApiTools.downloadSnapshot(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
webdav.uploadFile(id, '/Hassio Backup/Manual/' + name + '.tar');
|
webdav.uploadFile(id, pathTools.manual + name + '.tar');
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -162,7 +168,11 @@ router.post('/backup-settings', function(req, res, next) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post('/clean-now', function(req, res, next){
|
||||||
|
webdav.clean();
|
||||||
|
res.status(201);
|
||||||
|
res.send()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ const hassioApiTools = require('./hassioApiTools');
|
|||||||
|
|
||||||
const statusTools = require('./status');
|
const statusTools = require('./status');
|
||||||
|
|
||||||
|
const pathTools = require('./pathTools');
|
||||||
|
|
||||||
var CronJob = require('cron').CronJob;
|
var CronJob = require('cron').CronJob;
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ function startCron() {
|
|||||||
cronContainer.init();
|
cronContainer.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatetNextDate(){
|
function updatetNextDate() {
|
||||||
let cronContainer = new Singleton().getInstance();
|
let cronContainer = new Singleton().getInstance();
|
||||||
cronContainer.updatetNextDate();
|
cronContainer.updatetNextDate();
|
||||||
}
|
}
|
||||||
@ -68,11 +70,11 @@ class CronContainer {
|
|||||||
this.cronJob.stop();
|
this.cronJob.stop();
|
||||||
this.cronJob = null;
|
this.cronJob = null;
|
||||||
}
|
}
|
||||||
if(!checkConfig(settingsTools.getSettings())){
|
if (!checkConfig(settingsTools.getSettings())) {
|
||||||
console.log("No Cron settings available.")
|
console.log("No Cron settings available.")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (settings.cron_base) {
|
switch (settings.cron_base) {
|
||||||
case '0':
|
case '0':
|
||||||
console.log("No Cron settings available.")
|
console.log("No Cron settings available.")
|
||||||
@ -105,7 +107,7 @@ class CronContainer {
|
|||||||
|
|
||||||
updatetNextDate() {
|
updatetNextDate() {
|
||||||
let date;
|
let date;
|
||||||
if( this.cronJob == null)
|
if (this.cronJob == null)
|
||||||
date = "Not configured";
|
date = "Not configured";
|
||||||
else
|
else
|
||||||
date = this.cronJob.nextDate().format('MMM D, YYYY HH:mm');
|
date = this.cronJob.nextDate().format('MMM D, YYYY HH:mm');
|
||||||
@ -116,14 +118,14 @@ class CronContainer {
|
|||||||
|
|
||||||
_createBackup() {
|
_createBackup() {
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
if(status.status == "creating" && status.status == "upload" && status.status == "download")
|
if (status.status == "creating" && status.status == "upload" && status.status == "download")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let name = 'Auto-' + moment().format('YYYY-MM-DD_HH:mm');
|
let name = 'Auto-' + moment().format('YYYY-MM-DD_HH:mm');
|
||||||
hassioApiTools.createNewBackup(name).then((id) => {
|
hassioApiTools.createNewBackup(name).then((id) => {
|
||||||
hassioApiTools.downloadSnapshot(id)
|
hassioApiTools.downloadSnapshot(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
webdav.uploadFile(id, '/Hassio Backup/Auto/' + name + '.tar');
|
webdav.uploadFile(id, pathTools.auto + name + '.tar');
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -131,6 +133,10 @@ class CronContainer {
|
|||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clean() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
let root = '/Hassio Backup/'
|
||||||
|
exports.root = root;
|
||||||
|
exports.manual = root + 'Manual/'
|
||||||
|
exports.auto = root + 'Auto/'
|
@ -5,6 +5,9 @@ const moment = require('moment');
|
|||||||
const statusTools = require('./status');
|
const statusTools = require('./status');
|
||||||
const endpoint = "/remote.php/webdav"
|
const endpoint = "/remote.php/webdav"
|
||||||
const configPath = "./webdav_conf.json"
|
const configPath = "./webdav_conf.json"
|
||||||
|
const path = require('path');
|
||||||
|
const settingsTools = require('./settingsTools');
|
||||||
|
const pathTools = require('./pathTools');
|
||||||
|
|
||||||
const request = require('request');
|
const request = require('request');
|
||||||
|
|
||||||
@ -62,9 +65,9 @@ class WebdavTools {
|
|||||||
|
|
||||||
initFolder() {
|
initFolder() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.client.createDirectory("/Hassio Backup").catch(() => { }).then(() => {
|
this.client.createDirectory(pathTools.root).catch(() => { }).then(() => {
|
||||||
this.client.createDirectory("/Hassio Backup/Auto").catch(() => { }).then(() => {
|
this.client.createDirectory(pathTools.auto).catch(() => { }).then(() => {
|
||||||
this.client.createDirectory("/Hassio Backup/Manual").catch(() => { }).then(() => {
|
this.client.createDirectory(pathTools.manual).catch(() => { }).then(() => {
|
||||||
resolve();
|
resolve();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -208,27 +211,65 @@ class WebdavTools {
|
|||||||
getFolderContent(path) {
|
getFolderContent(path) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.client.getDirectoryContents(path)
|
this.client.getDirectoryContents(path)
|
||||||
.then((contents)=>{
|
.then((contents) => {
|
||||||
resolve(contents);
|
resolve(contents);
|
||||||
}).catch((error)=>{
|
}).catch((error) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clean() {
|
||||||
|
let limit = settingsTools.getSettings().auto_clean_local_keep;
|
||||||
|
if(limit == null)
|
||||||
|
limit = 5;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.getFolderContent(pathTools.auto).then(async (contents) => {
|
||||||
|
if (contents.length < limit) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
contents.sort((a, b) => {
|
||||||
|
if (moment(a.lastmod).isBefore(moment(b.lastmod)))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
let toDel = contents.slice(limit);
|
||||||
|
for (let i in toDel) {
|
||||||
|
await this.client.deleteFile(toDel[i].filename);
|
||||||
|
}
|
||||||
|
console.log('Cloud clean done.')
|
||||||
|
resolve();
|
||||||
|
|
||||||
|
}).catch((error) => {
|
||||||
|
status.status = "error";
|
||||||
|
status.error_code = 6;
|
||||||
|
status.message = "Fail to clean Nexcloud ("+ error + ") !"
|
||||||
|
statusTools.setStatus(status);
|
||||||
|
console.error(status.message);
|
||||||
|
reject(status.message);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function cleanTempFolder(){
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanTempFolder() {
|
||||||
fs.readdir("./temp/", (err, files) => {
|
fs.readdir("./temp/", (err, files) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
fs.unlink(path.join("./temp/", file), err => {
|
fs.unlink(path.join("./temp/", file), err => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row hide">
|
<div class="row">
|
||||||
<div class="input-field col s3">
|
<div class="input-field col s3">
|
||||||
<input type="text" class="white-text" disabled readonly="true" id="local-snap-keep-read">
|
<input type="text" class="white-text" disabled readonly="true" id="local-snap-keep-read">
|
||||||
<label class="white-text active">Local snapshot to keep</label>
|
<label class="white-text active">Local snapshot to keep</label>
|
||||||
@ -343,7 +343,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row hide">
|
<div class="row">
|
||||||
<div class="input-field col s3">
|
<div class="input-field col s3">
|
||||||
<input type="text" class="white-text" disabled readonly="true" id="backup-snap-keep-read">
|
<input type="text" class="white-text" disabled readonly="true" id="backup-snap-keep-read">
|
||||||
<label class="white-text active">Nextcloud snapshot to keep</label>
|
<label class="white-text active">Nextcloud snapshot to keep</label>
|
||||||
@ -599,9 +599,11 @@
|
|||||||
|
|
||||||
function listeners() {
|
function listeners() {
|
||||||
$('#save-nextcloud-settings').click(sendNextcloudSettings);
|
$('#save-nextcloud-settings').click(sendNextcloudSettings);
|
||||||
$('#trigger-nextcloud-settings').click(getNextcloudSettings)
|
$('#trigger-nextcloud-settings').click(getNextcloudSettings);
|
||||||
$('#trigger-backup-settings').click(getBackupSettings)
|
$('#trigger-backup-settings').click(getBackupSettings);
|
||||||
$('#btn-backup-now').click(backupNow)
|
$('#btn-backup-now').click(backupNow);
|
||||||
|
$('#btn-clean-now').click(cleanNow);
|
||||||
|
|
||||||
|
|
||||||
$('#save-backup-settings').click(sendBackupSettings);
|
$('#save-backup-settings').click(sendBackupSettings);
|
||||||
$('#cron-drop-day-month').on('input', function() {
|
$('#cron-drop-day-month').on('input', function() {
|
||||||
@ -611,22 +613,10 @@
|
|||||||
$('#local-snap-keep').on('input', function() {
|
$('#local-snap-keep').on('input', function() {
|
||||||
$('#local-snap-keep-read').val($(this).val());
|
$('#local-snap-keep-read').val($(this).val());
|
||||||
});
|
});
|
||||||
$("#auto_clean_local").change(() => {
|
|
||||||
if ($("#auto_clean_local").is(':checked'))
|
|
||||||
$('#local-snap-keep').parent().parent().parent().removeClass("hide");
|
|
||||||
else
|
|
||||||
$('#local-snap-keep').parent().parent().parent().addClass("hide");
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#backup-snap-keep').on('input', function() {
|
$('#backup-snap-keep').on('input', function() {
|
||||||
$('#backup-snap-keep-read').val($(this).val());
|
$('#backup-snap-keep-read').val($(this).val());
|
||||||
});
|
});
|
||||||
$("#auto_clean_backup").change(() => {
|
|
||||||
if ($("#auto_clean_backup").is(':checked'))
|
|
||||||
$('#backup-snap-keep').parent().parent().parent().removeClass("hide");
|
|
||||||
else
|
|
||||||
$('#backup-snap-keep').parent().parent().parent().addClass("hide");
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -702,6 +692,19 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanNow(){
|
||||||
|
loadingModal.open();
|
||||||
|
$.post('./api/clean-now')
|
||||||
|
.done(() => {
|
||||||
|
M.toast({ html: '<i class="material-icons" style="margin-right:10px">check_box</i> Command send !', classes: "green" });
|
||||||
|
}).fail((error) => {
|
||||||
|
console.log(error);
|
||||||
|
M.toast({ html: '<i class="material-icons" style="margin-right:10px">warning</i> Can\'t send command !', classes: "red" });
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
loadingModal.close();
|
||||||
|
})
|
||||||
|
}
|
||||||
function getBackupSettings() {
|
function getBackupSettings() {
|
||||||
loadingModal.open();
|
loadingModal.open();
|
||||||
$.get('./api/backup-settings', (data) => {
|
$.get('./api/backup-settings', (data) => {
|
||||||
@ -712,9 +715,9 @@
|
|||||||
cron_weekday: "0",
|
cron_weekday: "0",
|
||||||
cron_month_day: "1",
|
cron_month_day: "1",
|
||||||
auto_clean_local: false,
|
auto_clean_local: false,
|
||||||
auto_clean_local_keep: 1,
|
auto_clean_local_keep: 5,
|
||||||
auto_clean_backup: false,
|
auto_clean_backup: false,
|
||||||
auto_clean_backup_keep: 1,
|
auto_clean_backup_keep: 5,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,15 +742,6 @@
|
|||||||
$('#auto_clean_backup').prop('checked', data.auto_clean_backup);
|
$('#auto_clean_backup').prop('checked', data.auto_clean_backup);
|
||||||
$('#backup-snap-keep-read, #backup-snap-keep').val(data.auto_clean_backup_keep);
|
$('#backup-snap-keep-read, #backup-snap-keep').val(data.auto_clean_backup_keep);
|
||||||
|
|
||||||
if ($("#auto_clean_backup").is(':checked'))
|
|
||||||
$('#backup-snap-keep').parent().parent().parent().removeClass("hide");
|
|
||||||
else
|
|
||||||
$('#backup-snap-keep').parent().parent().parent().addClass("hide");
|
|
||||||
|
|
||||||
if ($("#auto_clean_local").is(':checked'))
|
|
||||||
$('#local-snap-keep').parent().parent().parent().removeClass("hide");
|
|
||||||
else
|
|
||||||
$('#local-snap-keep').parent().parent().parent().addClass("hide");
|
|
||||||
|
|
||||||
$('#backup-snap-keep-read + label').removeClass("active");
|
$('#backup-snap-keep-read + label').removeClass("active");
|
||||||
$('#backup-snap-keep-read + label').addClass("active");
|
$('#backup-snap-keep-read + label').addClass("active");
|
||||||
|
Loading…
Reference in New Issue
Block a user