mirror of
https://github.com/Sebclem/hassio-nextcloud-backup.git
synced 2024-08-19 06:04:56 +02:00
✏️ Clean code with prettier
This commit is contained in:
parent
1237f9c6ff
commit
8632a3d079
@ -2,19 +2,14 @@ module.exports = {
|
|||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"commonjs": true,
|
"commonjs": true,
|
||||||
"es6": true,
|
"es2021": true,
|
||||||
"node": true
|
"node": true
|
||||||
},
|
},
|
||||||
"extends": "eslint:recommended",
|
"extends": ["eslint:recommended","prettier"],
|
||||||
"globals": {
|
|
||||||
"Atomics": "readonly",
|
|
||||||
"SharedArrayBuffer": "readonly"
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2018
|
"ecmaVersion": 12
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-unused-vars": "warn"
|
"no-unused-vars": "warn"
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,30 +1,31 @@
|
|||||||
const createError = require('http-errors');
|
const createError = require("http-errors");
|
||||||
const express = require('express');
|
const express = require("express");
|
||||||
const path = require('path');
|
const path = require("path");
|
||||||
const cookieParser = require('cookie-parser');
|
const cookieParser = require("cookie-parser");
|
||||||
const logger = require('morgan');
|
const logger = require("morgan");
|
||||||
|
|
||||||
|
const indexRouter = require("./routes/index");
|
||||||
const indexRouter = require('./routes/index');
|
const apiRouter = require("./routes/api");
|
||||||
const apiRouter = require('./routes/api');
|
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
// view engine setup
|
// view engine setup
|
||||||
app.set('views', path.join(__dirname, 'views'));
|
app.set("views", path.join(__dirname, "views"));
|
||||||
app.set('view engine', 'ejs');
|
app.set("view engine", "ejs");
|
||||||
|
|
||||||
app.use(logger('dev', {
|
app.use(
|
||||||
|
logger("dev", {
|
||||||
skip: function (req, res) {
|
skip: function (req, res) {
|
||||||
return res.statusCode = 304
|
return (res.statusCode = 304);
|
||||||
}
|
},
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(express.urlencoded({extended: false}));
|
app.use(express.urlencoded({ extended: false }));
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.static(path.join(__dirname, 'public')));
|
app.use(express.static(path.join(__dirname, "public")));
|
||||||
|
|
||||||
app.use('/', indexRouter);
|
app.use("/", indexRouter);
|
||||||
app.use('/api', apiRouter);
|
app.use("/api", apiRouter);
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
@ -35,43 +36,43 @@ app.use(function (req, res, next) {
|
|||||||
app.use(function (err, req, res, next) {
|
app.use(function (err, req, res, next) {
|
||||||
// set locals, only providing error in development
|
// set locals, only providing error in development
|
||||||
res.locals.message = err.message;
|
res.locals.message = err.message;
|
||||||
res.locals.error = req.app.get('env') === 'development' ? err : {};
|
res.locals.error = req.app.get("env") === "development" ? err : {};
|
||||||
|
|
||||||
// render the error page
|
// render the error page
|
||||||
res.status(err.status || 500);
|
res.status(err.status || 500);
|
||||||
res.render('error');
|
res.render("error");
|
||||||
});
|
});
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
const newlog = require('./config/winston');
|
const newlog = require("./config/winston");
|
||||||
if (!fs.existsSync('/data'))
|
if (!fs.existsSync("/data")) fs.mkdirSync("/data");
|
||||||
fs.mkdirSync('/data');
|
const statusTools = require("./tools/status");
|
||||||
const statusTools = require('./tools/status');
|
|
||||||
statusTools.init();
|
statusTools.init();
|
||||||
newlog.info("Satus : \x1b[32mGo !\x1b[0m");
|
newlog.info("Satus : \x1b[32mGo !\x1b[0m");
|
||||||
const hassioApiTools = require('./tools/hassioApiTools');
|
const hassioApiTools = require("./tools/hassioApiTools");
|
||||||
hassioApiTools.getSnapshots().then(
|
hassioApiTools.getSnapshots().then(
|
||||||
() => {
|
() => {
|
||||||
newlog.info("Hassio API : \x1b[32mGo !\x1b[0m")
|
newlog.info("Hassio API : \x1b[32mGo !\x1b[0m");
|
||||||
|
},
|
||||||
}, (err) => {
|
(err) => {
|
||||||
newlog.error("Hassio API : \x1b[31;1mFAIL !\x1b[0m")
|
newlog.error("Hassio API : \x1b[31;1mFAIL !\x1b[0m");
|
||||||
newlog.error("... " + err);
|
newlog.error("... " + err);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const WebdavTools = require('./tools/webdavTools');
|
const WebdavTools = require("./tools/webdavTools");
|
||||||
const webdav = new WebdavTools().getInstance();
|
const webdav = new WebdavTools().getInstance();
|
||||||
webdav.confIsValid().then(
|
webdav.confIsValid().then(
|
||||||
() => {
|
() => {
|
||||||
newlog.info("Nextcloud connection : \x1b[32mGo !\x1b[0m")
|
newlog.info("Nextcloud connection : \x1b[32mGo !\x1b[0m");
|
||||||
}, (err) => {
|
},
|
||||||
newlog.error("Nextcloud connection : \x1b[31;1mFAIL !\x1b[0m")
|
(err) => {
|
||||||
|
newlog.error("Nextcloud connection : \x1b[31;1mFAIL !\x1b[0m");
|
||||||
newlog.error("... " + err);
|
newlog.error("... " + err);
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
const cronTools = require('./tools/cronTools');
|
const cronTools = require("./tools/cronTools");
|
||||||
cronTools.startCron();
|
cronTools.startCron();
|
||||||
|
|
||||||
|
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
const appRoot = require('app-root-path');
|
const appRoot = require("app-root-path");
|
||||||
const winston = require('winston');
|
const winston = require("winston");
|
||||||
|
|
||||||
|
|
||||||
const logger = winston.createLogger({
|
const logger = winston.createLogger({
|
||||||
level: 'debug',
|
level: "debug",
|
||||||
format: winston.format.combine(
|
format: winston.format.combine(
|
||||||
winston.format.timestamp({
|
winston.format.timestamp({
|
||||||
format: 'YYYY-MM-DD HH:mm:ss'
|
format: "YYYY-MM-DD HH:mm:ss",
|
||||||
}),
|
}),
|
||||||
// winston.format.errors({ stack: true }),
|
// winston.format.errors({ stack: true }),
|
||||||
// winston.format.splat(),
|
// winston.format.splat(),
|
||||||
|
|
||||||
winston.format.colorize(),
|
winston.format.colorize(),
|
||||||
winston.format.printf(({level, message, timestamp}) => {
|
winston.format.printf(({ level, message, timestamp }) => {
|
||||||
return `[${timestamp}] [${level}]: ${message}`;
|
return `[${timestamp}] [${level}]: ${message}`;
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
@ -21,10 +20,9 @@ const logger = winston.createLogger({
|
|||||||
// - Write to all logs with level `info` and below to `quick-start-combined.log`.
|
// - Write to all logs with level `info` and below to `quick-start-combined.log`.
|
||||||
// - Write all logs error (and below) to `quick-start-error.log`.
|
// - Write all logs error (and below) to `quick-start-error.log`.
|
||||||
//
|
//
|
||||||
new winston.transports.Console({handleExceptions: true}),
|
new winston.transports.Console({ handleExceptions: true }),
|
||||||
// new winston.transports.File({filename: '/data/NCB.log', handleExceptions: true})
|
// new winston.transports.File({filename: '/data/NCB.log', handleExceptions: true})
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
module.exports = logger;
|
module.exports = logger;
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,10 @@
|
|||||||
"winston": "^3.2.1"
|
"winston": "^3.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^7.13.0",
|
||||||
"eslint-config-google": "^0.14.0"
|
"eslint-config-eslint": "^6.0.0",
|
||||||
|
"eslint-config-prettier": "^6.15.0",
|
||||||
|
"eslint-plugin-import": "^2.22.1",
|
||||||
|
"eslint-plugin-node": "^11.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,122 +1,106 @@
|
|||||||
const express = require('express');
|
const express = require("express");
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const moment = require('moment');
|
const moment = require("moment");
|
||||||
const statusTools = require('../tools/status');
|
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 pathTools = require("../tools/pathTools");
|
||||||
const hassioApiTools = require('../tools/hassioApiTools');
|
const hassioApiTools = require("../tools/hassioApiTools");
|
||||||
const humanFileSize = require('../tools/toolbox').humanFileSize;
|
const humanFileSize = require("../tools/toolbox").humanFileSize;
|
||||||
|
|
||||||
const cronTools = require('../tools/cronTools');
|
const cronTools = require("../tools/cronTools");
|
||||||
|
|
||||||
const logger = require('../config/winston');
|
const logger = require("../config/winston");
|
||||||
|
|
||||||
|
router.get("/status", (req, res, next) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
router.get('/status', (req, res, next) => {
|
|
||||||
cronTools.updatetNextDate();
|
cronTools.updatetNextDate();
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
res.json(status);
|
res.json(status);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get("/formated-local-snap", function (req, res, next) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
router.get('/formated-local-snap', function(req, res, next) {
|
|
||||||
hassioApiTools.getSnapshots().then(
|
hassioApiTools.getSnapshots().then(
|
||||||
(snaps) => {
|
(snaps) => {
|
||||||
snaps.sort((a, b) => {
|
snaps.sort((a, b) => {
|
||||||
if (moment(a.date).isBefore(moment(b.date))){
|
if (moment(a.date).isBefore(moment(b.date))) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
})
|
res.render("localSnaps", { snaps: snaps, moment: moment });
|
||||||
res.render('localSnaps', { snaps: snaps, moment: moment });
|
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
res.status(500);
|
res.status(500);
|
||||||
res.send('');
|
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)
|
webdav
|
||||||
|
.getFolderContent(webdav.getConf().back_dir + 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))) return 1;
|
||||||
return 1;
|
else return -1;
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
})
|
|
||||||
res.render('backupSnaps',{backups: contents, moment: moment, humanFileSize: humanFileSize});
|
|
||||||
}).catch(()=>{
|
|
||||||
res.send();
|
|
||||||
});
|
});
|
||||||
|
res.render("backupSnaps", { backups: contents, moment: moment, humanFileSize: humanFileSize });
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/formated-backup-auto', function(req, res, next) {
|
|
||||||
let url = webdav.getConf().back_dir + pathTools.auto
|
|
||||||
webdav.getFolderContent( url )
|
|
||||||
.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, humanFileSize: humanFileSize});
|
.catch(() => {
|
||||||
}).catch(()=>{
|
|
||||||
res.send();
|
res.send();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get("/formated-backup-auto", function (req, res, next) {
|
||||||
|
let url = webdav.getConf().back_dir + pathTools.auto;
|
||||||
|
webdav
|
||||||
|
.getFolderContent(url)
|
||||||
|
.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, humanFileSize: humanFileSize });
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
res.send();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post("/nextcloud-settings", function (req, res, next) {
|
||||||
router.post('/nextcloud-settings', function(req, res, next) {
|
|
||||||
let settings = req.body;
|
let settings = req.body;
|
||||||
if (settings.ssl != null && settings.host != null && settings.host != "" && settings.username != null && settings.password != null) {
|
if (settings.ssl != null && settings.host != null && settings.host != "" && settings.username != null && settings.password != null) {
|
||||||
webdav.setConf(settings);
|
webdav.setConf(settings);
|
||||||
webdav.confIsValid().then(() => {
|
webdav
|
||||||
|
.confIsValid()
|
||||||
|
.then(() => {
|
||||||
res.status(201);
|
res.status(201);
|
||||||
res.send();
|
res.send();
|
||||||
}).catch((err) => {
|
})
|
||||||
|
.catch((err) => {
|
||||||
res.status(406);
|
res.status(406);
|
||||||
res.json({ message: err });
|
res.json({ message: err });
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
res.status(400);
|
res.status(400);
|
||||||
res.send();
|
res.send();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/nextcloud-settings', function(req, res, next) {
|
router.get("/nextcloud-settings", function (req, res, next) {
|
||||||
let conf = webdav.getConf();
|
let conf = webdav.getConf();
|
||||||
if (conf == null) {
|
if (conf == null) {
|
||||||
res.status(404);
|
res.status(404);
|
||||||
res.send();
|
res.send();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
res.json(conf);
|
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 id = req.query.id;
|
||||||
let name = req.query.name;
|
let name = req.query.name;
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
@ -126,84 +110,81 @@ router.post('/manual-backup', function(req, res, next) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hassioApiTools.downloadSnapshot(id)
|
hassioApiTools
|
||||||
|
.downloadSnapshot(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + '.tar');
|
webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + ".tar");
|
||||||
res.status(201);
|
res.status(201);
|
||||||
res.send();
|
res.send();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
res.status(500)
|
res.status(500);
|
||||||
res.send();
|
res.send();
|
||||||
})
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/new-backup', function(req, res, next) {
|
router.post("/new-backup", function (req, res, next) {
|
||||||
|
|
||||||
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") {
|
||||||
res.status(503);
|
res.status(503);
|
||||||
res.send();
|
res.send();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let name = 'Manual-' + moment().format('YYYY-MM-DD_HH-mm');
|
let name = "Manual-" + moment().format("YYYY-MM-DD_HH-mm");
|
||||||
hassioApiTools.createNewBackup(name).then((id) => {
|
hassioApiTools
|
||||||
hassioApiTools.downloadSnapshot(id)
|
.createNewBackup(name)
|
||||||
|
.then((id) => {
|
||||||
|
hassioApiTools
|
||||||
|
.downloadSnapshot(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + '.tar');
|
webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + ".tar");
|
||||||
}).catch(() => {
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}).catch(() => {
|
.catch(() => {});
|
||||||
|
|
||||||
})
|
})
|
||||||
|
.catch(() => {});
|
||||||
res.status(201);
|
res.status(201);
|
||||||
res.send();
|
res.send();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get("/backup-settings", function (req, res, next) {
|
||||||
router.get('/backup-settings', function(req, res, next) {
|
|
||||||
res.send(settingsTools.getSettings());
|
res.send(settingsTools.getSettings());
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/backup-settings', function(req, res, next) {
|
router.post("/backup-settings", function (req, res, next) {
|
||||||
if (cronTools.checkConfig(req.body)) {
|
if (cronTools.checkConfig(req.body)) {
|
||||||
settingsTools.setSettings(req.body);
|
settingsTools.setSettings(req.body);
|
||||||
cronTools.startCron();
|
cronTools.startCron();
|
||||||
res.send();
|
res.send();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
res.status(400);
|
res.status(400);
|
||||||
res.send();
|
res.send();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/clean-now', function(req, res, next){
|
router.post("/clean-now", function (req, res, next) {
|
||||||
webdav.clean().then(()=>{
|
webdav
|
||||||
|
.clean()
|
||||||
|
.then(() => {
|
||||||
hassioApiTools.clean().catch();
|
hassioApiTools.clean().catch();
|
||||||
}).catch(()=>{
|
})
|
||||||
|
.catch(() => {
|
||||||
hassioApiTools.clean().catch();
|
hassioApiTools.clean().catch();
|
||||||
});
|
});
|
||||||
res.status(201);
|
res.status(201);
|
||||||
res.send()
|
res.send();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post("/restore", function (req, res, next) {
|
||||||
router.post('/restore', function(req, res, next){
|
if (req.body["path"] != null) {
|
||||||
if(req.body['path'] != null){
|
webdav.downloadFile(req.body["path"]).then((path) => {
|
||||||
webdav.downloadFile(req.body['path'] ).then((path)=>{
|
|
||||||
hassioApiTools.uploadSnapshot(path);
|
hassioApiTools.uploadSnapshot(path);
|
||||||
});
|
});
|
||||||
res.status(200);
|
res.status(200);
|
||||||
res.send()
|
res.send();
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
res.status(400);
|
res.status(400);
|
||||||
res.send()
|
res.send();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
const express = require('express');
|
const express = require("express");
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
router.get('/', function(req, res, next) {
|
router.get("/", function (req, res, next) {
|
||||||
res.render('index');
|
res.render("index");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -1,43 +1,36 @@
|
|||||||
const settingsTools = require('./settingsTools');
|
const settingsTools = require("./settingsTools");
|
||||||
|
|
||||||
const WebdavTools = require('./webdavTools');
|
const WebdavTools = require("./webdavTools");
|
||||||
const webdav = new WebdavTools().getInstance();
|
const webdav = new WebdavTools().getInstance();
|
||||||
|
|
||||||
const hassioApiTools = require('./hassioApiTools');
|
const hassioApiTools = require("./hassioApiTools");
|
||||||
|
|
||||||
const statusTools = require('./status');
|
const statusTools = require("./status");
|
||||||
|
|
||||||
const pathTools = require('./pathTools');
|
const pathTools = require("./pathTools");
|
||||||
|
|
||||||
const CronJob = require('cron').CronJob;
|
|
||||||
const moment = require('moment');
|
|
||||||
const logger = require('../config/winston');
|
|
||||||
|
|
||||||
|
const CronJob = require("cron").CronJob;
|
||||||
|
const moment = require("moment");
|
||||||
|
const logger = require("../config/winston");
|
||||||
|
|
||||||
function checkConfig(conf) {
|
function checkConfig(conf) {
|
||||||
if (conf.cron_base != null) {
|
if (conf.cron_base != null) {
|
||||||
if (conf.cron_base === '1' || conf.cron_base === '2' || conf.cron_base === '3') {
|
if (conf.cron_base === "1" || conf.cron_base === "2" || conf.cron_base === "3") {
|
||||||
if (conf.cron_hour != null && conf.cron_hour.match(/\d\d:\d\d/)) {
|
if (conf.cron_hour != null && conf.cron_hour.match(/\d\d:\d\d/)) {
|
||||||
if (conf.cron_base === '1')
|
if (conf.cron_base === "1") return true;
|
||||||
return true;
|
} else return false;
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.cron_base === '2') {
|
if (conf.cron_base === "2") {
|
||||||
return conf.cron_weekday != null && conf.cron_weekday >= 0 && conf.cron_weekday <= 6;
|
return conf.cron_weekday != null && conf.cron_weekday >= 0 && conf.cron_weekday <= 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.cron_base === '3') {
|
if (conf.cron_base === "3") {
|
||||||
return conf.cron_month_day != null && conf.cron_month_day >= 1 && conf.cron_month_day <= 28;
|
return conf.cron_month_day != null && conf.cron_month_day >= 1 && conf.cron_month_day <= 28;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.cron_base === '0')
|
if (conf.cron_base === "0") return true;
|
||||||
return true
|
} else return false;
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -52,11 +45,10 @@ function updatetNextDate() {
|
|||||||
cronContainer.updatetNextDate();
|
cronContainer.updatetNextDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CronContainer {
|
class CronContainer {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.cronJob = null;
|
this.cronJob = null;
|
||||||
this.cronClean = null
|
this.cronClean = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -64,7 +56,7 @@ class CronContainer {
|
|||||||
let cronStr = "";
|
let cronStr = "";
|
||||||
if (this.cronClean == null) {
|
if (this.cronClean == null) {
|
||||||
logger.info("Starting auto clean cron...");
|
logger.info("Starting auto clean cron...");
|
||||||
this.cronClean = new CronJob('0 1 * * *', this._clean, null, false, Intl.DateTimeFormat().resolvedOptions().timeZone);
|
this.cronClean = new CronJob("0 1 * * *", this._clean, null, false, Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||||
this.cronClean.start();
|
this.cronClean.start();
|
||||||
}
|
}
|
||||||
if (this.cronJob != null) {
|
if (this.cronJob != null) {
|
||||||
@ -78,28 +70,26 @@ class CronContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (settings.cron_base) {
|
switch (settings.cron_base) {
|
||||||
case '0':
|
case "0":
|
||||||
logger.warn("No Cron settings available.");
|
logger.warn("No Cron settings available.");
|
||||||
return;
|
return;
|
||||||
case '1': {
|
case "1": {
|
||||||
let splited = settings.cron_hour.split(':');
|
let splited = settings.cron_hour.split(":");
|
||||||
cronStr = "" + splited[1] + " " + splited[0] + " * * *";
|
cronStr = "" + splited[1] + " " + splited[0] + " * * *";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '2': {
|
case "2": {
|
||||||
let splited = settings.cron_hour.split(':');
|
let splited = settings.cron_hour.split(":");
|
||||||
cronStr = "" + splited[1] + " " + splited[0] + " * * " + settings.cron_weekday;
|
cronStr = "" + splited[1] + " " + splited[0] + " * * " + settings.cron_weekday;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '3': {
|
case "3": {
|
||||||
let splited = settings.cron_hour.split(':');
|
let splited = settings.cron_hour.split(":");
|
||||||
cronStr = "" + splited[1] + " " + splited[0] + " " + settings.cron_month_day + " * *";
|
cronStr = "" + splited[1] + " " + splited[0] + " " + settings.cron_month_day + " * *";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
logger.info("Starting Cron...");
|
logger.info("Starting Cron...");
|
||||||
this.cronJob = new CronJob(cronStr, this._createBackup, null, false, Intl.DateTimeFormat().resolvedOptions().timeZone);
|
this.cronJob = new CronJob(cronStr, this._createBackup, null, false, Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||||
@ -109,32 +99,30 @@ class CronContainer {
|
|||||||
|
|
||||||
updatetNextDate() {
|
updatetNextDate() {
|
||||||
let date;
|
let date;
|
||||||
if (this.cronJob == null)
|
if (this.cronJob == null) date = "Not configured";
|
||||||
date = "Not configured";
|
else date = this.cronJob.nextDate().format("MMM D, YYYY HH:mm");
|
||||||
else
|
|
||||||
date = this.cronJob.nextDate().format('MMM D, YYYY HH:mm');
|
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
status.next_backup = date;
|
status.next_backup = date;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBackup() {
|
_createBackup() {
|
||||||
logger.debug('Cron triggered !');
|
logger.debug("Cron triggered !");
|
||||||
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
|
||||||
hassioApiTools.downloadSnapshot(id)
|
.createNewBackup(name)
|
||||||
|
.then((id) => {
|
||||||
|
hassioApiTools
|
||||||
|
.downloadSnapshot(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.auto + name + '.tar');
|
webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.auto + name + ".tar");
|
||||||
}).catch(() => {
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}).catch(() => {
|
.catch(() => {});
|
||||||
|
|
||||||
})
|
})
|
||||||
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
_clean() {
|
_clean() {
|
||||||
@ -146,11 +134,9 @@ class CronContainer {
|
|||||||
if (autoCleanCloud != null && autoCleanCloud === "true") {
|
if (autoCleanCloud != null && autoCleanCloud === "true") {
|
||||||
webdav.clean().catch(() => {});
|
webdav.clean().catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Singleton {
|
class Singleton {
|
||||||
constructor() {
|
constructor() {
|
||||||
if (!Singleton.instance) {
|
if (!Singleton.instance) {
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
const statusTools = require('./status');
|
const fs = require("fs");
|
||||||
const fs = require('fs');
|
|
||||||
const settingsTools = require('./settingsTools');
|
const moment = require("moment");
|
||||||
const moment = require('moment');
|
const stream = require("stream");
|
||||||
const logger = require('../config/winston');
|
const { promisify } = require("util");
|
||||||
const stream = require('stream');
|
|
||||||
const {promisify} = require('util');
|
|
||||||
const pipeline = promisify(stream.pipeline);
|
const pipeline = promisify(stream.pipeline);
|
||||||
const got = require ('got');
|
const got = require("got");
|
||||||
const FormData = require('form-data');
|
const FormData = require("form-data");
|
||||||
|
const statusTools = require("./status");
|
||||||
const create_snap_timeout = 90 * 60 * 1000
|
const settingsTools = require("./settingsTools");
|
||||||
|
const logger = require("../config/winston");
|
||||||
|
|
||||||
|
const create_snap_timeout = 90 * 60 * 1000;
|
||||||
|
|
||||||
function getSnapshots() {
|
function getSnapshots() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let token = process.env.HASSIO_TOKEN;
|
let token = process.env.HASSIO_TOKEN;
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
let option = {
|
let option = {
|
||||||
headers: { 'X-HASSIO-KEY': token },
|
headers: { "X-HASSIO-KEY": token },
|
||||||
responseType: 'json'
|
responseType: "json",
|
||||||
};
|
};
|
||||||
|
|
||||||
got("http://hassio/snapshots", option)
|
got("http://hassio/snapshots", option)
|
||||||
@ -42,41 +42,43 @@ function getSnapshots() {
|
|||||||
reject(error.message);
|
reject(error.message);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadSnapshot(id) {
|
function downloadSnapshot(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
logger.info(`Downloading snapshot ${id}...`);
|
logger.info(`Downloading snapshot ${id}...`);
|
||||||
if (!fs.existsSync('./temp/'))
|
if (!fs.existsSync("./temp/")) fs.mkdirSync("./temp/");
|
||||||
fs.mkdirSync('./temp/');
|
let tmp_file = `./temp/${id}.tar`;
|
||||||
let tmp_file = `./temp/${id}.tar`
|
|
||||||
let stream = fs.createWriteStream(tmp_file);
|
let stream = fs.createWriteStream(tmp_file);
|
||||||
let token = process.env.HASSIO_TOKEN;
|
let token = process.env.HASSIO_TOKEN;
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
checkSnap(id).then(() => {
|
checkSnap(id)
|
||||||
|
.then(() => {
|
||||||
status.status = "download";
|
status.status = "download";
|
||||||
status.progress = 0;
|
status.progress = 0;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
let option = {
|
let option = {
|
||||||
headers: { 'X-HASSIO-KEY': token },
|
headers: { "X-HASSIO-KEY": token },
|
||||||
};
|
};
|
||||||
|
|
||||||
pipeline(got.stream.get(`http://hassio/snapshots/${id}/download`, option)
|
pipeline(
|
||||||
.on('downloadProgress', e => {
|
got.stream.get(`http://hassio/snapshots/${id}/download`, option).on("downloadProgress", (e) => {
|
||||||
let percent = Math.round(e.percent * 100) / 100;
|
let percent = Math.round(e.percent * 100) / 100;
|
||||||
if (status.progress != percent) {
|
if (status.progress != percent) {
|
||||||
status.progress = percent;
|
status.progress = percent;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
}
|
}
|
||||||
}), stream)
|
}),
|
||||||
.then((res)=>{
|
stream
|
||||||
logger.info('Download success !')
|
)
|
||||||
|
.then((res) => {
|
||||||
|
logger.info("Download success !");
|
||||||
status.progress = 1;
|
status.progress = 1;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.debug("Snapshot dl size : " + (fs.statSync(tmp_file).size / 1024 / 1024));
|
logger.debug("Snapshot dl size : " + fs.statSync(tmp_file).size / 1024 / 1024);
|
||||||
resolve();
|
resolve();
|
||||||
}).catch((err)=>{
|
})
|
||||||
|
.catch((err) => {
|
||||||
fs.unlinkSync(tmp_file);
|
fs.unlinkSync(tmp_file);
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.message = "Fail to download Hassio snapshot (" + err.message + ")";
|
status.message = "Fail to download Hassio snapshot (" + err.message + ")";
|
||||||
@ -84,8 +86,9 @@ function downloadSnapshot(id) {
|
|||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject(err.message);
|
reject(err.message);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}).catch((err) => {
|
.catch((err) => {
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.message = "Fail to download Hassio snapshot. Not found ?";
|
status.message = "Fail to download Hassio snapshot. Not found ?";
|
||||||
status.error_code = 7;
|
status.error_code = 7;
|
||||||
@ -93,18 +96,18 @@ function downloadSnapshot(id) {
|
|||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject();
|
reject();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function dellSnap(id) {
|
function dellSnap(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
checkSnap(id).then(() => {
|
checkSnap(id)
|
||||||
|
.then(() => {
|
||||||
let token = process.env.HASSIO_TOKEN;
|
let token = process.env.HASSIO_TOKEN;
|
||||||
|
|
||||||
let option = {
|
let option = {
|
||||||
headers: { 'X-HASSIO-KEY': token },
|
headers: { "X-HASSIO-KEY": token },
|
||||||
responseType: 'json'
|
responseType: "json",
|
||||||
};
|
};
|
||||||
|
|
||||||
got.post(`http://hassio/snapshots/${id}/remove`, option)
|
got.post(`http://hassio/snapshots/${id}/remove`, option)
|
||||||
@ -114,48 +117,45 @@ function dellSnap(id) {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
reject();
|
reject();
|
||||||
});
|
});
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
reject();
|
reject();
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSnap(id) {
|
function checkSnap(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let token = process.env.HASSIO_TOKEN;
|
let token = process.env.HASSIO_TOKEN;
|
||||||
let option = {
|
let option = {
|
||||||
headers: { 'X-HASSIO-KEY': token },
|
headers: { "X-HASSIO-KEY": token },
|
||||||
responseType: 'json'
|
responseType: "json",
|
||||||
};
|
};
|
||||||
|
|
||||||
got(`http://hassio/snapshots/${id}/info`, option)
|
got(`http://hassio/snapshots/${id}/info`, option)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
logger.debug(`Snapshot size: ${result.body.data.size}`)
|
logger.debug(`Snapshot size: ${result.body.data.size}`);
|
||||||
resolve();
|
resolve();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
reject();
|
reject();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function createNewBackup(name) {
|
function createNewBackup(name) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
status.status = "creating";
|
status.status = "creating";
|
||||||
status.progress = -1;
|
status.progress = -1;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.info("Creating new snapshot...")
|
logger.info("Creating new snapshot...");
|
||||||
let token = process.env.HASSIO_TOKEN;
|
let token = process.env.HASSIO_TOKEN;
|
||||||
let option = {
|
let option = {
|
||||||
headers: { 'X-HASSIO-KEY': token },
|
headers: { "X-HASSIO-KEY": token },
|
||||||
responseType: 'json',
|
responseType: "json",
|
||||||
timeout: create_snap_timeout,
|
timeout: create_snap_timeout,
|
||||||
json: { name: name }
|
json: { name: name },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
got.post(`http://hassio/snapshots/new/full`, option)
|
got.post(`http://hassio/snapshots/new/full`, option)
|
||||||
@ -171,75 +171,71 @@ function createNewBackup(name) {
|
|||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject(status.message);
|
reject(status.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function clean() {
|
function clean() {
|
||||||
let limit = settingsTools.getSettings().auto_clean_local_keep;
|
let limit = settingsTools.getSettings().auto_clean_local_keep;
|
||||||
if (limit == null)
|
if (limit == null) limit = 5;
|
||||||
limit = 5;
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getSnapshots().then(async (snaps) => {
|
getSnapshots()
|
||||||
|
.then(async (snaps) => {
|
||||||
if (snaps.length < limit) {
|
if (snaps.length < limit) {
|
||||||
resolve();
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
snaps.sort((a, b) => {
|
snaps.sort((a, b) => {
|
||||||
if (moment(a.date).isBefore(moment(b.date)))
|
if (moment(a.date).isBefore(moment(b.date))) return 1;
|
||||||
return 1;
|
else return -1;
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
});
|
});
|
||||||
let toDel = snaps.slice(limit);
|
let toDel = snaps.slice(limit);
|
||||||
for (let i in toDel) {
|
for (let i in toDel) {
|
||||||
await dellSnap(toDel[i].slug)
|
await dellSnap(toDel[i].slug);
|
||||||
}
|
}
|
||||||
logger.info('Local clean done.')
|
logger.info("Local clean done.");
|
||||||
resolve();
|
resolve();
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
reject();
|
reject();
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function uploadSnapshot(path) {
|
function uploadSnapshot(path) {
|
||||||
return new Promise( (resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
status.status = "upload-b";
|
status.status = "upload-b";
|
||||||
status.progress = 0;
|
status.progress = 0;
|
||||||
status.message = null;
|
status.message = null;
|
||||||
status.error_code = null;
|
status.error_code = null;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.info('Uploading backup...');
|
logger.info("Uploading backup...");
|
||||||
let stream = fs.createReadStream(path);
|
let stream = fs.createReadStream(path);
|
||||||
let token = process.env.HASSIO_TOKEN;
|
let token = process.env.HASSIO_TOKEN;
|
||||||
|
|
||||||
let form = new FormData();
|
let form = new FormData();
|
||||||
form.append('file', stream)
|
form.append("file", stream);
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
body: form,
|
body: form,
|
||||||
username: this.username,
|
username: this.username,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
headers: { 'X-HASSIO-KEY': token },
|
headers: { "X-HASSIO-KEY": token },
|
||||||
}
|
};
|
||||||
|
|
||||||
got.stream.post(`http://hassio/snapshots/new/upload`, options).on('uploadProgress', e => {
|
got.stream
|
||||||
|
.post(`http://hassio/snapshots/new/upload`, options)
|
||||||
|
.on("uploadProgress", (e) => {
|
||||||
let percent = e.percent;
|
let percent = e.percent;
|
||||||
if (status.progress != percent) {
|
if (status.progress != percent) {
|
||||||
status.progress = percent;
|
status.progress = percent;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
}
|
}
|
||||||
if (percent >= 1) {
|
if (percent >= 1) {
|
||||||
logger.info('Upload done...');
|
logger.info("Upload done...");
|
||||||
}
|
}
|
||||||
}).on('response', res => {
|
})
|
||||||
|
.on("response", (res) => {
|
||||||
if (res.statusCode != 200) {
|
if (res.statusCode != 200) {
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 4;
|
status.error_code = 4;
|
||||||
@ -258,8 +254,8 @@ function uploadSnapshot(path) {
|
|||||||
fs.unlinkSync(path);
|
fs.unlinkSync(path);
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
}).on('error', err => {
|
})
|
||||||
|
.on("error", (err) => {
|
||||||
fs.unlinkSync(path);
|
fs.unlinkSync(path);
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 4;
|
status.error_code = 4;
|
||||||
@ -268,12 +264,9 @@ function uploadSnapshot(path) {
|
|||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject(status.message);
|
reject(status.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exports.getSnapshots = getSnapshots;
|
exports.getSnapshots = getSnapshots;
|
||||||
exports.downloadSnapshot = downloadSnapshot;
|
exports.downloadSnapshot = downloadSnapshot;
|
||||||
exports.createNewBackup = createNewBackup;
|
exports.createNewBackup = createNewBackup;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
let default_root = "/Hassio Backup/";
|
||||||
let default_root = '/Hassio Backup/';
|
|
||||||
exports.default_root = default_root;
|
exports.default_root = default_root;
|
||||||
exports.manual = 'Manual/';
|
exports.manual = "Manual/";
|
||||||
exports.auto = 'Auto/';
|
exports.auto = "Auto/";
|
||||||
|
@ -1,26 +1,19 @@
|
|||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
|
|
||||||
const settingsPath = "/data/backup_conf.json";
|
const settingsPath = "/data/backup_conf.json";
|
||||||
|
|
||||||
|
function getSettings() {
|
||||||
function getSettings(){
|
|
||||||
|
|
||||||
if (!fs.existsSync(settingsPath)) {
|
if (!fs.existsSync(settingsPath)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
let rawSettings = fs.readFileSync(settingsPath);
|
let rawSettings = fs.readFileSync(settingsPath);
|
||||||
return JSON.parse(rawSettings);
|
return JSON.parse(rawSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSettings(settings) {
|
||||||
function setSettings(settings){
|
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
fs.writeFileSync(settingsPath, JSON.stringify(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
exports.getSettings = getSettings;
|
exports.getSettings = getSettings;
|
||||||
exports.setSettings = setSettings;
|
exports.setSettings = setSettings;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,31 +1,27 @@
|
|||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
|
|
||||||
const statusPath = '/data/status.json';
|
const statusPath = "/data/status.json";
|
||||||
|
|
||||||
let baseStatus = {
|
let baseStatus = {
|
||||||
status: "idle",
|
status: "idle",
|
||||||
last_backup: null,
|
last_backup: null,
|
||||||
next_backup: null
|
next_backup: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if (!fs.existsSync(statusPath)) {
|
if (!fs.existsSync(statusPath)) {
|
||||||
fs.writeFileSync(statusPath, JSON.stringify(baseStatus));
|
fs.writeFileSync(statusPath, JSON.stringify(baseStatus));
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
let content = getStatus();
|
let content = getStatus();
|
||||||
if(content.status !== "idle"){
|
if (content.status !== "idle") {
|
||||||
content.status = "idle";
|
content.status = "idle";
|
||||||
content.message = null;
|
content.message = null;
|
||||||
setStatus(content)
|
setStatus(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStatus() {
|
||||||
function getStatus(){
|
|
||||||
if (!fs.existsSync(statusPath)) {
|
if (!fs.existsSync(statusPath)) {
|
||||||
fs.writeFileSync(statusPath, JSON.stringify(baseStatus));
|
fs.writeFileSync(statusPath, JSON.stringify(baseStatus));
|
||||||
}
|
}
|
||||||
@ -34,12 +30,10 @@ function getStatus(){
|
|||||||
return JSON.parse(content);
|
return JSON.parse(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStatus(state){
|
function setStatus(state) {
|
||||||
fs.writeFileSync(statusPath, JSON.stringify(state));
|
fs.writeFileSync(statusPath, JSON.stringify(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exports.init = init;
|
exports.init = init;
|
||||||
exports.getStatus = getStatus;
|
exports.getStatus = getStatus;
|
||||||
exports.setStatus = setStatus;
|
exports.setStatus = setStatus;
|
@ -1,23 +1,21 @@
|
|||||||
|
|
||||||
// Found on Stackoverflow, perfect code :D https://stackoverflow.com/a/14919494/8654475
|
// Found on Stackoverflow, perfect code :D https://stackoverflow.com/a/14919494/8654475
|
||||||
function humanFileSize(bytes, si=false, dp=1) {
|
function humanFileSize(bytes, si = false, dp = 1) {
|
||||||
const thresh = si ? 1000 : 1024;
|
const thresh = si ? 1000 : 1024;
|
||||||
|
|
||||||
if (Math.abs(bytes) < thresh) {
|
if (Math.abs(bytes) < thresh) {
|
||||||
return bytes + ' B';
|
return bytes + " B";
|
||||||
}
|
}
|
||||||
|
|
||||||
const units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
const units = si ? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] : ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
|
||||||
let u = -1;
|
let u = -1;
|
||||||
const r = 10**dp;
|
const r = 10 ** dp;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bytes /= thresh;
|
bytes /= thresh;
|
||||||
++u;
|
++u;
|
||||||
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
|
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
|
||||||
|
|
||||||
|
return bytes.toFixed(dp) + " " + units[u];
|
||||||
return bytes.toFixed(dp) + ' ' + units[u];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.humanFileSize = humanFileSize
|
exports.humanFileSize = humanFileSize;
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
const { createClient } = require("webdav");
|
const { createClient } = require("webdav");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const moment = require('moment');
|
const moment = require("moment");
|
||||||
const https = require('https')
|
const https = require("https");
|
||||||
|
|
||||||
const statusTools = require('./status');
|
const statusTools = require("./status");
|
||||||
const endpoint = "/remote.php/webdav";
|
const endpoint = "/remote.php/webdav";
|
||||||
const configPath = "/data/webdav_conf.json";
|
const configPath = "/data/webdav_conf.json";
|
||||||
const path = require('path');
|
const path = require("path");
|
||||||
const settingsTools = require('./settingsTools');
|
const settingsTools = require("./settingsTools");
|
||||||
const pathTools = require('./pathTools');
|
const pathTools = require("./pathTools");
|
||||||
const hassioApiTools = require('./hassioApiTools');
|
const hassioApiTools = require("./hassioApiTools");
|
||||||
const logger = require('../config/winston');
|
const logger = require("../config/winston");
|
||||||
|
|
||||||
const got = require ('got');
|
const got = require("got");
|
||||||
const stream = require('stream');
|
const stream = require("stream");
|
||||||
const {promisify} = require('util');
|
const { promisify } = require("util");
|
||||||
const pipeline = promisify(stream.pipeline);
|
const pipeline = promisify(stream.pipeline);
|
||||||
|
|
||||||
class WebdavTools {
|
class WebdavTools {
|
||||||
@ -32,11 +32,13 @@ class WebdavTools {
|
|||||||
this.baseUrl = (ssl === "true" ? "https" : "http") + "://" + host + endpoint;
|
this.baseUrl = (ssl === "true" ? "https" : "http") + "://" + host + endpoint;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
let agent_option = ssl === "true" ? { rejectUnauthorized: accept_selfsigned_cert === "false" } : {}
|
let agent_option = ssl === "true" ? { rejectUnauthorized: accept_selfsigned_cert === "false" } : {};
|
||||||
try {
|
try {
|
||||||
this.client = createClient(this.baseUrl, { username: username, password: password, httpsAgent: new https.Agent(agent_option) }) ;
|
this.client = createClient(this.baseUrl, { username: username, password: password, httpsAgent: new https.Agent(agent_option) });
|
||||||
|
|
||||||
this.client.getDirectoryContents("/").then(() => {
|
this.client
|
||||||
|
.getDirectoryContents("/")
|
||||||
|
.then(() => {
|
||||||
if (status.error_code == 3) {
|
if (status.error_code == 3) {
|
||||||
status.status = "idle";
|
status.status = "idle";
|
||||||
status.message = null;
|
status.message = null;
|
||||||
@ -47,11 +49,11 @@ class WebdavTools {
|
|||||||
this.initFolder().then(() => {
|
this.initFolder().then(() => {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
})
|
||||||
}).catch((error) => {
|
.catch((error) => {
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 3;
|
status.error_code = 3;
|
||||||
status.message = "Can't connect to Nextcloud (" + error + ") !"
|
status.message = "Can't connect to Nextcloud (" + error + ") !";
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
this.client = null;
|
this.client = null;
|
||||||
logger.error("Can't connect to Nextcloud (" + error + ") !");
|
logger.error("Can't connect to Nextcloud (" + error + ") !");
|
||||||
@ -60,46 +62,51 @@ class WebdavTools {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 3;
|
status.error_code = 3;
|
||||||
status.message = "Can't connect to Nextcloud (" + err + ") !"
|
status.message = "Can't connect to Nextcloud (" + err + ") !";
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
this.client = null;
|
this.client = null;
|
||||||
logger.error("Can't connect to Nextcloud (" + err + ") !");
|
logger.error("Can't connect to Nextcloud (" + err + ") !");
|
||||||
reject("Can't connect to Nextcloud (" + err + ") !");
|
reject("Can't connect to Nextcloud (" + err + ") !");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async __createRoot(){
|
async __createRoot() {
|
||||||
let root_splited = this.getConf().back_dir.split('/').splice(1)
|
let root_splited = this.getConf().back_dir.split("/").splice(1);
|
||||||
let path = '/'
|
let path = "/";
|
||||||
for(let elem of root_splited){
|
for (let elem of root_splited) {
|
||||||
if(elem != ''){
|
if (elem != "") {
|
||||||
path = path + elem + '/'
|
path = path + elem + "/";
|
||||||
try {
|
try {
|
||||||
await this.client.createDirectory(path)
|
await this.client.createDirectory(path);
|
||||||
logger.debug(`Path ${path} created.`)
|
logger.debug(`Path ${path} created.`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if(error.response.status == 405)
|
if (error.response.status == 405) logger.debug(`Path ${path} already exist.`);
|
||||||
logger.debug(`Path ${path} already exist.`)
|
else logger.error(error);
|
||||||
else
|
|
||||||
logger.error(error)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initFolder() {
|
initFolder() {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.__createRoot().catch((err) => { logger.error(err)}).then(() => {
|
this.__createRoot()
|
||||||
this.client.createDirectory(this.getConf().back_dir + pathTools.auto).catch(() => { }).then(() => {
|
.catch((err) => {
|
||||||
this.client.createDirectory(this.getConf().back_dir + pathTools.manual).catch(() => { }).then(() => {
|
logger.error(err);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.client
|
||||||
|
.createDirectory(this.getConf().back_dir + pathTools.auto)
|
||||||
|
.catch(() => {})
|
||||||
|
.then(() => {
|
||||||
|
this.client
|
||||||
|
.createDirectory(this.getConf().back_dir + pathTools.manual)
|
||||||
|
.catch(() => {})
|
||||||
|
.then(() => {
|
||||||
resolve();
|
resolve();
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Check if theh webdav config is valid, if yes, start init of webdav client
|
* Check if theh webdav config is valid, if yes, start init of webdav client
|
||||||
@ -117,53 +124,50 @@ class WebdavTools {
|
|||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
}
|
}
|
||||||
// Check if self_signed option exist
|
// Check if self_signed option exist
|
||||||
if( conf.self_signed == null || conf.self_signed == ''){
|
if (conf.self_signed == null || conf.self_signed == "") {
|
||||||
conf.self_signed = "false";
|
conf.self_signed = "false";
|
||||||
this.setConf(conf);
|
this.setConf(conf);
|
||||||
}
|
}
|
||||||
this.init(conf.ssl, conf.host, conf.username, conf.password, conf.self_signed).then(() => {
|
this.init(conf.ssl, conf.host, conf.username, conf.password, conf.self_signed)
|
||||||
|
.then(() => {
|
||||||
resolve();
|
resolve();
|
||||||
}).catch((err) => {
|
})
|
||||||
|
.catch((err) => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 2;
|
status.error_code = 2;
|
||||||
status.message = "Nextcloud config invalid !"
|
status.message = "Nextcloud config invalid !";
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject("Nextcloud config invalid !");
|
reject("Nextcloud config invalid !");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conf.back_dir == null || conf.back_dir == ''){
|
if (conf.back_dir == null || conf.back_dir == "") {
|
||||||
logger.info('Backup dir is null, initializing it.');
|
logger.info("Backup dir is null, initializing it.");
|
||||||
conf.back_dir = pathTools.default_root;
|
conf.back_dir = pathTools.default_root;
|
||||||
this.setConf(conf);
|
this.setConf(conf);
|
||||||
}
|
} else {
|
||||||
else{
|
if (!conf.back_dir.startsWith("/")) {
|
||||||
if(!conf.back_dir.startsWith('/')){
|
logger.warn("Backup dir not starting with '/', fixing this...");
|
||||||
logger.warn('Backup dir not starting with \'/\', fixing this...');
|
conf.back_dir = `/${conf.back_dir}`;
|
||||||
conf.back_dir=`/${conf.back_dir}`;
|
|
||||||
this.setConf(conf);
|
this.setConf(conf);
|
||||||
}
|
}
|
||||||
if(!conf.back_dir.endsWith('/')){
|
if (!conf.back_dir.endsWith("/")) {
|
||||||
logger.warn('Backup dir not ending with \'/\', fixing this...');
|
logger.warn("Backup dir not ending with '/', fixing this...");
|
||||||
conf.back_dir=`${conf.back_dir}/`;
|
conf.back_dir = `${conf.back_dir}/`;
|
||||||
this.setConf(conf);
|
this.setConf(conf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 2;
|
status.error_code = 2;
|
||||||
status.message = "Nextcloud config not found !"
|
status.message = "Nextcloud config not found !";
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject("Nextcloud config not found !");
|
reject("Nextcloud config not found !");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,62 +175,61 @@ class WebdavTools {
|
|||||||
if (fs.existsSync(configPath)) {
|
if (fs.existsSync(configPath)) {
|
||||||
let content = JSON.parse(fs.readFileSync(configPath));
|
let content = JSON.parse(fs.readFileSync(configPath));
|
||||||
return content;
|
return content;
|
||||||
}
|
} else return null;
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setConf(conf) {
|
setConf(conf) {
|
||||||
fs.writeFileSync(configPath, JSON.stringify(conf));
|
fs.writeFileSync(configPath, JSON.stringify(conf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uploadFile(id, path) {
|
uploadFile(id, path) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.client == null) {
|
if (this.client == null) {
|
||||||
this.confIsValid().then(() => {
|
this.confIsValid()
|
||||||
|
.then(() => {
|
||||||
this._startUpload(id, path);
|
this._startUpload(id, path);
|
||||||
}).catch((err) => {
|
|
||||||
reject(err);
|
|
||||||
})
|
})
|
||||||
}
|
.catch((err) => {
|
||||||
else
|
reject(err);
|
||||||
this._startUpload(id, path);
|
});
|
||||||
|
} else this._startUpload(id, path);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_startUpload(id, path) {
|
_startUpload(id, path) {
|
||||||
return new Promise( (resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
status.status = "upload";
|
status.status = "upload";
|
||||||
status.progress = 0;
|
status.progress = 0;
|
||||||
status.message = null;
|
status.message = null;
|
||||||
status.error_code = null;
|
status.error_code = null;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.info('Uploading snap...');
|
logger.info("Uploading snap...");
|
||||||
let tmpFile = `./temp/${id}.tar`
|
let tmpFile = `./temp/${id}.tar`;
|
||||||
let stream = fs.createReadStream(tmpFile);
|
let stream = fs.createReadStream(tmpFile);
|
||||||
let conf = this.getConf()
|
let conf = this.getConf();
|
||||||
let options = {
|
let options = {
|
||||||
body: stream,
|
body: stream,
|
||||||
username: this.username,
|
username: this.username,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
}
|
};
|
||||||
if(conf.ssl === 'true'){
|
if (conf.ssl === "true") {
|
||||||
options["https"] = { rejectUnauthorized: conf.self_signed === "false" }
|
options["https"] = { rejectUnauthorized: conf.self_signed === "false" };
|
||||||
}
|
}
|
||||||
|
|
||||||
got.stream.put(this.baseUrl + encodeURI(path), options).on('uploadProgress', e => {
|
got.stream
|
||||||
|
.put(this.baseUrl + encodeURI(path), options)
|
||||||
|
.on("uploadProgress", (e) => {
|
||||||
let percent = e.percent;
|
let percent = e.percent;
|
||||||
if (status.progress != percent) {
|
if (status.progress != percent) {
|
||||||
status.progress = percent;
|
status.progress = percent;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
}
|
}
|
||||||
if (percent >= 1) {
|
if (percent >= 1) {
|
||||||
logger.info('Upload done...');
|
logger.info("Upload done...");
|
||||||
}
|
}
|
||||||
}).on('response', res => {
|
})
|
||||||
|
.on("response", (res) => {
|
||||||
if (res.statusCode != 201 && res.statusCode != 204) {
|
if (res.statusCode != 201 && res.statusCode != 204) {
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 4;
|
status.error_code = 4;
|
||||||
@ -241,7 +244,7 @@ class WebdavTools {
|
|||||||
status.progress = -1;
|
status.progress = -1;
|
||||||
status.message = null;
|
status.message = null;
|
||||||
status.error_code = null;
|
status.error_code = null;
|
||||||
status.last_backup = moment().format('MMM D, YYYY HH:mm');
|
status.last_backup = moment().format("MMM D, YYYY HH:mm");
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
cleanTempFolder();
|
cleanTempFolder();
|
||||||
let autoCleanCloud = settingsTools.getSettings().auto_clean_backup;
|
let autoCleanCloud = settingsTools.getSettings().auto_clean_backup;
|
||||||
@ -254,8 +257,8 @@ class WebdavTools {
|
|||||||
}
|
}
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
}).on('error', err => {
|
})
|
||||||
|
.on("error", (err) => {
|
||||||
fs.unlinkSync(tmpFile);
|
fs.unlinkSync(tmpFile);
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 4;
|
status.error_code = 4;
|
||||||
@ -264,29 +267,29 @@ class WebdavTools {
|
|||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject(status.message);
|
reject(status.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadFile(path) {
|
downloadFile(path) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.client == null) {
|
if (this.client == null) {
|
||||||
this.confIsValid().then(() => {
|
this.confIsValid()
|
||||||
|
.then(() => {
|
||||||
this._startDownload(path)
|
this._startDownload(path)
|
||||||
.then((path)=> resolve(path))
|
.then((path) => resolve(path))
|
||||||
.catch(()=> reject());
|
.catch(() => reject());
|
||||||
}).catch((err) => {
|
|
||||||
reject(err);
|
|
||||||
})
|
})
|
||||||
}
|
.catch((err) => {
|
||||||
else
|
reject(err);
|
||||||
|
});
|
||||||
|
} else
|
||||||
this._startDownload(path)
|
this._startDownload(path)
|
||||||
.then((path)=> resolve(path))
|
.then((path) => resolve(path))
|
||||||
.catch(()=> reject());
|
.catch(() => reject());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_startDownload(path) {
|
_startDownload(path) {
|
||||||
return new Promise( (resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let status = statusTools.getStatus();
|
let status = statusTools.getStatus();
|
||||||
status.status = "download-b";
|
status.status = "download-b";
|
||||||
status.progress = 0;
|
status.progress = 0;
|
||||||
@ -294,121 +297,112 @@ class WebdavTools {
|
|||||||
status.error_code = null;
|
status.error_code = null;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
|
|
||||||
logger.info('Downloading backup...');
|
logger.info("Downloading backup...");
|
||||||
|
|
||||||
let tmpFile = `./temp/restore_${moment().format('MMM-DD-YYYY_HH_mm')}.tar`
|
let tmpFile = `./temp/restore_${moment().format("MMM-DD-YYYY_HH_mm")}.tar`;
|
||||||
let stream = fs.createWriteStream(tmpFile);
|
let stream = fs.createWriteStream(tmpFile);
|
||||||
let conf = this.getConf()
|
let conf = this.getConf();
|
||||||
let options = {
|
let options = {
|
||||||
username: this.username,
|
username: this.username,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
}
|
};
|
||||||
if(conf.ssl === 'true'){
|
if (conf.ssl === "true") {
|
||||||
options["https"] = { rejectUnauthorized: conf.self_signed === "false" }
|
options["https"] = { rejectUnauthorized: conf.self_signed === "false" };
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline(
|
pipeline(
|
||||||
got.stream.get(this.baseUrl + encodeURI(path), options)
|
got.stream.get(this.baseUrl + encodeURI(path), options).on("downloadProgress", (e) => {
|
||||||
.on('downloadProgress', e => {
|
|
||||||
let percent = Math.round(e.percent * 100) / 100;
|
let percent = Math.round(e.percent * 100) / 100;
|
||||||
if (status.progress != percent) {
|
if (status.progress != percent) {
|
||||||
status.progress = percent;
|
status.progress = percent;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
,
|
|
||||||
stream
|
stream
|
||||||
)
|
)
|
||||||
.then((res)=>{
|
.then((res) => {
|
||||||
logger.info('Download success !')
|
logger.info("Download success !");
|
||||||
status.progress = 1;
|
status.progress = 1;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.debug("Backup dl size : " + (fs.statSync(tmpFile).size / 1024 / 1024));
|
logger.debug("Backup dl size : " + fs.statSync(tmpFile).size / 1024 / 1024);
|
||||||
resolve(tmpFile);
|
resolve(tmpFile);
|
||||||
}).catch((err)=>{
|
})
|
||||||
if(fs.existsSync(tmpFile))
|
.catch((err) => {
|
||||||
fs.unlinkSync(tmpFile);
|
if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.message = "Fail to download Hassio snapshot (" + err.message + ")";
|
status.message = "Fail to download Hassio snapshot (" + err.message + ")";
|
||||||
status.error_code = 7;
|
status.error_code = 7;
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject(err.message);
|
reject(err.message);
|
||||||
})
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getFolderContent(path) {
|
getFolderContent(path) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if(this.client == null){
|
if (this.client == null) {
|
||||||
reject();
|
reject();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.client.getDirectoryContents(path)
|
this.client
|
||||||
|
.getDirectoryContents(path)
|
||||||
.then((contents) => {
|
.then((contents) => {
|
||||||
resolve(contents);
|
resolve(contents);
|
||||||
}).catch((error) => {
|
|
||||||
reject(error);
|
|
||||||
})
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
clean() {
|
clean() {
|
||||||
let limit = settingsTools.getSettings().auto_clean_backup_keep;
|
let limit = settingsTools.getSettings().auto_clean_backup_keep;
|
||||||
if (limit == null)
|
if (limit == null) limit = 5;
|
||||||
limit = 5;
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.getFolderContent(this.getConf().back_dir + pathTools.auto).then(async (contents) => {
|
this.getFolderContent(this.getConf().back_dir + pathTools.auto)
|
||||||
|
.then(async (contents) => {
|
||||||
if (contents.length < limit) {
|
if (contents.length < limit) {
|
||||||
resolve();
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
contents.sort((a, b) => {
|
contents.sort((a, b) => {
|
||||||
if (moment(a.lastmod).isBefore(moment(b.lastmod)))
|
if (moment(a.lastmod).isBefore(moment(b.lastmod))) return 1;
|
||||||
return 1;
|
else return -1;
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let toDel = contents.slice(limit);
|
let toDel = contents.slice(limit);
|
||||||
for (let i in toDel) {
|
for (let i in toDel) {
|
||||||
await this.client.deleteFile(toDel[i].filename);
|
await this.client.deleteFile(toDel[i].filename);
|
||||||
}
|
}
|
||||||
logger.info('Cloud clean done.')
|
logger.info("Cloud clean done.");
|
||||||
resolve();
|
resolve();
|
||||||
|
})
|
||||||
}).catch((error) => {
|
.catch((error) => {
|
||||||
status.status = "error";
|
status.status = "error";
|
||||||
status.error_code = 6;
|
status.error_code = 6;
|
||||||
status.message = "Fail to clean Nexcloud (" + error + ") !"
|
status.message = "Fail to clean Nexcloud (" + error + ") !";
|
||||||
statusTools.setStatus(status);
|
statusTools.setStatus(status);
|
||||||
logger.error(status.message);
|
logger.error(status.message);
|
||||||
reject(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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Singleton {
|
||||||
class Singleton {
|
|
||||||
constructor() {
|
constructor() {
|
||||||
if (!Singleton.instance) {
|
if (!Singleton.instance) {
|
||||||
Singleton.instance = new WebdavTools();
|
Singleton.instance = new WebdavTools();
|
||||||
@ -418,8 +412,6 @@ class WebdavTools {
|
|||||||
getInstance() {
|
getInstance() {
|
||||||
return Singleton.instance;
|
return Singleton.instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Singleton;
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = Singleton;
|
||||||
|
Loading…
Reference in New Issue
Block a user