You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-29 22:48:10 +02:00
All: Handle case where file is left half-uploaded on Nextcloud instance (possibly an ocloud.de issue only)
This commit is contained in:
@@ -4,6 +4,8 @@ const { basicDelta } = require('lib/file-api');
|
||||
const { rtrimSlashes, ltrimSlashes } = require('lib/path-utils.js');
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const html_entity_decode = (new Entities()).decode;
|
||||
const { shim } = require('lib/shim');
|
||||
const { basename } = require('lib/path-utils');
|
||||
|
||||
class FileApiDriverWebDav {
|
||||
|
||||
@@ -20,6 +22,7 @@ class FileApiDriverWebDav {
|
||||
const result = await this.api().execPropFind(path, 0, [
|
||||
'd:getlastmodified',
|
||||
'd:resourcetype',
|
||||
'd:getcontentlength', // Remove this once PUT call issue is sorted out
|
||||
]);
|
||||
|
||||
const resource = this.api().objectFromJson(result, ['d:multistatus', 'd:response', 0]);
|
||||
@@ -34,6 +37,9 @@ class FileApiDriverWebDav {
|
||||
const isCollection = this.api().stringFromJson(resource, ['d:propstat', 0, 'd:prop', 0, 'd:resourcetype', 0, 'd:collection', 0]);
|
||||
const lastModifiedString = this.api().stringFromJson(resource, ['d:propstat', 0, 'd:prop', 0, 'd:getlastmodified', 0]);
|
||||
|
||||
const sizeDONOTUSE = Number(this.api().stringFromJson(resource, ['d:propstat', 0, 'd:prop', 0, 'd:getcontentlength', 0]));
|
||||
if (isNaN(sizeDONOTUSE)) throw new Error('Cannot get content size: ' + JSON.stringify(resource));
|
||||
|
||||
if (!lastModifiedString) throw new Error('Could not get lastModified date: ' + JSON.stringify(resource));
|
||||
|
||||
const lastModifiedDate = new Date(lastModifiedString);
|
||||
@@ -44,6 +50,7 @@ class FileApiDriverWebDav {
|
||||
created_time: lastModifiedDate.getTime(),
|
||||
updated_time: lastModifiedDate.getTime(),
|
||||
isDir: isCollection === '',
|
||||
sizeDONOTUSE: sizeDONOTUSE, // This property is used only for the WebDAV PUT hack (see below) so mark it as such so that it can be removed with the hack later on.
|
||||
};
|
||||
}
|
||||
|
||||
@@ -229,7 +236,32 @@ class FileApiDriverWebDav {
|
||||
}
|
||||
|
||||
async put(path, content, options = null) {
|
||||
await this.api().exec('PUT', path, content, null, options);
|
||||
// In theory, if a client doesn't complete an upload, the file will not appear in the Nextcloud app. Likewise if
|
||||
// the server interrupts the upload midway, the client should receive some kind of error and try uploading the
|
||||
// file again next time. At the very least the file should not appear half-uploaded on the server. In practice
|
||||
// however it seems some files might end up half uploaded on the server (at least on ocloud.de) so, for now,
|
||||
// instead of doing a simple PUT, we do it to a temp file on Nextcloud, then check the file size and, if it
|
||||
// matches, move it its actual place (hoping the server won't mess up and only copy half of the file).
|
||||
// This is innefficient so once the bug is better understood it should hopefully be possible to go back to
|
||||
// using a single PUT call.
|
||||
|
||||
let contentSize = 0;
|
||||
if (content) contentSize = content.length;
|
||||
if (options && options.path) {
|
||||
const stat = await shim.fsDriver().stat(options.path);
|
||||
contentSize = stat.size;
|
||||
}
|
||||
|
||||
const tempPath = this.fileApi_.tempDirName() + '/' + basename(path) + '_' + Date.now();
|
||||
await this.api().exec('PUT', tempPath, content, null, options);
|
||||
|
||||
const stat = await this.stat(tempPath);
|
||||
if (stat.sizeDONOTUSE != contentSize) {
|
||||
// await this.delete(tempPath);
|
||||
throw new Error('WebDAV PUT - Size check failed for ' + tempPath + ' Expected: ' + contentSize + '. Found: ' + stat.sizeDONOTUSE);
|
||||
}
|
||||
|
||||
await this.move(tempPath, path);
|
||||
}
|
||||
|
||||
async delete(path) {
|
||||
@@ -241,7 +273,9 @@ class FileApiDriverWebDav {
|
||||
}
|
||||
|
||||
async move(oldPath, newPath) {
|
||||
throw new Error('Not implemented');
|
||||
await this.api().exec('MOVE', oldPath, null, {
|
||||
'Destination': this.api().baseUrl() + '/' + newPath,
|
||||
});
|
||||
}
|
||||
|
||||
format() {
|
||||
|
||||
Reference in New Issue
Block a user