From fc90ccb425af0131717e1f95d8b7f3f102df0cea Mon Sep 17 00:00:00 2001 From: abraunegg Date: Thu, 21 May 2020 06:48:02 +1000 Subject: [PATCH] Implement 'bypass_data_preservation' enhancement (Issue #824) (#831) * On some Linux distributions, the file system search tool locally modifies certain files after indexing. Even though the file contents has not changed, the file itself has, as the local modified timestamp has been updated. This then causes timestamp checks to be invalid. To ignore this in cases where this is occurring, configure 'bypass_data_preservation' to 'true' in the config file and local data protection rules will be ignored. * Add warning to application startup if 'bypass_data_preservation' has been enabled --- config | 1 + src/config.d | 3 +++ src/main.d | 6 ++++++ src/sync.d | 40 +++++++++++++++++++++++++++++----------- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/config b/config index c902e5b0..8b78f3d1 100644 --- a/config +++ b/config @@ -36,3 +36,4 @@ # skip_dir_strict_match = "false" # application_id = "" # resync = "false" +# bypass_data_preservation = "false" diff --git a/src/config.d b/src/config.d index fb8eaa22..96cfe4aa 100644 --- a/src/config.d +++ b/src/config.d @@ -78,6 +78,9 @@ final class Config stringValues["application_id"] = ""; // allow for resync to be set via config file boolValues["resync"] = false; + // Ignore data safety checks and overwrite local data rather than preserve & rename + // This is a config file option ONLY + boolValues["bypass_data_preservation"] = false; // DEVELOPER OPTIONS // display_memory = true | false diff --git a/src/main.d b/src/main.d index efb1681c..9ed589a2 100644 --- a/src/main.d +++ b/src/main.d @@ -673,6 +673,12 @@ int main(string[] args) // Do we configure to disable the upload validation routine if (cfg.getValueBool("disable_upload_validation")) sync.setDisableUploadValidation(); + // Has the user enabled to bypass data preservation of renaming local files when there is a conflict? + if (cfg.getValueBool("bypass_data_preservation")) { + log.log("WARNING: Application has been configured to bypass local data preservation in the event of file conflict."); + log.log("WARNING: Local data loss MAY occur in this scenario."); + } + // Do we need to validate the syncDir to check for the presence of a '.nosync' file if (cfg.getValueBool("check_nomount")) { // we were asked to check the mounts diff --git a/src/sync.d b/src/sync.d index 80c4967a..e14ad13a 100644 --- a/src/sync.d +++ b/src/sync.d @@ -1660,12 +1660,22 @@ final class SyncEngine log.vlog("Remote item modified time is newer based on UTC time conversion"); auto ext = extension(oldPath); auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext; - log.vlog("The local item is out-of-sync with OneDrive, renaming to preserve existing file: ", oldPath, " -> ", newPath); - if (!dryRun) { - safeRename(oldPath); + + // has the user configured to IGNORE local data protection rules? + if (cfg.getValueString("bypass_data_preservation")){ + // The user has configured to ignore data safety checks and overwrite local data rather than preserve & rename + log.vlog("WARNING: Local Data Protection has been disabled. You may experience data loss on this file: ", oldPath); } else { - // Expectation here is that there is a new file locally (newPath) however as we don't create this, the "new file" will not be uploaded as it does not exist - log.vdebug("DRY-RUN: Skipping local file rename"); + // local data protection is configured, renaming local file + log.vlog("The local item is out-of-sync with OneDrive, renaming to preserve existing file and prevent data loss: ", oldPath, " -> ", newPath); + + // perform the rename action + if (!dryRun) { + safeRename(oldPath); + } else { + // Expectation here is that there is a new file locally (newPath) however as we don't create this, the "new file" will not be uploaded as it does not exist + log.vdebug("DRY-RUN: Skipping local file rename"); + } } } } @@ -1760,13 +1770,21 @@ final class SyncEngine log.vlog("Remote item modified time is newer based on UTC time conversion"); auto ext = extension(path); auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext; - log.vlog("The local item is out-of-sync with OneDrive, renaming to preserve existing file: ", path, " -> ", newPath); - if (!dryRun) { - // rename the local file to prevent data loss incase the local file is actually needed - safeRename(path); + + // has the user configured to IGNORE local data protection rules? + if (cfg.getValueString("bypass_data_preservation")){ + // The user has configured to ignore data safety checks and overwrite local data rather than preserve & rename + log.vlog("WARNING: Local Data Protection has been disabled. You may experience data loss on this file: ", path); } else { - // Expectation here is that there is a new file locally (newPath) however as we don't create this, the "new file" will not be uploaded as it does not exist - log.vdebug("DRY-RUN: Skipping local file rename"); + // local data protection is configured, renaming local file + log.vlog("The local item is out-of-sync with OneDrive, renaming to preserve existing file and prevent data loss: ", path, " -> ", newPath); + // perform the rename action of the local file + if (!dryRun) { + safeRename(path); + } else { + // Expectation here is that there is a new file locally (newPath) however as we don't create this, the "new file" will not be uploaded as it does not exist + log.vdebug("DRY-RUN: Skipping local file rename"); + } } } }