rclone-api 1.0.73__tar.gz → 1.0.76__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. {rclone_api-1.0.73 → rclone_api-1.0.76}/PKG-INFO +1 -1
  2. {rclone_api-1.0.73 → rclone_api-1.0.76}/pyproject.toml +1 -1
  3. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/diff.py +2 -3
  4. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/dir.py +1 -1
  5. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/rclone.py +18 -0
  6. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/scan_missing_folders.py +26 -16
  7. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api.egg-info/PKG-INFO +1 -1
  8. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_diff.py +2 -2
  9. {rclone_api-1.0.73 → rclone_api-1.0.76}/.aiderignore +0 -0
  10. {rclone_api-1.0.73 → rclone_api-1.0.76}/.github/workflows/lint.yml +0 -0
  11. {rclone_api-1.0.73 → rclone_api-1.0.76}/.github/workflows/push_macos.yml +0 -0
  12. {rclone_api-1.0.73 → rclone_api-1.0.76}/.github/workflows/push_ubuntu.yml +0 -0
  13. {rclone_api-1.0.73 → rclone_api-1.0.76}/.github/workflows/push_win.yml +0 -0
  14. {rclone_api-1.0.73 → rclone_api-1.0.76}/.gitignore +0 -0
  15. {rclone_api-1.0.73 → rclone_api-1.0.76}/.pylintrc +0 -0
  16. {rclone_api-1.0.73 → rclone_api-1.0.76}/.vscode/launch.json +0 -0
  17. {rclone_api-1.0.73 → rclone_api-1.0.76}/.vscode/settings.json +0 -0
  18. {rclone_api-1.0.73 → rclone_api-1.0.76}/.vscode/tasks.json +0 -0
  19. {rclone_api-1.0.73 → rclone_api-1.0.76}/LICENSE +0 -0
  20. {rclone_api-1.0.73 → rclone_api-1.0.76}/MANIFEST.in +0 -0
  21. {rclone_api-1.0.73 → rclone_api-1.0.76}/README.md +0 -0
  22. {rclone_api-1.0.73 → rclone_api-1.0.76}/clean +0 -0
  23. {rclone_api-1.0.73 → rclone_api-1.0.76}/install +0 -0
  24. {rclone_api-1.0.73 → rclone_api-1.0.76}/lint +0 -0
  25. {rclone_api-1.0.73 → rclone_api-1.0.76}/requirements.testing.txt +0 -0
  26. {rclone_api-1.0.73 → rclone_api-1.0.76}/setup.cfg +0 -0
  27. {rclone_api-1.0.73 → rclone_api-1.0.76}/setup.py +0 -0
  28. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/__init__.py +0 -0
  29. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/assets/example.txt +0 -0
  30. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/cli.py +0 -0
  31. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/cmd/list_files.py +0 -0
  32. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/completed_process.py +0 -0
  33. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/config.py +0 -0
  34. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/convert.py +0 -0
  35. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/deprecated.py +0 -0
  36. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/dir_listing.py +0 -0
  37. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/exec.py +0 -0
  38. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/file.py +0 -0
  39. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/filelist.py +0 -0
  40. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/group_files.py +0 -0
  41. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/process.py +0 -0
  42. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/remote.py +0 -0
  43. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/rpath.py +0 -0
  44. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/types.py +0 -0
  45. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/util.py +0 -0
  46. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api/walk.py +0 -0
  47. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api.egg-info/SOURCES.txt +0 -0
  48. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  49. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api.egg-info/entry_points.txt +0 -0
  50. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api.egg-info/requires.txt +0 -0
  51. {rclone_api-1.0.73 → rclone_api-1.0.76}/src/rclone_api.egg-info/top_level.txt +0 -0
  52. {rclone_api-1.0.73 → rclone_api-1.0.76}/test +0 -0
  53. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_cmd_list_files.py +0 -0
  54. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_copy.py +0 -0
  55. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_copy_files.py +0 -0
  56. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_group_files.py +0 -0
  57. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_is_synced.py +0 -0
  58. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_ls.py +0 -0
  59. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_mount.py +0 -0
  60. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_mount_s3.py +0 -0
  61. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_mount_webdav.py +0 -0
  62. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_obscure.py +0 -0
  63. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_remote_control.py +0 -0
  64. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_remotes.py +0 -0
  65. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_scan_missing_folders.py +0 -0
  66. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_serve_webdav.py +0 -0
  67. {rclone_api-1.0.73 → rclone_api-1.0.76}/tests/test_walk.py +0 -0
  68. {rclone_api-1.0.73 → rclone_api-1.0.76}/tox.ini +0 -0
  69. {rclone_api-1.0.73 → rclone_api-1.0.76}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.73
