mirror of
https://github.com/abraunegg/onedrive
synced 2024-05-17 05:06:55 +02:00
* Add --force-http-1.1 flag to downgrade any HTTP/2 curl operations to HTTP 1.1 protocol * Explicitly set all bool items to false at initialisation * Update --display-config to display sync_list if configured * Add debug handling to display when sync_list is loaded * Add debug handling to output the handling of OneDrive changes
This commit is contained in:
parent
ddc5d602da
commit
1fa7e5f20c
55
src/main.d
55
src/main.d
|
@ -17,7 +17,7 @@ int main(string[] args)
|
||||||
|
|
||||||
// Application Option Variables
|
// Application Option Variables
|
||||||
// Add a check mounts option to resolve https://github.com/abraunegg/onedrive/issues/8
|
// Add a check mounts option to resolve https://github.com/abraunegg/onedrive/issues/8
|
||||||
bool checkMount;
|
bool checkMount = false;
|
||||||
// configuration directory
|
// configuration directory
|
||||||
string configDirName;
|
string configDirName;
|
||||||
// Create a single root directory on OneDrive
|
// Create a single root directory on OneDrive
|
||||||
|
@ -25,7 +25,7 @@ int main(string[] args)
|
||||||
// The destination directory if we are using the OneDrive client to rename a directory
|
// The destination directory if we are using the OneDrive client to rename a directory
|
||||||
string destinationDirectory;
|
string destinationDirectory;
|
||||||
// Debug the HTTPS submit operations if required
|
// Debug the HTTPS submit operations if required
|
||||||
bool debugHttp;
|
bool debugHttp = false;
|
||||||
// Do not use notifications in monitor mode
|
// Do not use notifications in monitor mode
|
||||||
bool disableNotifications = false;
|
bool disableNotifications = false;
|
||||||
// Display application configuration but do not sync
|
// Display application configuration but do not sync
|
||||||
|
@ -33,45 +33,49 @@ int main(string[] args)
|
||||||
// Display sync status
|
// Display sync status
|
||||||
bool displaySyncStatus = false;
|
bool displaySyncStatus = false;
|
||||||
// only download remote changes
|
// only download remote changes
|
||||||
bool downloadOnly;
|
bool downloadOnly = false;
|
||||||
// Does the user want to disable upload validation - https://github.com/abraunegg/onedrive/issues/205
|
// Does the user want to disable upload validation - https://github.com/abraunegg/onedrive/issues/205
|
||||||
// SharePoint will associate some metadata from the library the file is uploaded to directly in the file - thus change file size & checksums
|
// SharePoint will associate some metadata from the library the file is uploaded to directly in the file - thus change file size & checksums
|
||||||
bool disableUploadValidation = false;
|
bool disableUploadValidation = false;
|
||||||
// Do we enable a log file
|
// Do we enable a log file
|
||||||
bool enableLogFile = false;
|
bool enableLogFile = false;
|
||||||
|
// Force the use of HTTP 1.1 to overcome curl => 7.62.0 where some operations are now sent via HTTP/2
|
||||||
|
// Whilst HTTP/2 operations are handled, in some cases the handling of this outside of the client is not being done correctly (router, other) thus the client breaks
|
||||||
|
// This flag then allows the user to downgrade all HTTP operations to HTTP 1.1 for maximum network path compatibility
|
||||||
|
bool forceHTTP11 = false;
|
||||||
// SharePoint / Office 365 Shared Library name to query
|
// SharePoint / Office 365 Shared Library name to query
|
||||||
string o365SharedLibraryName;
|
string o365SharedLibraryName;
|
||||||
// Local sync - Upload local changes first before downloading changes from OneDrive
|
// Local sync - Upload local changes first before downloading changes from OneDrive
|
||||||
bool localFirst;
|
bool localFirst = false;
|
||||||
// remove the current user and sync state
|
// remove the current user and sync state
|
||||||
bool logout;
|
bool logout = false;
|
||||||
// enable monitor mode
|
// enable monitor mode
|
||||||
bool monitor;
|
bool monitor = false;
|
||||||
// Add option for no remote delete
|
// Add option for no remote delete
|
||||||
bool noRemoteDelete;
|
bool noRemoteDelete = false;
|
||||||
// print the access token
|
// print the access token
|
||||||
bool printAccessToken;
|
bool printAccessToken = false;
|
||||||
// force a full resync
|
// force a full resync
|
||||||
bool resync;
|
bool resync = false;
|
||||||
// Remove a single directory on OneDrive
|
// Remove a single directory on OneDrive
|
||||||
string removeDirectory;
|
string removeDirectory;
|
||||||
// This allows for selective directory syncing instead of everything under ~/OneDrive/
|
// This allows for selective directory syncing instead of everything under ~/OneDrive/
|
||||||
string singleDirectory;
|
string singleDirectory;
|
||||||
// Add option to skip symlinks
|
// Add option to skip symlinks
|
||||||
bool skipSymlinks;
|
bool skipSymlinks = false;
|
||||||
// The source directory if we are using the OneDrive client to rename a directory
|
// The source directory if we are using the OneDrive client to rename a directory
|
||||||
string sourceDirectory;
|
string sourceDirectory;
|
||||||
// override the sync directory
|
// override the sync directory
|
||||||
string syncDirName;
|
string syncDirName;
|
||||||
// Configure a flag to perform a sync
|
// Configure a flag to perform a sync
|
||||||
// This is beneficial so that if just running the client itself - without any options, or sync check, the client does not perform a sync
|
// This is beneficial so that if just running the client itself - without any options, or sync check, the client does not perform a sync
|
||||||
bool synchronize;
|
bool synchronize = false;
|
||||||
// Upload Only
|
// Upload Only
|
||||||
bool uploadOnly;
|
bool uploadOnly = false;
|
||||||
// enable verbose logging
|
// enable verbose logging
|
||||||
bool verbose;
|
bool verbose = false;
|
||||||
// print the version and exit
|
// print the version and exit
|
||||||
bool printVersion;
|
bool printVersion = false;
|
||||||
|
|
||||||
// Application Startup option validation
|
// Application Startup option validation
|
||||||
try {
|
try {
|
||||||
|
@ -90,6 +94,7 @@ int main(string[] args)
|
||||||
"download-only|d", "Only download remote changes", &downloadOnly,
|
"download-only|d", "Only download remote changes", &downloadOnly,
|
||||||
"disable-upload-validation", "Disable upload validation when uploading to OneDrive", &disableUploadValidation,
|
"disable-upload-validation", "Disable upload validation when uploading to OneDrive", &disableUploadValidation,
|
||||||
"enable-logging", "Enable client activity to a separate log file", &enableLogFile,
|
"enable-logging", "Enable client activity to a separate log file", &enableLogFile,
|
||||||
|
"force-http-1.1", "Force the use of HTTP 1.1 for all operations", &forceHTTP11,
|
||||||
"get-O365-drive-id", "Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library", &o365SharedLibraryName,
|
"get-O365-drive-id", "Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library", &o365SharedLibraryName,
|
||||||
"local-first", "Synchronize from the local directory source first, before downloading changes from OneDrive.", &localFirst,
|
"local-first", "Synchronize from the local directory source first, before downloading changes from OneDrive.", &localFirst,
|
||||||
"logout", "Logout the current user", &logout,
|
"logout", "Logout the current user", &logout,
|
||||||
|
@ -276,6 +281,8 @@ int main(string[] args)
|
||||||
if (displayConfiguration){
|
if (displayConfiguration){
|
||||||
string userConfigFilePath = configDirName ~ "/config";
|
string userConfigFilePath = configDirName ~ "/config";
|
||||||
string userSyncList = configDirName ~ "/sync_list";
|
string userSyncList = configDirName ~ "/sync_list";
|
||||||
|
// Display application version
|
||||||
|
std.stdio.write("onedrive version = ", import("version"));
|
||||||
// Display all of the pertinent configuration options
|
// Display all of the pertinent configuration options
|
||||||
writeln("Config path = ", configDirName);
|
writeln("Config path = ", configDirName);
|
||||||
|
|
||||||
|
@ -301,6 +308,14 @@ int main(string[] args)
|
||||||
// Is sync_list configured?
|
// Is sync_list configured?
|
||||||
if (exists(userSyncList)){
|
if (exists(userSyncList)){
|
||||||
writeln("Selective sync configured = true");
|
writeln("Selective sync configured = true");
|
||||||
|
writeln("sync_list contents:");
|
||||||
|
// Output the sync_list contents
|
||||||
|
auto syncListFile = File(userSyncList);
|
||||||
|
auto range = syncListFile.byLine();
|
||||||
|
foreach (line; range)
|
||||||
|
{
|
||||||
|
writeln(line);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
writeln("Selective sync configured = false");
|
writeln("Selective sync configured = false");
|
||||||
}
|
}
|
||||||
|
@ -320,7 +335,7 @@ int main(string[] args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize OneDrive, check for authorization
|
// Initialize OneDrive, check for authorization
|
||||||
oneDrive = new OneDriveApi(cfg, debugHttp);
|
oneDrive = new OneDriveApi(cfg, debugHttp, forceHTTP11);
|
||||||
oneDrive.printAccessToken = printAccessToken;
|
oneDrive.printAccessToken = printAccessToken;
|
||||||
if (!oneDrive.init()) {
|
if (!oneDrive.init()) {
|
||||||
log.error("Could not initialize the OneDrive API");
|
log.error("Could not initialize the OneDrive API");
|
||||||
|
@ -362,6 +377,16 @@ int main(string[] args)
|
||||||
|
|
||||||
// Configure selective sync by parsing and getting a regex for skip_file config component
|
// Configure selective sync by parsing and getting a regex for skip_file config component
|
||||||
auto selectiveSync = new SelectiveSync();
|
auto selectiveSync = new SelectiveSync();
|
||||||
|
if (exists(cfg.syncListFilePath)){
|
||||||
|
log.vdebug("Loading user configured sync_list file ...");
|
||||||
|
// list what will be synced
|
||||||
|
auto syncListFile = File(cfg.syncListFilePath);
|
||||||
|
auto range = syncListFile.byLine();
|
||||||
|
foreach (line; range)
|
||||||
|
{
|
||||||
|
log.vdebug("sync_list: ", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
selectiveSync.load(cfg.syncListFilePath);
|
selectiveSync.load(cfg.syncListFilePath);
|
||||||
selectiveSync.setMask(cfg.getValue("skip_file"));
|
selectiveSync.setMask(cfg.getValue("skip_file"));
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ final class OneDriveApi
|
||||||
// if true, every new access token is printed
|
// if true, every new access token is printed
|
||||||
bool printAccessToken;
|
bool printAccessToken;
|
||||||
|
|
||||||
this(Config cfg, bool debugHttp)
|
this(Config cfg, bool debugHttp, bool forceHTTP11)
|
||||||
{
|
{
|
||||||
this.cfg = cfg;
|
this.cfg = cfg;
|
||||||
http = HTTP();
|
http = HTTP();
|
||||||
|
@ -91,10 +91,19 @@ final class OneDriveApi
|
||||||
// Specify how many redirects should be allowed
|
// Specify how many redirects should be allowed
|
||||||
http.maxRedirects(5);
|
http.maxRedirects(5);
|
||||||
|
|
||||||
|
// Do we enable curl debugging?
|
||||||
if (debugHttp) {
|
if (debugHttp) {
|
||||||
http.verbose = true;
|
http.verbose = true;
|
||||||
.debugResponse = true;
|
.debugResponse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// What version of HTTP protocol do we use?
|
||||||
|
// Curl >= 7.62.0 defaults to http2 for a significant number of operations
|
||||||
|
if (forceHTTP11) {
|
||||||
|
log.vdebug("Downgrading all HTTP operations to HTTP 1.1");
|
||||||
|
// Downgrade to HTTP 1.1 - yes version = 2 is HTTP 1.1
|
||||||
|
http.handle.set(CurlOption.http_version,2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init()
|
bool init()
|
||||||
|
|
28
src/sync.d
28
src/sync.d
|
@ -491,6 +491,14 @@ final class SyncEngine
|
||||||
syncFolderChildPath = "";
|
syncFolderChildPath = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debug Output
|
||||||
|
log.vdebug("Sync Folder Name: ", syncFolderName);
|
||||||
|
// Debug Output of path if only set, generally only set if using --single-directory
|
||||||
|
if (hasParentReferencePath(idDetails)) {
|
||||||
|
log.vdebug("Sync Folder Path: ", syncFolderPath);
|
||||||
|
log.vdebug("Sync Folder Child Path: ", syncFolderChildPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -542,6 +550,8 @@ final class SyncEngine
|
||||||
// Are there any changes to process?
|
// Are there any changes to process?
|
||||||
if (("value" in changes) != null) {
|
if (("value" in changes) != null) {
|
||||||
// There are valid changes
|
// There are valid changes
|
||||||
|
log.vdebug("Number of changes from OneDrive to process: ", count(changes["value"].array));
|
||||||
|
|
||||||
foreach (item; changes["value"].array) {
|
foreach (item; changes["value"].array) {
|
||||||
bool isRoot = false;
|
bool isRoot = false;
|
||||||
string thisItemPath;
|
string thisItemPath;
|
||||||
|
@ -642,7 +652,9 @@ final class SyncEngine
|
||||||
// Reset the downloadFailed flag for this item
|
// Reset the downloadFailed flag for this item
|
||||||
downloadFailed = false;
|
downloadFailed = false;
|
||||||
|
|
||||||
|
// Is the change from OneDrive a 'root' item
|
||||||
if (isItemRoot(driveItem) || !item.parentId || isRoot) {
|
if (isItemRoot(driveItem) || !item.parentId || isRoot) {
|
||||||
|
log.vdebug("Handing a OneDrive 'root' change");
|
||||||
item.parentId = null; // ensures that it has no parent
|
item.parentId = null; // ensures that it has no parent
|
||||||
item.driveId = driveId; // HACK: makeItem() cannot set the driveId property of the root
|
item.driveId = driveId; // HACK: makeItem() cannot set the driveId property of the root
|
||||||
itemdb.upsert(item);
|
itemdb.upsert(item);
|
||||||
|
@ -656,11 +668,11 @@ final class SyncEngine
|
||||||
// check the item type
|
// check the item type
|
||||||
if (!unwanted) {
|
if (!unwanted) {
|
||||||
if (isItemFile(driveItem)) {
|
if (isItemFile(driveItem)) {
|
||||||
//log.vlog("The item we are syncing is a file");
|
log.vdebug("The item we are syncing is a file");
|
||||||
} else if (isItemFolder(driveItem)) {
|
} else if (isItemFolder(driveItem)) {
|
||||||
//log.vlog("The item we are syncing is a folder");
|
log.vdebug("The item we are syncing is a folder");
|
||||||
} else if (isItemRemote(driveItem)) {
|
} else if (isItemRemote(driveItem)) {
|
||||||
//log.vlog("The item we are syncing is a remote item");
|
log.vdebug("The item we are syncing is a remote item");
|
||||||
assert(isItemFolder(driveItem["remoteItem"]), "The remote item is not a folder");
|
assert(isItemFolder(driveItem["remoteItem"]), "The remote item is not a folder");
|
||||||
} else {
|
} else {
|
||||||
log.vlog("This item type (", item.name, ") is not supported");
|
log.vlog("This item type (", item.name, ") is not supported");
|
||||||
|
@ -676,6 +688,9 @@ final class SyncEngine
|
||||||
path = itemdb.computePath(item.driveId, item.parentId) ~ "/" ~ item.name;
|
path = itemdb.computePath(item.driveId, item.parentId) ~ "/" ~ item.name;
|
||||||
path = buildNormalizedPath(path);
|
path = buildNormalizedPath(path);
|
||||||
unwanted = selectiveSync.isPathExcluded(path);
|
unwanted = selectiveSync.isPathExcluded(path);
|
||||||
|
if (unwanted) {
|
||||||
|
log.vdebug("OneDrive change path is to be excluded by user configuration: ", path);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
unwanted = true;
|
unwanted = true;
|
||||||
}
|
}
|
||||||
|
@ -683,7 +698,7 @@ final class SyncEngine
|
||||||
|
|
||||||
// skip unwanted items early
|
// skip unwanted items early
|
||||||
if (unwanted) {
|
if (unwanted) {
|
||||||
//log.vlog("Filtered out");
|
log.vdebug("Skipping OneDrive change as this is determined to be unwanted");
|
||||||
skippedItems ~= item.id;
|
skippedItems ~= item.id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -695,8 +710,7 @@ final class SyncEngine
|
||||||
// check if the item is going to be deleted
|
// check if the item is going to be deleted
|
||||||
if (isItemDeleted(driveItem)) {
|
if (isItemDeleted(driveItem)) {
|
||||||
// item.name is not available, so we get a bunch of meaningless log output
|
// item.name is not available, so we get a bunch of meaningless log output
|
||||||
// will fix this with wider logging changes being worked on
|
// Item name we will attempt to delete will be printed out later
|
||||||
//log.vlog("This item is marked for deletion:", item.name);
|
|
||||||
if (cached) {
|
if (cached) {
|
||||||
// flag to delete
|
// flag to delete
|
||||||
idsToDelete ~= [item.driveId, item.id];
|
idsToDelete ~= [item.driveId, item.id];
|
||||||
|
@ -723,8 +737,10 @@ final class SyncEngine
|
||||||
|
|
||||||
// update the item
|
// update the item
|
||||||
if (cached) {
|
if (cached) {
|
||||||
|
log.vdebug("OneDrive change is an update to an existing local item");
|
||||||
applyChangedItem(oldItem, oldPath, item, path);
|
applyChangedItem(oldItem, oldPath, item, path);
|
||||||
} else {
|
} else {
|
||||||
|
log.vdebug("OneDrive change is a new local item");
|
||||||
applyNewItem(item, path);
|
applyNewItem(item, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue