mirror of
https://github.com/abraunegg/onedrive
synced 2024-05-10 17:56:44 +02:00
* Resolve multiple versions of file shown on website after single upload - however Issue #23 & OneDrive API bug (https://github.com/OneDrive/onedrive-api-docs/issues/877) will still create 2 file versions on OneDrive Business. The work around is to disable file versions until #877 is resolved.
This commit is contained in:
parent
5e48ba96ac
commit
83c28ba3b6
|
@ -212,12 +212,13 @@ final class OneDriveApi
|
|||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createuploadsession
|
||||
JSONValue createUploadSession(const(char)[] parentDriveId, const(char)[] parentId, const(char)[] filename, const(char)[] eTag = null)
|
||||
JSONValue createUploadSession(const(char)[] parentDriveId, const(char)[] parentId, const(char)[] filename, const(char)[] eTag = null, JSONValue item = null)
|
||||
{
|
||||
checkAccessTokenExpired();
|
||||
const(char)[] url = driveByIdUrl ~ parentDriveId ~ "/items/" ~ parentId ~ ":/" ~ encodeComponent(filename) ~ ":/createUploadSession";
|
||||
if (eTag) http.addRequestHeader("If-Match", eTag);
|
||||
return post(url, null);
|
||||
http.addRequestHeader("Content-Type", "application/json");
|
||||
return post(url, item.toString());
|
||||
}
|
||||
|
||||
// https://dev.onedrive.com/items/upload_large_files.htm
|
||||
|
|
154
src/sync.d
154
src/sync.d
|
@ -816,37 +816,53 @@ final class SyncEngine
|
|||
// HACK: reduce time resolution to seconds before comparing
|
||||
item.mtime.fracSecs = Duration.zero;
|
||||
localModifiedTime.fracSecs = Duration.zero;
|
||||
|
||||
if (localModifiedTime != item.mtime) {
|
||||
log.vlog("The file last modified time has changed");
|
||||
log.vlog("The file last modified time has changed");
|
||||
string eTag = item.eTag;
|
||||
if (!testFileHash(path, item)) {
|
||||
log.vlog("The file content has changed");
|
||||
write("Uploading file ", path, " ...");
|
||||
JSONValue response;
|
||||
if (getSize(path) <= thresholdFileSize) {
|
||||
try {
|
||||
response = onedrive.simpleUploadReplace(path, item.driveId, item.id, item.eTag);
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 504) {
|
||||
// HTTP request returned status code 504 (Gateway Timeout)
|
||||
// Try upload as a session
|
||||
//log.vlog("OneDrive returned a 'HTTP 504 - Gateway Timeout' - gracefully handling error");
|
||||
response = session.upload(path, item.driveId, item.parentId, baseName(path), eTag);
|
||||
|
||||
// Are we using OneDrive Personal or OneDrive Business?
|
||||
// To solve 'Multiple versions of file shown on website after single upload' (https://github.com/abraunegg/onedrive/issues/2)
|
||||
// check what 'account type' this is as this issue only affects OneDrive Business so we need some extra logic here
|
||||
if (accountType == "personal"){
|
||||
// Original file upload logic
|
||||
if (getSize(path) <= thresholdFileSize) {
|
||||
try {
|
||||
response = onedrive.simpleUploadReplace(path, item.driveId, item.id, item.eTag);
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 504) {
|
||||
// HTTP request returned status code 504 (Gateway Timeout)
|
||||
// Try upload as a session
|
||||
response = session.upload(path, item.driveId, item.parentId, baseName(path), eTag);
|
||||
}
|
||||
else throw e;
|
||||
}
|
||||
else throw e;
|
||||
}
|
||||
writeln(" done.");
|
||||
writeln(" done.");
|
||||
} else {
|
||||
writeln("");
|
||||
response = session.upload(path, item.driveId, item.parentId, baseName(path), eTag);
|
||||
writeln(" done.");
|
||||
}
|
||||
} else {
|
||||
// OneDrive Business Account - always use a session to upload
|
||||
writeln("");
|
||||
response = session.upload(path, item.driveId, item.parentId, baseName(path), eTag);
|
||||
response = session.upload(path, item.driveId, item.parentId, baseName(path));
|
||||
writeln(" done.");
|
||||
// As the session.upload includes the last modified time, save the response
|
||||
saveItem(response);
|
||||
}
|
||||
log.fileOnly("Uploading file ", path, " ... done.");
|
||||
// saveItem(response); redundant
|
||||
// use the cTag instead of the eTag because Onedrive may update the metadata of files AFTER they have been uploaded
|
||||
eTag = response["cTag"].str;
|
||||
}
|
||||
uploadLastModifiedTime(item.driveId, item.id, eTag, localModifiedTime.toUTC());
|
||||
if (accountType == "personal"){
|
||||
// If Personal, call to update the modified time as stored on OneDrive
|
||||
uploadLastModifiedTime(item.driveId, item.id, eTag, localModifiedTime.toUTC());
|
||||
}
|
||||
} else {
|
||||
log.vlog("The file has not changed");
|
||||
}
|
||||
|
@ -1055,24 +1071,46 @@ final class SyncEngine
|
|||
// The file was not found on OneDrive, need to upload it
|
||||
write("Uploading file ", path, " ...");
|
||||
JSONValue response;
|
||||
if (getSize(path) <= thresholdFileSize) {
|
||||
try {
|
||||
response = onedrive.simpleUpload(path, parent.driveId, parent.id, baseName(path));
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 504) {
|
||||
// HTTP request returned status code 504 (Gateway Timeout)
|
||||
// Try upload as a session
|
||||
//log.vlog("OneDrive returned a 'HTTP 504 - Gateway Timeout' - gracefully handling error");
|
||||
response = session.upload(path, parent.driveId, parent.id, baseName(path));
|
||||
}
|
||||
else throw e;
|
||||
}
|
||||
writeln(" done.");
|
||||
} else {
|
||||
writeln("");
|
||||
response = session.upload(path, parent.driveId, parent.id, baseName(path));
|
||||
|
||||
// Resolve https://github.com/abraunegg/onedrive/issues/37
|
||||
if (thisFileSize == 0){
|
||||
// We can only upload zero size files via simpleFileUpload regardless of account type
|
||||
// https://github.com/OneDrive/onedrive-api-docs/issues/53
|
||||
response = onedrive.simpleUpload(path, parent.driveId, parent.id, baseName(path));
|
||||
writeln(" done.");
|
||||
} else {
|
||||
// File is not a zero byte file
|
||||
// Are we using OneDrive Personal or OneDrive Business?
|
||||
// To solve 'Multiple versions of file shown on website after single upload' (https://github.com/abraunegg/onedrive/issues/2)
|
||||
// check what 'account type' this is as this issue only affects OneDrive Business so we need some extra logic here
|
||||
if (accountType == "personal"){
|
||||
// Original file upload logic
|
||||
if (getSize(path) <= thresholdFileSize) {
|
||||
try {
|
||||
response = onedrive.simpleUpload(path, parent.driveId, parent.id, baseName(path));
|
||||
} catch (OneDriveException e) {
|
||||
if (e.httpStatusCode == 504) {
|
||||
// HTTP request returned status code 504 (Gateway Timeout)
|
||||
// Try upload as a session
|
||||
response = session.upload(path, parent.driveId, parent.id, baseName(path));
|
||||
}
|
||||
else throw e;
|
||||
}
|
||||
writeln(" done.");
|
||||
} else {
|
||||
writeln("");
|
||||
response = session.upload(path, parent.driveId, parent.id, baseName(path));
|
||||
writeln(" done.");
|
||||
}
|
||||
} else {
|
||||
// OneDrive Business Account - always use a session to upload
|
||||
writeln("");
|
||||
response = session.upload(path, parent.driveId, parent.id, baseName(path));
|
||||
writeln(" done.");
|
||||
}
|
||||
}
|
||||
|
||||
// Log action to log file
|
||||
log.fileOnly("Uploading file ", path, " ... done.");
|
||||
|
||||
// The file was uploaded
|
||||
|
@ -1090,13 +1128,21 @@ final class SyncEngine
|
|||
uploadNewFile(path);
|
||||
return;
|
||||
} else {
|
||||
// Update the item's metadata on OneDrive
|
||||
string id = response["id"].str;
|
||||
string cTag = response["cTag"].str;
|
||||
SysTime mtime = timeLastModified(path).toUTC();
|
||||
// use the cTag instead of the eTag because OneDrive may update the metadata of files AFTER they have been uploaded
|
||||
uploadLastModifiedTime(parent.driveId, id, cTag, mtime);
|
||||
return;
|
||||
if ((accountType == "personal") || (thisFileSize == 0)){
|
||||
// Update the item's metadata on OneDrive
|
||||
string id = response["id"].str;
|
||||
string cTag = response["cTag"].str;
|
||||
SysTime mtime = timeLastModified(path).toUTC();
|
||||
// use the cTag instead of the eTag because OneDrive may update the metadata of files AFTER they have been uploaded
|
||||
uploadLastModifiedTime(parent.driveId, id, cTag, mtime);
|
||||
return;
|
||||
} else {
|
||||
// OneDrive Business Account - always use a session to upload
|
||||
// The session includes a Request Body element containing lastModifiedDateTime
|
||||
// which negates the need for a modify event against OneDrive
|
||||
saveItem(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1110,23 +1156,35 @@ final class SyncEngine
|
|||
if (localFileModifiedTime > remoteFileModifiedTime){
|
||||
// local file is newer
|
||||
log.vlog("Requested file to upload is newer than existing file on OneDrive");
|
||||
|
||||
write("Uploading file ", path, " ...");
|
||||
JSONValue response;
|
||||
if (getSize(path) <= thresholdFileSize) {
|
||||
response = onedrive.simpleUpload(path, parent.driveId, parent.id, baseName(path));
|
||||
writeln(" done.");
|
||||
|
||||
if (accountType == "personal"){
|
||||
// OneDrive Personal account upload handling
|
||||
if (getSize(path) <= thresholdFileSize) {
|
||||
response = onedrive.simpleUpload(path, parent.driveId, parent.id, baseName(path));
|
||||
writeln(" done.");
|
||||
} else {
|
||||
writeln("");
|
||||
response = session.upload(path, parent.driveId, parent.id, baseName(path));
|
||||
writeln(" done.");
|
||||
}
|
||||
string id = response["id"].str;
|
||||
string cTag = response["cTag"].str;
|
||||
SysTime mtime = timeLastModified(path).toUTC();
|
||||
// use the cTag instead of the eTag because Onedrive may update the metadata of files AFTER they have been uploaded
|
||||
uploadLastModifiedTime(parent.driveId, id, cTag, mtime);
|
||||
} else {
|
||||
// OneDrive Business account upload handling
|
||||
writeln("");
|
||||
response = session.upload(path, parent.driveId, parent.id, baseName(path));
|
||||
writeln(" done.");
|
||||
saveItem(response);
|
||||
}
|
||||
|
||||
// Log action to log file
|
||||
log.fileOnly("Uploading file ", path, " ... done.");
|
||||
string id = response["id"].str;
|
||||
string cTag = response["cTag"].str;
|
||||
SysTime mtime = timeLastModified(path).toUTC();
|
||||
// use the cTag instead of the eTag because Onedrive may update the metadata of files AFTER they have been uploaded
|
||||
uploadLastModifiedTime(parent.driveId, id, cTag, mtime);
|
||||
|
||||
} else {
|
||||
// Save the details of the file that we got from OneDrive
|
||||
log.vlog("Updating the local database with details for this file: ", path);
|
||||
|
|
17
src/upload.d
17
src/upload.d
|
@ -23,7 +23,22 @@ struct UploadSession
|
|||
|
||||
JSONValue upload(string localPath, const(char)[] parentDriveId, const(char)[] parentId, const(char)[] filename, const(char)[] eTag = null)
|
||||
{
|
||||
session = onedrive.createUploadSession(parentDriveId, parentId, filename, eTag);
|
||||
// Fix https://github.com/abraunegg/onedrive/issues/2
|
||||
// More Details https://github.com/OneDrive/onedrive-api-docs/issues/778
|
||||
|
||||
SysTime localFileLastModifiedTime = timeLastModified(localPath).toUTC();
|
||||
localFileLastModifiedTime.fracSecs = Duration.zero;
|
||||
|
||||
JSONValue fileSystemInfo = [
|
||||
"item": JSONValue([
|
||||
"@name.conflictBehavior": JSONValue("replace"),
|
||||
"fileSystemInfo": JSONValue([
|
||||
"lastModifiedDateTime": localFileLastModifiedTime.toISOExtString()
|
||||
])
|
||||
])
|
||||
];
|
||||
|
||||
session = onedrive.createUploadSession(parentDriveId, parentId, filename, eTag, fileSystemInfo);
|
||||
session["localPath"] = localPath;
|
||||
save();
|
||||
return upload();
|
||||
|
|
Loading…
Reference in a new issue