Skip to content

Commit 1603dff

Browse files
JoeZiminskiSushma-1706pre-commit-ci[bot]Copilot
authored
Improve transfer overwrite options (#696)
* refactor: clarify overwrite transfer options * docs: clarify overwrite transfer behavior * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Implement, manual test, update docs. * Working through tests. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix tests. * Update docs/source/pages/user_guides/transfer-data.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/source/pages/get_started/getting-started.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update datashuttle/utils/data_transfer.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update datashuttle/datashuttle_class.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix all docstrings. --------- Co-authored-by: Sushma-1706 <damacharlasushma@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 6bf7b46 commit 1603dff

10 files changed

Lines changed: 158 additions & 78 deletions

File tree

datashuttle/datashuttle_class.py

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,12 @@ def upload_custom(
352352
353353
overwrite_existing_files
354354
If ``"never"`` files on target will never be overwritten by source.
355-
If ``"always"`` files on target will be overwritten by source if
356-
there is any difference in date or size.
357355
If ``"if_source_newer"`` files on target will only be overwritten
358356
by files on source with newer creation / modification datetime.
357+
If ``"if_different"``, target will always be overwritten if the
358+
size or creation / modification datetimes differ.
359+
If ``"always"`` files on target will always be overwritten by source,
360+
even when size and creation / modification datetimes match.
359361
360362
dry_run
361363
Perform a dry-run of transfer. This will output as if file
@@ -442,10 +444,12 @@ def download_custom(
442444
443445
overwrite_existing_files
444446
If ``"never"`` files on target will never be overwritten by source.
445-
If ``"always"`` files on target will be overwritten by source if
446-
there is any difference in date or size.
447447
If ``"if_source_newer"`` files on target will only be overwritten
448448
by files on source with newer creation / modification datetime.
449+
If ``"if_different"``, target will always be overwritten if the
450+
size or creation / modification datetimes differ.
451+
If ``"always"`` files on target will always be overwritten by source,
452+
even when size and creation / modification datetimes match.
449453
450454
dry_run
451455
Perform a dry-run of transfer. This will output as if file
@@ -513,10 +517,12 @@ def upload_rawdata(
513517
----------
514518
overwrite_existing_files
515519
If ``"never"`` files on target will never be overwritten by source.
516-
If ``"always"`` files on target will be overwritten by source if
517-
there is any difference in date or size.
518520
If ``"if_source_newer"`` files on target will only be overwritten
519521
by files on source with newer creation / modification datetime.
522+
If ``"if_different"``, target will always be overwritten if the
523+
size or creation / modification datetimes differ.
524+
If ``"always"`` files on target will always be overwritten by source,
525+
even when size and creation / modification datetimes match.
520526
521527
dry_run
522528
Perform a dry-run of transfer. This will output as if file
@@ -543,10 +549,12 @@ def upload_derivatives(
543549
----------
544550
overwrite_existing_files
545551
If ``"never"`` files on target will never be overwritten by source.
546-
If ``"always"`` files on target will be overwritten by source if
547-
there is any difference in date or size.
548552
If ``"if_source_newer"`` files on target will only be overwritten
549553
by files on source with newer creation / modification datetime.
554+
If ``"if_different"``, target will always be overwritten if the
555+
size or creation / modification datetimes differ.
556+
If ``"always"`` files on target will always be overwritten by source,
557+
even when size and creation / modification datetimes match.
550558
551559
dry_run
552560
Perform a dry-run of transfer. This will output as if file
@@ -573,10 +581,12 @@ def download_rawdata(
573581
----------
574582
overwrite_existing_files
575583
If ``"never"`` files on target will never be overwritten by source.
576-
If ``"always"`` files on target will be overwritten by source if
577-
there is any difference in date or size.
578584
If ``"if_source_newer"`` files on target will only be overwritten
579585
by files on source with newer creation / modification datetime.
586+
If ``"if_different"``, target will always be overwritten if the
587+
size or creation / modification datetimes differ.
588+
If ``"always"`` files on target will always be overwritten by source,
589+
even when size and creation / modification datetimes match.
580590
581591
dry_run
582592
Perform a dry-run of transfer. This will output as if file
@@ -603,10 +613,12 @@ def download_derivatives(
603613
----------
604614
overwrite_existing_files
605615
If ``"never"`` files on target will never be overwritten by source.
606-
If ``"always"`` files on target will be overwritten by source if
607-
there is any difference in date or size.
608616
If ``"if_source_newer"`` files on target will only be overwritten
609617
by files on source with newer creation / modification datetime.
618+
If ``"if_different"``, target will always be overwritten if the
619+
size or creation / modification datetimes differ.
620+
If ``"always"`` files on target will always be overwritten by source,
621+
even when size and creation / modification datetimes match.
610622
611623
dry_run
612624
Perform a dry-run of transfer. This will output as if file
@@ -635,10 +647,12 @@ def upload_entire_project(
635647
----------
636648
overwrite_existing_files
637649
If ``"never"`` files on target will never be overwritten by source.
638-
If ``"always"`` files on target will be overwritten by source if
639-
there is any difference in date or size.
640650
If ``"if_source_newer"`` files on target will only be overwritten
641651
by files on source with newer creation / modification datetime.
652+
If ``"if_different"``, target will always be overwritten if the
653+
size or creation / modification datetimes differ.
654+
If ``"always"`` files on target will always be overwritten by source,
655+
even when size and creation / modification datetimes match.
642656
643657
dry_run
644658
Perform a dry-run of transfer. This will output as if file
@@ -675,10 +689,12 @@ def download_entire_project(
675689
----------
676690
overwrite_existing_files
677691
If ``"never"`` files on target will never be overwritten by source.
678-
If ``"always"`` files on target will be overwritten by source if
679-
there is any difference in date or size.
680692
If ``"if_source_newer"`` files on target will only be overwritten
681693
by files on source with newer creation / modification datetime.
694+
If ``"if_different"``, target will always be overwritten if the
695+
size or creation / modification datetimes differ.
696+
If ``"always"`` files on target will always be overwritten by source,
697+
even when size and creation / modification datetimes match.
682698
683699
dry_run
684700
Perform a dry-run of transfer. This will output as if file
@@ -722,10 +738,12 @@ def upload_specific_folder_or_file(
722738
723739
overwrite_existing_files
724740
If ``"never"`` files on target will never be overwritten by source.
725-
If ``"always"`` files on target will be overwritten by source if
726-
there is any difference in date or size.
727741
If ``"if_source_newer"`` files on target will only be overwritten
728742
by files on source with newer creation / modification datetime.
743+
If ``"if_different"``, target will always be overwritten if the
744+
size or creation / modification datetimes differ.
745+
If ``"always"`` files on target will always be overwritten by source,
746+
even when size and creation / modification datetimes match.
729747
730748
dry_run
731749
Perform a dry-run of transfer. This will output as if file
@@ -771,10 +789,12 @@ def download_specific_folder_or_file(
771789
772790
overwrite_existing_files
773791
If ``"never"`` files on target will never be overwritten by source.
774-
If ``"always"`` files on target will be overwritten by source if
775-
there is any difference in date or size.
776792
If ``"if_source_newer"`` files on target will only be overwritten
777793
by files on source with newer creation / modification datetime.
794+
IF ``"if_different"``, target will always be overwritten if the
795+
size or creation / modification datetimes differ.
796+
If ``"always"`` files on target will be overwritten by source if
797+
there is any difference in datetimes or size.
778798
779799
dry_run
780800
Perform a dry-run of transfer. This will output as if file

datashuttle/tui/tabs/transfer.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,12 @@ def compose(self) -> ComposeResult:
179179
Select(
180180
(
181181
(name, name)
182-
for name in ["Never", "Always", "If Source Newer"]
182+
for name in [
183+
"Never",
184+
"If Source Newer",
185+
"If Different",
186+
"Always",
187+
]
183188
),
184189
value=self.interface.tui_settings[
185190
"overwrite_existing_files"
@@ -238,7 +243,12 @@ def on_mount(self) -> None:
238243
def on_select_changed(self, event: Select.Changed) -> None:
239244
"""Handle a Select widget changed on the tab."""
240245
if event.select.id == "transfer_tab_overwrite_select":
241-
assert event.select.value in ["Never", "Always", "If Source Newer"]
246+
assert event.select.value in [
247+
"Never",
248+
"If Source Newer",
249+
"If Different",
250+
"Always",
251+
]
242252
format_select = event.select.value.lower().replace(" ", "_")
243253
self.interface.save_tui_settings(
244254
format_select,

datashuttle/utils/custom_types.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
TopLevelFolder = Literal["rawdata", "derivatives"]
88

9-
OverwriteExistingFiles = Literal["never", "always", "if_source_newer"]
9+
OverwriteExistingFiles = Literal[
10+
"never", "if_source_newer", "if_different", "always"
11+
]
1012

1113
Prefix = Literal["sub", "ses"]
1214

datashuttle/utils/data_transfer.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,13 @@ def __init__(
6262
6363
overwrite_existing_files
6464
If ``"never"`` files on target will never be overwritten by source.
65-
If ``"always"`` files on target will be overwritten by source if
66-
there is any difference in date or size.
6765
If ``"if_source_newer"`` files on target will only be overwritten
6866
by files on source with newer creation / modification datetime.
67+
If ``"if_different"``, target will always be overwritten if the
68+
size or creation / modification datetimes differ.
69+
If ``"always"``, files on target will always be overwritten by
70+
source, even when size and creation / modification datetimes
71+
are identical.
6972
7073
dry_run
7174
Perform a dry-run of transfer. This will output as if file

datashuttle/utils/rclone.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ def make_rclone_transfer_options(
799799
overwrite_existing_files: OverwriteExistingFiles, dry_run: bool
800800
) -> Dict:
801801
"""Create a dictionary of rclone transfer options."""
802-
allowed_overwrite = ["never", "always", "if_source_newer"]
802+
allowed_overwrite = ["never", "if_source_newer", "if_different", "always"]
803803

804804
if overwrite_existing_files not in allowed_overwrite:
805805
utils.log_and_raise_error(
@@ -967,9 +967,13 @@ def handle_rclone_arguments(
967967
if overwrite == "never":
968968
extra_arguments_list += [rclone_args("never_overwrite")]
969969

970-
elif overwrite == "always":
970+
elif overwrite == "if_different":
971+
# default rclone behavior (no flags)
971972
pass
972973

974+
elif overwrite == "always":
975+
extra_arguments_list += [rclone_args("always_overwrite")]
976+
973977
elif overwrite == "if_source_newer":
974978
extra_arguments_list += [rclone_args("if_source_newer_overwrite")]
975979

@@ -993,6 +997,7 @@ def rclone_args(name: str) -> str:
993997
"copy",
994998
"never_overwrite",
995999
"if_source_newer_overwrite",
1000+
"always_overwrite",
9961001
"progress",
9971002
"check",
9981003
]
@@ -1010,6 +1015,9 @@ def rclone_args(name: str) -> str:
10101015
if name == "if_source_newer_overwrite":
10111016
arg = "--update"
10121017

1018+
if name == "always_overwrite":
1019+
arg = "--ignore-times"
1020+
10131021
if name == "progress":
10141022
arg = "--progress"
10151023

docs/source/pages/get_started/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ central storage machine connected as a mounted drive or through SSH.
498498

499499
```{warning}
500500
The **overwrite existing files** setting is very important.
501-
It takes on the options **never**, **always** or **if source newer**.
501+
It takes on the options **never**, **if source newer**, **if_different**, or **always**.
502502
503503
See the [transfer options](transfer-options) section for full details.
504504
```

docs/source/pages/user_guides/transfer-data.md

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ allow transfer across:
4646

4747
```{warning}
4848
The **overwrite existing files** setting is very important.
49-
It takes on the options **never**, **always** or **if source newer**.
49+
It takes on the options **never**, **if source newer**, **if different** or **always**.
5050
5151
See the [transfer options](transfer-options) section for full details on
5252
this and other transfer settings.
@@ -304,28 +304,20 @@ Transfer a range
304304
(transfer-options)=
305305

306306
overwrite existing files
307-
: By default this option is set to **never**—a transfer will never overwrite a
308-
file that already exists, even if the source and destination modification datetimes
309-
or sizes are different.
310-
311-
: If *always**, when there are differences in datetime or size
312-
between the source and destination file the destination file will be overwritten.
313-
This includes when the source file is older or smaller than the destination.
314-
315-
: Finally, **if source newer** ensures data is only overwritten
316-
when the
317-
[source file has a more recent modification time](https://rclone.org/docs/#u-update)
318-
than the destination.
319-
If modification datetimes are equal, the destination will be overwritten if the
320-
sizes or checksums are different.
321-
322-
: Under the hood, transfers are made with calls to
323-
[Rclone](https://rclone.org/). Using **never**
324-
calls
325-
[Rclone's copy](https://rclone.org/commands/rclone_copy/)
326-
function with the flag `--ignore_existing`. Using
327-
**always** copies without this flag and (using Rclone's default overwrite behaviour.)
328-
Using **if source newer** calls copy with the `--update` flag.
307+
: Controls how existing files are handled during transfer.
308+
309+
: **never**
310+
Never overwrite existing files.
311+
312+
: **if_source_newer**
313+
Only overwrite files if the source file is newer than the destination.
314+
315+
: **if_different**
316+
Only overwrite files if the source and destination differ in
317+
modification time or size.
318+
319+
: **always**
320+
Always overwrite files, even if sizes and timestamps are identical.
329321

330322
(dry-run-argument)=
331323
dry run

0 commit comments

Comments
 (0)