|
| 1 | +import os |
| 2 | +import platform |
1 | 3 | import subprocess |
| 4 | +import tempfile |
2 | 5 | from pathlib import Path |
3 | 6 | from subprocess import CompletedProcess |
4 | 7 | from typing import Dict, List, Literal |
@@ -30,6 +33,45 @@ def call_rclone(command: str, pipe_std: bool = False) -> CompletedProcess: |
30 | 33 | return output |
31 | 34 |
|
32 | 35 |
|
| 36 | +def call_rclone_through_script(command: str) -> CompletedProcess: |
| 37 | + """ |
| 38 | + Call rclone through a script, to avoid limits on command-line calls |
| 39 | + (in particular on Windows). Used for transfers due to generation of |
| 40 | + large call strings. |
| 41 | + """ |
| 42 | + system = platform.system() |
| 43 | + |
| 44 | + command = "rclone " + command |
| 45 | + |
| 46 | + if system == "Windows": |
| 47 | + suffix = ".bat" |
| 48 | + else: |
| 49 | + suffix = ".sh" |
| 50 | + command = "#!/bin/bash\n" + command |
| 51 | + |
| 52 | + with tempfile.NamedTemporaryFile( |
| 53 | + mode="w", suffix=suffix, delete=False |
| 54 | + ) as tmp_script: |
| 55 | + tmp_script.write(command) |
| 56 | + tmp_script_path = tmp_script.name |
| 57 | + |
| 58 | + try: |
| 59 | + if system != "Windows": |
| 60 | + os.chmod(tmp_script_path, 0o700) |
| 61 | + |
| 62 | + output = subprocess.run( |
| 63 | + [tmp_script_path], |
| 64 | + stdout=subprocess.PIPE, |
| 65 | + stderr=subprocess.PIPE, |
| 66 | + shell=False, |
| 67 | + ) |
| 68 | + |
| 69 | + finally: |
| 70 | + os.remove(tmp_script_path) |
| 71 | + |
| 72 | + return output |
| 73 | + |
| 74 | + |
33 | 75 | # ----------------------------------------------------------------------------- |
34 | 76 | # Setup |
35 | 77 | # ----------------------------------------------------------------------------- |
@@ -189,19 +231,17 @@ def transfer_data( |
189 | 231 | extra_arguments = handle_rclone_arguments(rclone_options, include_list) |
190 | 232 |
|
191 | 233 | if upload_or_download == "upload": |
192 | | - output = call_rclone( |
| 234 | + output = call_rclone_through_script( |
193 | 235 | f"{rclone_args('copy')} " |
194 | 236 | f'"{local_filepath}" "{cfg.get_rclone_config_name()}:' |
195 | 237 | f'{central_filepath}" {extra_arguments}', |
196 | | - pipe_std=True, |
197 | 238 | ) |
198 | 239 |
|
199 | 240 | elif upload_or_download == "download": |
200 | | - output = call_rclone( |
| 241 | + output = call_rclone_through_script( |
201 | 242 | f"{rclone_args('copy')} " |
202 | 243 | f'"{cfg.get_rclone_config_name()}:' |
203 | 244 | f'{central_filepath}" "{local_filepath}" {extra_arguments}', |
204 | | - pipe_std=True, |
205 | 245 | ) |
206 | 246 |
|
207 | 247 | return output |
|
0 commit comments