diff --git a/docs/algorithm.md b/docs/algorithm.md index 315a8d7..58ef78a 100644 --- a/docs/algorithm.md +++ b/docs/algorithm.md @@ -14,16 +14,16 @@ Assuming all sources are reliable. We list all combinations mutually exclusive and collectively exhaustive. -| ID | Remote Files | Local files | Local delete rename history | Extra | Decision | -| --- | ------------ | ----------- | --------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -| 1 | exist | exist | ignore | mtime_remote > mtime_local | download remote file, create local folder if not exists, clear local history if exists | -| 2 | exist | exist | ignore | mtime_remote < mtime_local | upload local file, create remote folder if not exists, clear local history if exists | -| 3 | exist | exist | ignore | mtime_remote === mtime_local && size_remote === size_local | clear local history if exists (the file was synced and no changes after last sync) | -| 4 | exist | exist | ignore | mtime_remote === mtime_local && size_remote !== size_local | upload local file, clear local history if exists (we always prefer local to remote) | -| 5 | exist | exist | ignore | If local is a folder. mtime_local === undefined | clear local history if exists. TODO: what if a folder and a previous file share the same name? | -| 6 | exist | not exist | exist | mtime_remote >= delete_time_local | download remote file, create folder if not exists | -| 7 | exist | not exist | exist | mtime_remote < delete_time_local | delete remote file, clear local history | -| 8 | exist | not exist | not exist | | download remote file, create folder if not exists | -| 9 | not exist | exist | ignore | If local is a single file. | upload local file, create remote folder if not exists, clear local history if exists | -| 10 | not exist | exist | ignore | If local is a folder. | upload local files recursively, create remote folder if not exists, clear local history if exists | -| 11 | not exist | not exist | ignore | | clear local history if exists | +| ID | Remote Files | Local files | Local delete rename history | Extra | Decision | +| ---- | ------------ | ----------- | --------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| 1 | exist | exist | ignore | mtime_remote > mtime_local | download remote file, create local folder if not exists, clear local history if exists | +| 2 | exist | exist | ignore | mtime_remote < mtime_local | upload local file, create remote folder if not exists, clear local history if exists | +| 3 | exist | exist | ignore | mtime_remote === mtime_local && password === "" && size_remote === size_local | clear local history if exists (the file was synced and no changes after last sync) | +| 4 | exist | exist | ignore | mtime_remote === mtime_local && password === "" && size_remote !== size_local | upload local file, clear local history if exists (we always prefer local to remote) | +| 5 | exist | exist | ignore | mtime_remote === mtime_local && password !== "" | clear local history if exists (in encryption mode, file sizes are unequal. we can only rely on mtime(s)) | +| 6 | exist | exist | ignore | If local is a folder. mtime_local === undefined | clear local history if exists. TODO: what if a folder and a previous file share the same name? | +| 7 | exist | not exist | exist | mtime_remote >= delete_time_local | download remote file, create folder if not exists | +| 8 | exist | not exist | exist | mtime_remote < delete_time_local | delete remote file, clear local history | +| 9 | exist | not exist | not exist | | download remote file, create folder if not exists | +| 10 | not exist | exist | ignore | local may be folder or file | upload local files recursively, create remote folder if not exists, clear local history if exists | +| 11 | not exist | not exist | ignore | | clear local history if exists | diff --git a/src/sync.ts b/src/sync.ts index 7db9219..d2ef4f5 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -190,7 +190,8 @@ const ensembleMixedStates = async ( const getOperation = ( origRecord: FileOrFolderMixedState, - inplace: boolean = false + inplace: boolean = false, + password: string = "" ) => { let r = origRecord; if (!inplace) { @@ -238,6 +239,7 @@ const getOperation = ( r.mtime_remote !== undefined && r.mtime_local !== undefined && r.mtime_remote === r.mtime_local && + password === "" && r.size_local === r.size_remote ) { r.decision = "skip"; @@ -248,17 +250,31 @@ const getOperation = ( r.mtime_remote !== undefined && r.mtime_local !== undefined && r.mtime_remote === r.mtime_local && + password === "" && r.size_local !== r.size_remote ) { r.decision = "upload_clearhist"; r.decision_branch = 4; + } else if ( + r.exist_remote && + r.exist_local && + r.mtime_remote !== undefined && + r.mtime_local !== undefined && + r.mtime_remote === r.mtime_local && + password !== "" + ) { + // if we have encryption, + // the size is always unequal + // only mtime(s) are reliable + r.decision = "skip"; + r.decision_branch = 5; } else if (r.exist_remote && r.exist_local && r.mtime_local === undefined) { // this must be a folder! if (!r.key.endsWith("/")) { throw Error(`${r.key} is not a folder but lacks local mtime`); } r.decision = "skip"; - r.decision_branch = 5; + r.decision_branch = 6; } else if ( r.exist_remote && !r.exist_local && @@ -268,7 +284,7 @@ const getOperation = ( r.mtime_remote >= r.delete_time_local ) { r.decision = "download_clearhist"; - r.decision_branch = 6; + r.decision_branch = 7; } else if ( r.exist_remote && !r.exist_local && @@ -278,7 +294,7 @@ const getOperation = ( r.mtime_remote < r.delete_time_local ) { r.decision = "delremote_clearhist"; - r.decision_branch = 7; + r.decision_branch = 8; } else if ( r.exist_remote && !r.exist_local && @@ -287,10 +303,10 @@ const getOperation = ( r.delete_time_local == undefined ) { r.decision = "download"; - r.decision_branch = 8; + r.decision_branch = 9; } else if (!r.exist_remote && r.exist_local && r.mtime_remote === undefined) { r.decision = "upload_clearhist"; - r.decision_branch = 9; + r.decision_branch = 10; } else if ( !r.exist_remote && !r.exist_local && @@ -298,7 +314,7 @@ const getOperation = ( r.mtime_local === undefined ) { r.decision = "clearhist"; - r.decision_branch = 10; + r.decision_branch = 11; } return r;