diff --git a/src/main.d b/src/main.d index a3816b3b..7de18af7 100644 --- a/src/main.d +++ b/src/main.d @@ -678,6 +678,7 @@ int main(string[] args) 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."); + sync.setBypassDataPreservation(); } // Do we need to validate the syncDir to check for the presence of a '.nosync' file diff --git a/src/sync.d b/src/sync.d index 96b71b05..d8ced635 100644 --- a/src/sync.d +++ b/src/sync.d @@ -238,6 +238,9 @@ final class SyncEngine private bool syncListConfigured = false; // sync_list new folder added, trigger delta scan override private bool oneDriveFullScanTrigger = false; + // is bypass_data_preservation set via config file + // Local data loss MAY occur in this scenario + private bool bypassDataPreservation = false; this(Config cfg, OneDriveApi onedrive, ItemDatabase itemdb, SelectiveSync selectiveSync) { @@ -482,6 +485,13 @@ final class SyncEngine log.vdebug("Setting syncListConfigured = true"); } + // set bypassDataPreservation to true + void setBypassDataPreservation() + { + bypassDataPreservation = true; + log.vdebug("Setting bypassDataPreservation = true"); + } + // download all new changes from OneDrive void applyDifferences(bool performFullItemScan) { @@ -1662,7 +1672,7 @@ final class SyncEngine auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext; // has the user configured to IGNORE local data protection rules? - if (cfg.getValueString("bypass_data_preservation")){ + if (bypassDataPreservation) { // 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 { @@ -1741,12 +1751,14 @@ final class SyncEngine // local file is newer than item on OneDrive based on file modified time // Is this item id in the database? if (itemdb.idInLocalDatabase(item.driveId, item.id)){ + // item id is in the database // no local rename // no download needed log.vlog("Local item modified time is newer based on UTC time conversion - keeping local item as this exists in the local database"); log.vdebug("Skipping OneDrive change as this is determined to be unwanted due to local item modified time being newer than OneDrive item and present in the sqlite database"); return; } else { + // item id is not in the database .. maybe a --resync ? // Should this 'download' be skipped? // Do we need to check for .nosync? Only if --check-for-nosync was passed in if (cfg.getValueBool("check_nosync")) { @@ -1764,6 +1776,33 @@ final class SyncEngine } // file exists locally but is not in the sqlite database - maybe a failed download? log.vlog("Local item does not exist in local database - replacing with file from OneDrive - failed download?"); + + // was --resync issued? + if (cfg.getValueBool("resync")) { + // in a --resync scenario we have zero way of knowing IF the local file is meant to be the right file + // we have passed the following checks: + // 1. file exists locally + // 2. local modified time > remote modified time + // 3. id is not in the database + // 4. --resync was issued + auto ext = extension(path); + auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext; + // has the user configured to IGNORE local data protection rules? + if (bypassDataPreservation) { + // 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 { + // 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 due to --resync: ", 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"); + } + } + } } } else { // remote file is newer than local item @@ -1772,7 +1811,7 @@ final class SyncEngine auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext; // has the user configured to IGNORE local data protection rules? - if (cfg.getValueString("bypass_data_preservation")){ + if (bypassDataPreservation) { // 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 {