diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md b/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md index e8fae6b..da5bd01 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/error_code.md @@ -4,4 +4,5 @@ - `2` => Nextcloud config invalid - `3` => Can't connect to nextcloud - `4` => Upload snap fail -- `5` => Fail create new snap \ No newline at end of file +- `5` => Fail create new snap +- `6` => Fail to clean \ No newline at end of file diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js index 11ba9eb..fa67183 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js @@ -5,7 +5,7 @@ const statusTools = require('../tools/status'); const WebdavTools = require('../tools/webdavTools') const webdav = new WebdavTools().getInstance(); const settingsTools = require('../tools/settingsTools'); - +const pathTools = require('../tools/pathTools'); const hassioApiTools = require('../tools/hassioApiTools'); 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) { - webdav.getFolderContent('/Hassio Backup/Manual/') + webdav.getFolderContent(pathTools.manual) .then((contents) => { contents.sort((a, b) => { 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) { - webdav.getFolderContent('/Hassio Backup/Auto/') + webdav.getFolderContent(pathTools.auto) .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}); }); @@ -111,7 +117,7 @@ router.post('/manual-backup', function(req, res, next) { hassioApiTools.downloadSnapshot(id) .then(() => { - webdav.uploadFile(id, '/Hassio Backup/Manual/' + name + '.tar'); + webdav.uploadFile(id, pathTools.manual + name + '.tar'); res.status(201); res.send(); }) @@ -134,7 +140,7 @@ router.post('/new-backup', function(req, res, next) { hassioApiTools.createNewBackup(name).then((id) => { hassioApiTools.downloadSnapshot(id) .then(() => { - webdav.uploadFile(id, '/Hassio Backup/Manual/' + name + '.tar'); + webdav.uploadFile(id, pathTools.manual + name + '.tar'); }).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() +}); diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js index cacab79..3345602 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js @@ -7,6 +7,8 @@ const hassioApiTools = require('./hassioApiTools'); const statusTools = require('./status'); +const pathTools = require('./pathTools'); + var CronJob = require('cron').CronJob; const moment = require('moment'); @@ -49,7 +51,7 @@ function startCron() { cronContainer.init(); } -function updatetNextDate(){ +function updatetNextDate() { let cronContainer = new Singleton().getInstance(); cronContainer.updatetNextDate(); } @@ -68,11 +70,11 @@ class CronContainer { this.cronJob.stop(); this.cronJob = null; } - if(!checkConfig(settingsTools.getSettings())){ + if (!checkConfig(settingsTools.getSettings())) { console.log("No Cron settings available.") return; } - + switch (settings.cron_base) { case '0': console.log("No Cron settings available.") @@ -105,7 +107,7 @@ class CronContainer { updatetNextDate() { let date; - if( this.cronJob == null) + if (this.cronJob == null) date = "Not configured"; else date = this.cronJob.nextDate().format('MMM D, YYYY HH:mm'); @@ -116,14 +118,14 @@ class CronContainer { _createBackup() { 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; - + let name = 'Auto-' + moment().format('YYYY-MM-DD_HH:mm'); hassioApiTools.createNewBackup(name).then((id) => { hassioApiTools.downloadSnapshot(id) .then(() => { - webdav.uploadFile(id, '/Hassio Backup/Auto/' + name + '.tar'); + webdav.uploadFile(id, pathTools.auto + name + '.tar'); }).catch(() => { }) @@ -131,6 +133,10 @@ class CronContainer { }) } + + clean() { + + } } diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/pathTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/pathTools.js new file mode 100644 index 0000000..80e1326 --- /dev/null +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/pathTools.js @@ -0,0 +1,4 @@ +let root = '/Hassio Backup/' +exports.root = root; +exports.manual = root + 'Manual/' +exports.auto = root + 'Auto/' \ No newline at end of file diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js index 503420e..37883a4 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js @@ -5,6 +5,9 @@ const moment = require('moment'); const statusTools = require('./status'); const endpoint = "/remote.php/webdav" const configPath = "./webdav_conf.json" +const path = require('path'); +const settingsTools = require('./settingsTools'); +const pathTools = require('./pathTools'); const request = require('request'); @@ -62,9 +65,9 @@ class WebdavTools { initFolder() { return new Promise((resolve, reject) => { - this.client.createDirectory("/Hassio Backup").catch(() => { }).then(() => { - this.client.createDirectory("/Hassio Backup/Auto").catch(() => { }).then(() => { - this.client.createDirectory("/Hassio Backup/Manual").catch(() => { }).then(() => { + this.client.createDirectory(pathTools.root).catch(() => { }).then(() => { + this.client.createDirectory(pathTools.auto).catch(() => { }).then(() => { + this.client.createDirectory(pathTools.manual).catch(() => { }).then(() => { resolve(); }) }) @@ -208,27 +211,65 @@ class WebdavTools { getFolderContent(path) { return new Promise((resolve, reject) => { this.client.getDirectoryContents(path) - .then((contents)=>{ + .then((contents) => { resolve(contents); - }).catch((error)=>{ + }).catch((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) => { if (err) throw err; - + for (const file of files) { - fs.unlink(path.join("./temp/", file), err => { - if (err) throw err; - }); + fs.unlink(path.join("./temp/", file), err => { + if (err) throw err; + }); } - }); + }); } diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/views/index.ejs b/nextcloud_backup/rootfs/opt/nextcloud_backup/views/index.ejs index a1740ab..a9cd5c6 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/views/index.ejs +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/views/index.ejs @@ -318,7 +318,7 @@ -
+
@@ -343,7 +343,7 @@
-
+
@@ -599,9 +599,11 @@ function listeners() { $('#save-nextcloud-settings').click(sendNextcloudSettings); - $('#trigger-nextcloud-settings').click(getNextcloudSettings) - $('#trigger-backup-settings').click(getBackupSettings) - $('#btn-backup-now').click(backupNow) + $('#trigger-nextcloud-settings').click(getNextcloudSettings); + $('#trigger-backup-settings').click(getBackupSettings); + $('#btn-backup-now').click(backupNow); + $('#btn-clean-now').click(cleanNow); + $('#save-backup-settings').click(sendBackupSettings); $('#cron-drop-day-month').on('input', function() { @@ -611,22 +613,10 @@ $('#local-snap-keep').on('input', function() { $('#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-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: 'check_box Command send !', classes: "green" }); + }).fail((error) => { + console.log(error); + M.toast({ html: 'warning Can\'t send command !', classes: "red" }); + }) + .always(() => { + loadingModal.close(); + }) + } function getBackupSettings() { loadingModal.open(); $.get('./api/backup-settings', (data) => { @@ -712,9 +715,9 @@ cron_weekday: "0", cron_month_day: "1", auto_clean_local: false, - auto_clean_local_keep: 1, + auto_clean_local_keep: 5, 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); $('#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').addClass("active");