3
+ Version: 1.0.76
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
@@ -15,7 +15,7 @@ dependencies = [
15
15
  "python-dotenv>=1.0.0",
16
16
  ]
17
17
  # Change this with the version number bump.
18
- version = "1.0.73"
18
+ version = "1.0.76"
19
19
 
20
20
  [tool.setuptools]
21
21
  package-dir = {"" = "src"}
@@ -126,19 +126,18 @@ def _async_diff_stream_from_running_process(
126
126
  except UnicodeDecodeError:
127
127
  print("UnicodeDecodeError")
128
128
  continue
129
- output.put(None)
130
129
  except KeyboardInterrupt:
131
130
  import _thread
132
131
 
133
132
  print("KeyboardInterrupt")
134
- output.put(None)
135
133
  _thread.interrupt_main()
136
134
  except Exception as e:
137
135
  import _thread
138
136
 
139
137
  print(f"Error: {e}")
140
- output.put(None)
141
138
  _thread.interrupt_main()
139
+ finally:
140
+ output.put(None)
142
141
 
143
142
 
144
143
  def diff_stream_from_running_process(
@@ -66,7 +66,7 @@ class Dir:
66
66
  self_path = Path(self.path.path)
67
67
  other_path = Path(other.path.path)
68
68
  rel_path = self_path.relative_to(other_path)
69
- return str(rel_path)
69
+ return str(rel_path.as_posix())
70
70
 
71
71
  def walk(
72
72
  self, breadth_first: bool, max_depth: int = -1
@@ -349,12 +349,17 @@ class Rclone:
349
349
  dst: str,
350
350
  files: list[str] | Path,
351
351
  check: bool | None = None,
352
+ max_backlog: int | None = None,
352
353
  verbose: bool | None = None,
353
354
  checkers: int | None = None,
354
355
  transfers: int | None = None,
355
356
  low_level_retries: int | None = None,
356
357
  retries: int | None = None,
358
+ retries_sleep: str | None = None,
359
+ metadata: bool | None = None,
360
+ timeout: str | None = None,
357
361
  max_partition_workers: int | None = None,
362
+ multi_thread_streams: int | None = None,
358
363
  other_args: list[str] | None = None,
359
364
  ) -> list[CompletedProcess]:
360
365
  """Copy multiple files from source to destination.
@@ -444,6 +449,19 @@ class Rclone:
444
449
  "--retries",
445
450
  str(retries),
446
451
  ]
452
+ if metadata:
453
+ cmd_list.append("--metadata")
454
+ if retries_sleep is not None:
455
+ cmd_list += ["--retries-sleep", retries_sleep]
456
+ if timeout is not None:
457
+ cmd_list += ["--timeout", timeout]
458
+ if max_backlog is not None:
459
+ cmd_list += ["--max-backlog", str(max_backlog)]
460
+ if multi_thread_streams is not None:
461
+ cmd_list += [
462
+ "--multi-thread-streams",
463
+ str(multi_thread_streams),
464
+ ]
447
465
  if verbose:
448
466
  if not any(["-v" in x for x in other_args]):
449
467
  cmd_list.append("-vvvv")
@@ -13,11 +13,23 @@ from rclone_api.walk import walk_runner_depth_first
13
13
  _MAX_OUT_QUEUE_SIZE = 50
14
14
 
15
15
 
16
+ def _reorder_inplace(data: list, order: Order) -> None:
17
+ if order == Order.NORMAL:
18
+ return
19
+ elif order == Order.REVERSE:
20
+ data.reverse()
21
+ return
22
+ elif order == Order.RANDOM:
23
+ random.shuffle(data)
24
+ return
25
+ else:
26
+ raise ValueError(f"Invalid order: {order}")
27
+
28
+
16
29
  # ONLY Works from src -> dst diffing.
17
30
  def _async_diff_dir_walk_task(
18
31
  src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], order: Order
19
32
  ) -> None:
20
- curr_src, curr_dst = src, dst
21
33
  can_scan_two_deep = max_depth > 1 or max_depth == -1
22
34
  ls_depth = 2 if can_scan_two_deep else 1
23
35
  with ThreadPoolExecutor(max_workers=2) as executor:
@@ -35,27 +47,25 @@ def _async_diff_dir_walk_task(
35
47
  )
36
48
  src_dir_listing: DirListing = t1.result()
37
49
  dst_dir_listing: DirListing = t2.result()
38
- next_depth = max_depth - 1 if max_depth > 0 else max_depth
39
- dst_dirs: list[str] = [d.name for d in dst_dir_listing.dirs]
40
- src_dirs: list[str] = [d.name for d in src_dir_listing.dirs]
50
+ next_depth = max_depth - ls_depth if max_depth > 0 else max_depth
51
+ dst_dirs: list[str] = [d.relative_to(src) for d in dst_dir_listing.dirs]
52
+ src_dirs: list[str] = [d.relative_to(dst) for d in src_dir_listing.dirs]
41
53
  dst_files_set: set[str] = set(dst_dirs)
42
54
  matching_dirs: list[str] = []
43
- if order == Order.REVERSE:
44
- src_dirs.reverse()
45
- dst_dirs.reverse()
46
- elif order == Order.RANDOM:
47
- random.shuffle(src_dirs)
48
- random.shuffle(dst_dirs)
49
- for file in src_dirs:
50
- if file not in dst_files_set:
55
+ _reorder_inplace(src_dirs, order)
56
+ _reorder_inplace(dst_dirs, order)
57
+ for i, src_dir in enumerate(src_dirs):
58
+ src_dir_dir = src / src_dir
59
+ if src_dir not in dst_files_set:
51
60
  queue_dir_listing: Queue[DirListing | None] = Queue()
52
61
  if next_depth > 0 or next_depth == -1:
53
62
  walk_runner_depth_first(
54
- dir=curr_src,
63
+ dir=src_dir_dir,
55
64
  out_queue=queue_dir_listing,
56
65
  order=order,
57
66
  max_depth=next_depth,
58
67
  )
68
+ out_queue.put(src)
59
69
  while dirlisting := queue_dir_listing.get():
60
70
  if dirlisting is None:
61
71
  break
@@ -63,13 +73,13 @@ def _async_diff_dir_walk_task(
63
73
  for d in dirlisting.dirs:
64
74
  out_queue.put(d)
65
75
  else:
66
- matching_dirs.append(file)
76
+ matching_dirs.append(src_dir)
67
77
 
68
78
  for matching_dir in matching_dirs:
69
79
  # print(f"matching dir: {matching_dir}")
70
80
  if next_depth > 0 or next_depth == -1:
71
- src_next = curr_src / matching_dir
72
- dst_next = curr_dst / matching_dir
81
+ src_next = src / matching_dir
82
+ dst_next = dst / matching_dir
73
83
  _async_diff_dir_walk_task(
74
84
  src=src_next,
75
85
  dst=dst_next,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.73
3
+ Version: 1.0.76
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
@@ -83,7 +83,7 @@ class RcloneDiffTests(unittest.TestCase):
83
83
  item.type, DiffType.MISSING_ON_DST
84
84
  ) # should be equal because same repo
85
85
  all.append(item)
86
- self.assertGreater(len(all), 0)
86
+ self.assertEqual(len(all), 47)
87
87
  msg = "\n".join([str(item) for item in all])
88
88
  print(msg)
89
89
 
@@ -98,7 +98,7 @@ class RcloneDiffTests(unittest.TestCase):
98
98
  ):
99
99
  self.assertEqual(item.type, DiffType.MISSING_ON_SRC)
100
100
  all.append(item)
101
- self.assertGreater(len(all), 0)
101
+ self.assertEqual(len(all), 47)
102
102
  msg = "\n".join([str(item) for item in all])
103
103
  print(msg)
104
104
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes