mirror of
https://github.com/Sebclem/hassio-nextcloud-backup.git
synced 2024-11-22 09:12:58 +01:00
🔨 Add file upload for webdav
This commit is contained in:
parent
b1f4d45eb5
commit
c6ff7f819c
@ -1,15 +1,17 @@
|
|||||||
|
import { XMLParser } from "fast-xml-parser";
|
||||||
|
import { createReadStream, statSync, unlinkSync } from "fs";
|
||||||
import got, { HTTPError, Method } from "got";
|
import got, { HTTPError, Method } from "got";
|
||||||
|
import { DateTime } from "luxon";
|
||||||
import logger from "../config/winston.js";
|
import logger from "../config/winston.js";
|
||||||
import messageManager from "../tools/messageManager.js";
|
import messageManager from "../tools/messageManager.js";
|
||||||
|
import * as pathTools from "../tools/pathTools.js";
|
||||||
|
import * as statusTools from "../tools/status.js";
|
||||||
|
import { WebdavBackup } from "../types/services/webdav.js";
|
||||||
import { WebdavConfig } from "../types/services/webdavConfig.js";
|
import { WebdavConfig } from "../types/services/webdavConfig.js";
|
||||||
import { getEndpoint } from "./webdavConfigService.js";
|
import { getEndpoint } from "./webdavConfigService.js";
|
||||||
import * as pathTools from "../tools/pathTools.js";
|
|
||||||
import { XMLParser } from "fast-xml-parser";
|
|
||||||
import { WebdavBackup } from "../types/services/webdav.js";
|
|
||||||
import { DateTime } from "luxon";
|
|
||||||
|
|
||||||
const PROPFIND_BODY =
|
const PROPFIND_BODY =
|
||||||
'<?xml version="1.0" encoding="utf-8" ?>\
|
'<?xml version="1.0" encoding="utf-8" ?>\
|
||||||
<d:propfind xmlns:d="DAV:">\
|
<d:propfind xmlns:d="DAV:">\
|
||||||
<d:prop>\
|
<d:prop>\
|
||||||
<d:getlastmodified />\
|
<d:getlastmodified />\
|
||||||
@ -118,33 +120,99 @@ export function getBackups(folder: string, config: WebdavConfig) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseXmlBackupData(body: string) {
|
||||||
function parseXmlBackupData(body: string){
|
|
||||||
const parser = new XMLParser();
|
const parser = new XMLParser();
|
||||||
const data = parser.parse(body);
|
const data = parser.parse(body);
|
||||||
const multistatus = data["d:multistatus"];
|
const multistatus = data["d:multistatus"];
|
||||||
const backups: WebdavBackup[] = [];
|
const backups: WebdavBackup[] = [];
|
||||||
if(Array.isArray(multistatus["d:response"])){
|
if (Array.isArray(multistatus["d:response"])) {
|
||||||
for(const elem of multistatus["d:response"]){
|
for (const elem of multistatus["d:response"]) {
|
||||||
// If array -> base folder, ignoring it
|
// If array -> base folder, ignoring it
|
||||||
if(!Array.isArray(elem["d:propstat"])){
|
if (!Array.isArray(elem["d:propstat"])) {
|
||||||
const propstat = elem["d:propstat"];
|
const propstat = elem["d:propstat"];
|
||||||
const id = propstat["d:prop"]["d:getetag"].replaceAll("\"", "");
|
const id = propstat["d:prop"]["d:getetag"].replaceAll('"', "");
|
||||||
const href = decodeURI(elem["d:href"]);
|
const href = decodeURI(elem["d:href"]);
|
||||||
const name = href.split("/").slice(-1)[0];
|
const name = href.split("/").slice(-1)[0];
|
||||||
const lastEdit = DateTime.fromHTTP(propstat["d:prop"]["d:getlastmodified"]);
|
const lastEdit = DateTime.fromHTTP(
|
||||||
|
propstat["d:prop"]["d:getlastmodified"]
|
||||||
|
);
|
||||||
backups.push({
|
backups.push({
|
||||||
id: id,
|
id: id,
|
||||||
lastEdit: lastEdit,
|
lastEdit: lastEdit,
|
||||||
size: propstat["d:prop"]["d:getcontentlenght"],
|
size: propstat["d:prop"]["d:getcontentlenght"],
|
||||||
name: name
|
name: name,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return backups;
|
return backups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function webdabUploadFile(
|
||||||
|
localPath: string,
|
||||||
|
webdavPath: string,
|
||||||
|
config: WebdavConfig
|
||||||
|
) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
logger.info(`Uploading ${localPath} to webdav...`);
|
||||||
|
const stats = statSync(localPath);
|
||||||
|
const stream = createReadStream(localPath);
|
||||||
|
const options = {
|
||||||
|
body: stream,
|
||||||
|
headers: {
|
||||||
|
authorization:
|
||||||
|
"Basic " +
|
||||||
|
Buffer.from(config.username + ":" + config.password).toString(
|
||||||
|
"base64"
|
||||||
|
),
|
||||||
|
"content-length": String(stats.size),
|
||||||
|
},
|
||||||
|
https: { rejectUnauthorized: !config.allowSelfSignedCerts },
|
||||||
|
};
|
||||||
|
const url =
|
||||||
|
config.url + getEndpoint(config) + config.backupDir + webdavPath;
|
||||||
|
|
||||||
|
logger.debug(`...URI: ${encodeURI(url)}`);
|
||||||
|
logger.debug(`...rejectUnauthorized: ${options.https?.rejectUnauthorized}`);
|
||||||
|
const status = statusTools.getStatus();
|
||||||
|
got.stream
|
||||||
|
.put(encodeURI(url), options)
|
||||||
|
.on("uploadProgress", (e) => {
|
||||||
|
const percent = e.percent;
|
||||||
|
if (status.progress !== percent) {
|
||||||
|
status.progress = percent;
|
||||||
|
statusTools.setStatus(status);
|
||||||
|
}
|
||||||
|
if (percent >= 1) {
|
||||||
|
logger.info("Upload done...");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("response", (res) => {
|
||||||
|
if (res.statusCode != 201 && res.statusCode != 204) {
|
||||||
|
messageManager.error(
|
||||||
|
"Fail to upload file to webdav.",
|
||||||
|
`Status code: ${res.statusCode}`
|
||||||
|
);
|
||||||
|
logger.error(
|
||||||
|
`Fail to upload file to webdav, Status code: ${res.statusCode}`
|
||||||
|
);
|
||||||
|
logger.error(status.message);
|
||||||
|
unlinkSync(localPath);
|
||||||
|
reject(res);
|
||||||
|
} else {
|
||||||
|
logger.info(`...Upload finish ! (status: ${res.statusCode})`);
|
||||||
|
unlinkSync(localPath);
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("error", (err) => {
|
||||||
|
logger.error(status.message);
|
||||||
|
logger.error(err.stack);
|
||||||
|
reject(status.message);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// import fs from "fs";
|
// import fs from "fs";
|
||||||
// import got from "got";
|
// import got from "got";
|
||||||
// import https from "https";
|
// import https from "https";
|
||||||
@ -610,17 +678,5 @@ function parseXmlBackupData(body: string){
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// 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;
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const INSTANCE = new WebdavTools();
|
// const INSTANCE = new WebdavTools();
|
||||||
// export default INSTANCE;
|
// export default INSTANCE;
|
||||||
|
Loading…
Reference in New Issue
Block a user