mirror of
https://github.com/abraunegg/onedrive
synced 2024-05-04 06:53:23 +02:00
Update with working state
* Update with working state
This commit is contained in:
parent
a3050bca54
commit
c1a619f82f
|
@ -201,6 +201,7 @@ class CurlEngine {
|
|||
bool keepAlive;
|
||||
ulong dnsTimeout;
|
||||
CurlResponse response;
|
||||
File uploadFile;
|
||||
|
||||
this() {
|
||||
http = HTTP();
|
||||
|
@ -210,6 +211,8 @@ class CurlEngine {
|
|||
~this() {
|
||||
object.destroy(http);
|
||||
object.destroy(response);
|
||||
if (uploadFile.isOpen())
|
||||
uploadFile.close();
|
||||
}
|
||||
|
||||
void initialise(ulong dnsTimeout, ulong connectTimeout, ulong dataTimeout, ulong operationTimeout, int maxRedirects, bool httpsDebug, string userAgent, bool httpProtocol, ulong userRateLimit, ulong protocolVersion, bool keepAlive=true) {
|
||||
|
@ -337,10 +340,25 @@ class CurlEngine {
|
|||
}
|
||||
}
|
||||
|
||||
void setFile(File* file, ulong offsetSize) {
|
||||
void setFile(string filepath, string contentRange, ulong offset, ulong offsetSize) {
|
||||
setResponseHolder(null);
|
||||
// open file as read-only in binary mode
|
||||
uploadFile = File(filepath, "rb");
|
||||
|
||||
if (contentRange.empty) {
|
||||
offsetSize = uploadFile.size();
|
||||
} else {
|
||||
addRequestHeader("Content-Range", contentRange);
|
||||
uploadFile.seek(offset);
|
||||
}
|
||||
|
||||
// Setup progress bar to display
|
||||
http.onProgress = delegate int(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
addRequestHeader("Content-Type", "application/octet-stream");
|
||||
http.onSend = data => file.rawRead(data).length;
|
||||
http.onSend = data => uploadFile.rawRead(data).length;
|
||||
http.contentLength = offsetSize;
|
||||
}
|
||||
|
||||
|
@ -362,9 +380,6 @@ class CurlEngine {
|
|||
|
||||
CurlResponse download(string originalFilename, string downloadFilename) {
|
||||
setResponseHolder(null);
|
||||
// Threshold for displaying download bar
|
||||
long thresholdFileSize = 4 * 2^^20; // 4 MiB
|
||||
|
||||
// open downloadFilename as write in binary mode
|
||||
auto file = File(downloadFilename, "wb");
|
||||
|
||||
|
@ -403,6 +418,12 @@ class CurlEngine {
|
|||
};
|
||||
http.contentLength = 0;
|
||||
response = null;
|
||||
|
||||
// close file if open
|
||||
if (uploadFile.isOpen()){
|
||||
// close open file
|
||||
uploadFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
|
|
27
src/itemdb.d
27
src/itemdb.d
|
@ -208,13 +208,38 @@ final class ItemDatabase {
|
|||
if (e.msg == "database is locked") {
|
||||
addLogEntry();
|
||||
addLogEntry("ERROR: The 'onedrive' application is already running - please check system process list for active application instances");
|
||||
addLogEntry(" - Use 'sudo ps aufxw | grep onedrive' to potentially determine acive running process", ["verbose"]);
|
||||
addLogEntry(" - Use 'sudo ps aufxw | grep onedrive' to potentially determine acive running process");
|
||||
addLogEntry();
|
||||
} else {
|
||||
// A different error .. detail the message, detail the actual SQLite Error Code to assist with troubleshooting
|
||||
addLogEntry();
|
||||
addLogEntry("ERROR: An internal database error occurred: " ~ e.msg ~ " (SQLite Error Code: " ~ to!string(e.errorCode) ~ ")");
|
||||
addLogEntry();
|
||||
|
||||
// Give the user some additional information and pointers on this error
|
||||
// The below list is based on user issue / discussion reports since 2018
|
||||
switch (e.errorCode) {
|
||||
case 7: // SQLITE_NOMEM
|
||||
addLogEntry("The operation could not be completed due to insufficient memory. Please close unnecessary applications to free up memory and try again.");
|
||||
break;
|
||||
case 10: // SQLITE_IOERR
|
||||
addLogEntry("A disk I/O error occurred. This could be due to issues with the storage medium (e.g., disk full, hardware failure, filesystem corruption). Please check your disk's health using a disk utility tool, ensure there is enough free space, and check the filesystem for errors.");
|
||||
break;
|
||||
case 11: // SQLITE_CORRUPT
|
||||
addLogEntry("The database file appears to be corrupt. This could be due to incomplete or failed writes, hardware issues, or unexpected interruptions during database operations. Please perform a --resync operation.");
|
||||
break;
|
||||
case 14: // SQLITE_CANTOPEN
|
||||
addLogEntry("The database file could not be opened. Please check that the database file exists, has the correct permissions, and is not being blocked by another process or security software.");
|
||||
break;
|
||||
case 26: // SQLITE_NOTADB
|
||||
addLogEntry("The file attempted to be opened does not appear to be a valid SQLite database, or it may have been corrupted to a point where it's no longer recognizable. Please check your application configuration directory and/or perform a --resync operation.");
|
||||
break;
|
||||
default:
|
||||
addLogEntry("An unexpected error occurred. Please consult the application documentation or support to resolve this issue.");
|
||||
break;
|
||||
}
|
||||
// Blank line before exit
|
||||
addLogEntry();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -392,12 +392,10 @@ class OneDriveApi {
|
|||
string authFilesString = appConfig.getValueString("auth_files");
|
||||
string authResponseString = appConfig.getValueString("auth_response");
|
||||
|
||||
// Is authResponseString not empty
|
||||
if (!authResponseString.empty) {
|
||||
// read the response from authResponseString
|
||||
response = cast(char[]) authResponseString;
|
||||
} else if (authFilesString != "") {
|
||||
// authResponseString empty .. is authFilesString not empty
|
||||
string[] authFiles = authFilesString.split(":");
|
||||
string authUrl = authFiles[0];
|
||||
string responseUrl = authFiles[1];
|
||||
|
@ -422,7 +420,6 @@ class OneDriveApi {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
// Add logging that we are waiting for auth elements to be available
|
||||
addLogEntry("Client requires authentication before proceeding. Waiting for --auth-files elements to be available.");
|
||||
|
||||
while (!exists(responseUrl)) {
|
||||
|
@ -529,7 +526,6 @@ class OneDriveApi {
|
|||
// Return all the items that are shared with the user
|
||||
// https://docs.microsoft.com/en-us/graph/api/drive-sharedwithme
|
||||
JSONValue getSharedWithMe() {
|
||||
checkAccessTokenExpired();
|
||||
return get(sharedWithMeUrl);
|
||||
}
|
||||
|
||||
|
@ -683,7 +679,6 @@ class OneDriveApi {
|
|||
}
|
||||
|
||||
JSONValue createSubscription(string notificationUrl, SysTime expirationDateTime) {
|
||||
checkAccessTokenExpired();
|
||||
string driveId = appConfig.getValueString("drive_id");
|
||||
string url = subscriptionUrl;
|
||||
|
||||
|
@ -772,7 +767,6 @@ class OneDriveApi {
|
|||
|
||||
// Private OneDrive API Functions
|
||||
private void addIncludeFeatureRequestHeader(string[string]* headers) {
|
||||
|
||||
addLogEntry("Adding 'Include-Feature=AddToOneDrive' API request header as 'sync_business_shared_items' config option is enabled", ["debug"]);
|
||||
(*headers)["Prefer"] = "Include-Feature=AddToOneDrive";
|
||||
}
|
||||
|
@ -919,10 +913,11 @@ class OneDriveApi {
|
|||
}
|
||||
|
||||
private void performDelete(const(char)[] url, string[string] requestHeaders=null, string callingFunction=__FUNCTION__, int lineno=__LINE__) {
|
||||
bool validateJSONResponse = false;
|
||||
oneDriveErrorHandlerWrapper((CurlResponse response) {
|
||||
connect(HTTP.Method.del, url, false, response, requestHeaders);
|
||||
return curlEngine.execute();
|
||||
}, callingFunction, lineno);
|
||||
}, validateJSONResponse, callingFunction, lineno);
|
||||
}
|
||||
|
||||
private void downloadFile(const(char)[] url, string filename, long fileSize, string callingFunction=__FUNCTION__, int lineno=__LINE__) {
|
||||
|
@ -1067,55 +1062,42 @@ class OneDriveApi {
|
|||
}
|
||||
|
||||
private JSONValue get(string url, bool skipToken = false, string[string] requestHeaders=null, string callingFunction=__FUNCTION__, int lineno=__LINE__) {
|
||||
bool validateJSONResponse = true;
|
||||
return oneDriveErrorHandlerWrapper((CurlResponse response) {
|
||||
connect(HTTP.Method.get, url, skipToken, response, requestHeaders);
|
||||
return curlEngine.execute();
|
||||
}, callingFunction, lineno);
|
||||
}, validateJSONResponse, callingFunction, lineno);
|
||||
}
|
||||
|
||||
private JSONValue patch(const(char)[] url, const(char)[] patchData, string[string] requestHeaders=null, const(char)[] contentType = "application/json", string callingFunction=__FUNCTION__, int lineno=__LINE__) {
|
||||
bool validateJSONResponse = true;
|
||||
return oneDriveErrorHandlerWrapper((CurlResponse response) {
|
||||
connect(HTTP.Method.patch, url, false, response, requestHeaders);
|
||||
curlEngine.setContent(contentType, patchData);
|
||||
return curlEngine.execute();
|
||||
}, callingFunction, lineno);
|
||||
}, validateJSONResponse, callingFunction, lineno);
|
||||
}
|
||||
|
||||
private JSONValue post(const(char)[] url, const(char)[] postData, bool skipToken = false, const(char)[] contentType = "application/json", string callingFunction=__FUNCTION__, int lineno=__LINE__) {
|
||||
bool validateJSONResponse = true;
|
||||
return oneDriveErrorHandlerWrapper((CurlResponse response) {
|
||||
connect(HTTP.Method.post, url, skipToken, response);
|
||||
curlEngine.setContent(contentType, postData);
|
||||
return curlEngine.execute();
|
||||
}, callingFunction, lineno);
|
||||
}, validateJSONResponse, callingFunction, lineno);
|
||||
}
|
||||
|
||||
private JSONValue put(const(char)[] url, string filepath, bool skipToken=false, string contentRange=null, ulong offset=0, ulong offsetSize=0, string callingFunction=__FUNCTION__, int lineno=__LINE__) {
|
||||
bool validateJSONResponse = true;
|
||||
return oneDriveErrorHandlerWrapper((CurlResponse response) {
|
||||
string[string] requestHeaders;
|
||||
// open file as read-only in binary mode
|
||||
auto file = File(filepath, "rb");
|
||||
if (!contentRange.empty)
|
||||
file.seek(offset);
|
||||
// function scopes
|
||||
scope(exit) {
|
||||
// close file if open
|
||||
if (file.isOpen()){
|
||||
// close open file
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
if (!contentRange.empty)
|
||||
requestHeaders["Content-Range"] = contentRange;
|
||||
else
|
||||
offsetSize = file.size;
|
||||
connect(HTTP.Method.put, url, skipToken, response, requestHeaders);
|
||||
curlEngine.setFile(&file, offsetSize);
|
||||
connect(HTTP.Method.put, url, skipToken, response);
|
||||
curlEngine.setFile(filepath, contentRange, offset, offsetSize);
|
||||
return curlEngine.execute();
|
||||
}, callingFunction, lineno);
|
||||
}, validateJSONResponse, callingFunction, lineno);
|
||||
}
|
||||
|
||||
// Wrapper function for all requests to OneDrive API
|
||||
// throws a OneDriveException
|
||||
// throws OneDriveException
|
||||
private JSONValue oneDriveErrorHandlerWrapper(CurlResponse delegate(CurlResponse response) executer, bool validateJSONResponse, string callingFunction, int lineno) {
|
||||
int maxRetryCount = 10;
|
||||
int retryAttempts = 0;
|
||||
|
|
|
@ -4847,11 +4847,11 @@ class SyncEngine {
|
|||
onlinePathData = foundDirectoryJSONItem;
|
||||
} else {
|
||||
// No 'search item matches found' - raise a 404 so that the exception handling will take over to create the folder
|
||||
throw new OneDriveException(404, "Name not found via search", null);
|
||||
throw new OneDriveException(404, "Name not found via search");
|
||||
}
|
||||
} else {
|
||||
// No 'search item matches found' - raise a 404 so that the exception handling will take over to create the folder
|
||||
throw new OneDriveException(404, "Name not found via search", null);
|
||||
throw new OneDriveException(404, "Name not found via search");
|
||||
}
|
||||
}
|
||||
} catch (OneDriveException exception) {
|
||||
|
|
Loading…
Reference in a new issue