rclone-api 1.0.56__py2.py3-none-any.whl → 1.0.57__py2.py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- rclone_api/rclone.py +111 -100
- {rclone_api-1.0.56.dist-info → rclone_api-1.0.57.dist-info}/METADATA +1 -1
- {rclone_api-1.0.56.dist-info → rclone_api-1.0.57.dist-info}/RECORD +7 -7
- {rclone_api-1.0.56.dist-info → rclone_api-1.0.57.dist-info}/LICENSE +0 -0
- {rclone_api-1.0.56.dist-info → rclone_api-1.0.57.dist-info}/WHEEL +0 -0
- {rclone_api-1.0.56.dist-info → rclone_api-1.0.57.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.0.56.dist-info → rclone_api-1.0.57.dist-info}/top_level.txt +0 -0
rclone_api/rclone.py
CHANGED
@@ -34,8 +34,6 @@ from rclone_api.util import (
|
|
34
34
|
)
|
35
35
|
from rclone_api.walk import walk
|
36
36
|
|
37
|
-
EXECUTOR = ThreadPoolExecutor(16)
|
38
|
-
|
39
37
|
|
40
38
|
def rclone_verbose(verbose: bool | None) -> bool:
|
41
39
|
if verbose is not None:
|
@@ -276,6 +274,9 @@ class Rclone:
|
|
276
274
|
verbose: bool | None = None,
|
277
275
|
checkers: int | None = None,
|
278
276
|
transfers: int | None = None,
|
277
|
+
low_level_retries: int | None = None,
|
278
|
+
retries: int | None = None,
|
279
|
+
max_partition_workers: int | None = None,
|
279
280
|
other_args: list[str] | None = None,
|
280
281
|
) -> list[CompletedProcess]:
|
281
282
|
"""Copy multiple files from source to destination.
|
@@ -283,6 +284,9 @@ class Rclone:
|
|
283
284
|
Args:
|
284
285
|
payload: Dictionary of source and destination file paths
|
285
286
|
"""
|
287
|
+
max_partition_workers = max_partition_workers or 8
|
288
|
+
low_level_retries = low_level_retries or 10
|
289
|
+
retries = retries or 3
|
286
290
|
other_args = other_args or []
|
287
291
|
checkers = checkers or 1000
|
288
292
|
transfers = transfers or 32
|
@@ -303,65 +307,69 @@ class Rclone:
|
|
303
307
|
|
304
308
|
futures: list[Future] = []
|
305
309
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
310
|
+
with ThreadPoolExecutor(max_workers=max_partition_workers) as executor:
|
311
|
+
for common_prefix, files in datalists.items():
|
312
|
+
|
313
|
+
def _task(files=files) -> subprocess.CompletedProcess:
|
314
|
+
with TemporaryDirectory() as tmpdir:
|
315
|
+
include_files_txt = Path(tmpdir) / "include_files.txt"
|
316
|
+
include_files_txt.write_text("\n".join(files), encoding="utf-8")
|
317
|
+
if common_prefix:
|
318
|
+
src_path = f"{src}/{common_prefix}"
|
319
|
+
dst_path = f"{dst}/{common_prefix}"
|
320
|
+
else:
|
321
|
+
src_path = src
|
322
|
+
dst_path = dst
|
323
|
+
|
324
|
+
if verbose:
|
325
|
+
nfiles = len(files)
|
326
|
+
files_fqdn = [f" {src_path}/{f}" for f in files]
|
327
|
+
print(f"Copying {nfiles} files:")
|
328
|
+
chunk_size = 100
|
329
|
+
for i in range(0, nfiles, chunk_size):
|
330
|
+
chunk = files_fqdn[i : i + chunk_size]
|
331
|
+
files_str = "\n".join(chunk)
|
332
|
+
print(f"{files_str}")
|
333
|
+
# files_str = "\n".join(files_fqdn)
|
334
|
+
# print(f"Copying {nfiles} files: \n{files_str}")
|
335
|
+
|
336
|
+
# print(include_files_txt)
|
337
|
+
cmd_list: list[str] = [
|
338
|
+
"copy",
|
339
|
+
src_path,
|
340
|
+
dst_path,
|
341
|
+
"--files-from",
|
342
|
+
str(include_files_txt),
|
343
|
+
"--checkers",
|
344
|
+
str(checkers),
|
345
|
+
"--transfers",
|
346
|
+
str(transfers),
|
347
|
+
"--low-level-retries",
|
348
|
+
str(low_level_retries),
|
349
|
+
"--retries",
|
350
|
+
str(retries),
|
351
|
+
]
|
352
|
+
if verbose:
|
353
|
+
if not any(["-v" in x for x in other_args]):
|
354
|
+
cmd_list.append("-vvvv")
|
355
|
+
if not any(["--progress" in x for x in other_args]):
|
356
|
+
cmd_list.append("--progress")
|
357
|
+
if other_args:
|
358
|
+
cmd_list += other_args
|
359
|
+
out = self._run(cmd_list, capture=not verbose)
|
360
|
+
return out
|
361
|
+
|
362
|
+
fut: Future = executor.submit(_task)
|
363
|
+
futures.append(fut)
|
364
|
+
for fut in futures:
|
365
|
+
cp: subprocess.CompletedProcess = fut.result()
|
366
|
+
assert cp is not None
|
367
|
+
out.append(CompletedProcess.from_subprocess(cp))
|
368
|
+
if cp.returncode != 0:
|
369
|
+
if check:
|
370
|
+
raise ValueError(f"Error deleting files: {cp.stderr}")
|
316
371
|
else:
|
317
|
-
|
318
|
-
dst_path = dst
|
319
|
-
|
320
|
-
if verbose:
|
321
|
-
nfiles = len(files)
|
322
|
-
files_fqdn = [f" {src_path}/{f}" for f in files]
|
323
|
-
print(f"Copying {nfiles} files:")
|
324
|
-
chunk_size = 100
|
325
|
-
for i in range(0, nfiles, chunk_size):
|
326
|
-
chunk = files_fqdn[i : i + chunk_size]
|
327
|
-
files_str = "\n".join(chunk)
|
328
|
-
print(f"{files_str}")
|
329
|
-
# files_str = "\n".join(files_fqdn)
|
330
|
-
# print(f"Copying {nfiles} files: \n{files_str}")
|
331
|
-
|
332
|
-
# print(include_files_txt)
|
333
|
-
cmd_list: list[str] = [
|
334
|
-
"copy",
|
335
|
-
src_path,
|
336
|
-
dst_path,
|
337
|
-
"--files-from",
|
338
|
-
str(include_files_txt),
|
339
|
-
"--checkers",
|
340
|
-
str(checkers),
|
341
|
-
"--transfers",
|
342
|
-
str(transfers),
|
343
|
-
]
|
344
|
-
if verbose:
|
345
|
-
if not any(["-v" in x for x in other_args]):
|
346
|
-
cmd_list.append("-vvvv")
|
347
|
-
if not any(["--progress" in x for x in other_args]):
|
348
|
-
cmd_list.append("--progress")
|
349
|
-
if other_args:
|
350
|
-
cmd_list += other_args
|
351
|
-
out = self._run(cmd_list, capture=not verbose)
|
352
|
-
return out
|
353
|
-
|
354
|
-
fut: Future = EXECUTOR.submit(_task)
|
355
|
-
futures.append(fut)
|
356
|
-
for fut in futures:
|
357
|
-
cp: subprocess.CompletedProcess = fut.result()
|
358
|
-
assert cp is not None
|
359
|
-
out.append(CompletedProcess.from_subprocess(cp))
|
360
|
-
if cp.returncode != 0:
|
361
|
-
if check:
|
362
|
-
raise ValueError(f"Error deleting files: {cp.stderr}")
|
363
|
-
else:
|
364
|
-
warnings.warn(f"Error deleting files: {cp.stderr}")
|
372
|
+
warnings.warn(f"Error deleting files: {cp.stderr}")
|
365
373
|
return out
|
366
374
|
|
367
375
|
def copy(self, src: Dir | str, dst: Dir | str) -> CompletedProcess:
|
@@ -393,6 +401,7 @@ class Rclone:
|
|
393
401
|
check=True,
|
394
402
|
rmdirs=False,
|
395
403
|
verbose: bool | None = None,
|
404
|
+
max_partition_workers: int | None = None,
|
396
405
|
other_args: list[str] | None = None,
|
397
406
|
) -> CompletedProcess:
|
398
407
|
"""Delete a directory"""
|
@@ -414,48 +423,50 @@ class Rclone:
|
|
414
423
|
|
415
424
|
futures: list[Future] = []
|
416
425
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
426
|
+
with ThreadPoolExecutor(max_workers=max_partition_workers) as executor:
|
427
|
+
|
428
|
+
for remote, files in datalists.items():
|
429
|
+
|
430
|
+
def _task(
|
431
|
+
files=files, check=check, remote=remote
|
432
|
+
) -> subprocess.CompletedProcess:
|
433
|
+
with TemporaryDirectory() as tmpdir:
|
434
|
+
include_files_txt = Path(tmpdir) / "include_files.txt"
|
435
|
+
include_files_txt.write_text("\n".join(files), encoding="utf-8")
|
436
|
+
|
437
|
+
# print(include_files_txt)
|
438
|
+
cmd_list: list[str] = [
|
439
|
+
"delete",
|
440
|
+
remote,
|
441
|
+
"--files-from",
|
442
|
+
str(include_files_txt),
|
443
|
+
"--checkers",
|
444
|
+
"1000",
|
445
|
+
"--transfers",
|
446
|
+
"1000",
|
447
|
+
]
|
448
|
+
if verbose:
|
449
|
+
cmd_list.append("-vvvv")
|
450
|
+
if rmdirs:
|
451
|
+
cmd_list.append("--rmdirs")
|
452
|
+
if other_args:
|
453
|
+
cmd_list += other_args
|
454
|
+
out = self._run(cmd_list, check=check)
|
455
|
+
if out.returncode != 0:
|
456
|
+
if check:
|
457
|
+
completed_processes.append(out)
|
458
|
+
raise ValueError(f"Error deleting files: {out}")
|
459
|
+
else:
|
460
|
+
warnings.warn(f"Error deleting files: {out}")
|
461
|
+
return out
|
451
462
|
|
452
|
-
|
453
|
-
|
463
|
+
fut: Future = executor.submit(_task)
|
464
|
+
futures.append(fut)
|
454
465
|
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
466
|
+
for fut in futures:
|
467
|
+
out = fut.result()
|
468
|
+
assert out is not None
|
469
|
+
completed_processes.append(out)
|
459
470
|
|
460
471
|
return CompletedProcess(completed_processes)
|
461
472
|
|
@@ -12,16 +12,16 @@ rclone_api/file.py,sha256=YtR5Y6c0YfXTS-sReOy2UgiSnafcAeO6b2hnbojBQD4,1423
|
|
12
12
|
rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
13
13
|
rclone_api/group_files.py,sha256=kOHh6ysFDkxjldSwvW6KqmiADUC1yFCdrZRY57TvbGY,5328
|
14
14
|
rclone_api/process.py,sha256=RrMfTe0bndmJ6gBK67ioqNvCstJ8aTC8RlGX1XBLlcw,4191
|
15
|
-
rclone_api/rclone.py,sha256=
|
15
|
+
rclone_api/rclone.py,sha256=gfXFdGNJ_najxH_xgSX_xk5Pv9i4DslNSlXJzf1i9N8,25466
|
16
16
|
rclone_api/remote.py,sha256=c9hlRKBCg1BFB9MCINaQIoCg10qyAkeqiS4brl8ce-8,343
|
17
17
|
rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
|
18
18
|
rclone_api/util.py,sha256=IWNOOcPE0xdKvehzXQ9okIppGDBYWJPIfdbUME8BFVM,4015
|
19
19
|
rclone_api/walk.py,sha256=kca0t1GAnF6FLclN01G8NG__Qe-ggodLtAbQSHyVPng,2968
|
20
20
|
rclone_api/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
21
21
|
rclone_api/cmd/list_files.py,sha256=x8FHODEilwKqwdiU1jdkeJbLwOqUkUQuDWPo2u_zpf0,741
|
22
|
-
rclone_api-1.0.
|
23
|
-
rclone_api-1.0.
|
24
|
-
rclone_api-1.0.
|
25
|
-
rclone_api-1.0.
|
26
|
-
rclone_api-1.0.
|
27
|
-
rclone_api-1.0.
|
22
|
+
rclone_api-1.0.57.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
23
|
+
rclone_api-1.0.57.dist-info/METADATA,sha256=IdoQc7o_OI7jGGTZOeFnRB_bxVYWI89XpIEAOqHSSkc,4489
|
24
|
+
rclone_api-1.0.57.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
|
25
|
+
rclone_api-1.0.57.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
|
26
|
+
rclone_api-1.0.57.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
27
|
+
rclone_api-1.0.57.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|