rclone-api 1.0.72__tar.gz → 1.0.75__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.72 → rclone_api-1.0.75}/PKG-INFO +1 -1
  2. {rclone_api-1.0.72 → rclone_api-1.0.75}/pyproject.toml +1 -1
  3. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/diff.py +2 -3
  4. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/dir.py +1 -1
  5. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/rclone.py +12 -0
  6. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/scan_missing_folders.py +36 -18
  7. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api.egg-info/PKG-INFO +1 -1
  8. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_diff.py +2 -2
  9. {rclone_api-1.0.72 → rclone_api-1.0.75}/.aiderignore +0 -0
  10. {rclone_api-1.0.72 → rclone_api-1.0.75}/.github/workflows/lint.yml +0 -0
  11. {rclone_api-1.0.72 → rclone_api-1.0.75}/.github/workflows/push_macos.yml +0 -0
  12. {rclone_api-1.0.72 → rclone_api-1.0.75}/.github/workflows/push_ubuntu.yml +0 -0
  13. {rclone_api-1.0.72 → rclone_api-1.0.75}/.github/workflows/push_win.yml +0 -0
  14. {rclone_api-1.0.72 → rclone_api-1.0.75}/.gitignore +0 -0
  15. {rclone_api-1.0.72 → rclone_api-1.0.75}/.pylintrc +0 -0
  16. {rclone_api-1.0.72 → rclone_api-1.0.75}/.vscode/launch.json +0 -0
  17. {rclone_api-1.0.72 → rclone_api-1.0.75}/.vscode/settings.json +0 -0
  18. {rclone_api-1.0.72 → rclone_api-1.0.75}/.vscode/tasks.json +0 -0
  19. {rclone_api-1.0.72 → rclone_api-1.0.75}/LICENSE +0 -0
  20. {rclone_api-1.0.72 → rclone_api-1.0.75}/MANIFEST.in +0 -0
  21. {rclone_api-1.0.72 → rclone_api-1.0.75}/README.md +0 -0
  22. {rclone_api-1.0.72 → rclone_api-1.0.75}/clean +0 -0
  23. {rclone_api-1.0.72 → rclone_api-1.0.75}/install +0 -0
  24. {rclone_api-1.0.72 → rclone_api-1.0.75}/lint +0 -0
  25. {rclone_api-1.0.72 → rclone_api-1.0.75}/requirements.testing.txt +0 -0
  26. {rclone_api-1.0.72 → rclone_api-1.0.75}/setup.cfg +0 -0
  27. {rclone_api-1.0.72 → rclone_api-1.0.75}/setup.py +0 -0
  28. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/__init__.py +0 -0
  29. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/assets/example.txt +0 -0
  30. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/cli.py +0 -0
  31. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/cmd/list_files.py +0 -0
  32. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/completed_process.py +0 -0
  33. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/config.py +0 -0
  34. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/convert.py +0 -0
  35. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/deprecated.py +0 -0
  36. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/dir_listing.py +0 -0
  37. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/exec.py +0 -0
  38. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/file.py +0 -0
  39. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/filelist.py +0 -0
  40. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/group_files.py +0 -0
  41. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/process.py +0 -0
  42. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/remote.py +0 -0
  43. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/rpath.py +0 -0
  44. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/types.py +0 -0
  45. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/util.py +0 -0
  46. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api/walk.py +0 -0
  47. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api.egg-info/SOURCES.txt +0 -0
  48. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  49. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api.egg-info/entry_points.txt +0 -0
  50. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api.egg-info/requires.txt +0 -0
  51. {rclone_api-1.0.72 → rclone_api-1.0.75}/src/rclone_api.egg-info/top_level.txt +0 -0
  52. {rclone_api-1.0.72 → rclone_api-1.0.75}/test +0 -0
  53. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_cmd_list_files.py +0 -0
  54. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_copy.py +0 -0
  55. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_copy_files.py +0 -0
  56. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_group_files.py +0 -0
  57. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_is_synced.py +0 -0
  58. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_ls.py +0 -0
  59. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_mount.py +0 -0
  60. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_mount_s3.py +0 -0
  61. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_mount_webdav.py +0 -0
  62. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_obscure.py +0 -0
  63. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_remote_control.py +0 -0
  64. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_remotes.py +0 -0
  65. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_scan_missing_folders.py +0 -0
  66. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_serve_webdav.py +0 -0
  67. {rclone_api-1.0.72 → rclone_api-1.0.75}/tests/test_walk.py +0 -0
  68. {rclone_api-1.0.72 → rclone_api-1.0.75}/tox.ini +0 -0
  69. {rclone_api-1.0.72 → rclone_api-1.0.75}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.72
3
+ Version: 1.0.75
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.72"
18
+ version = "1.0.75"
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,11 +349,15 @@ 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,
358
362
  other_args: list[str] | None = None,
359
363
  ) -> list[CompletedProcess]:
@@ -444,6 +448,14 @@ class Rclone:
444
448
  "--retries",
445
449
  str(retries),
446
450
  ]
451
+ if metadata:
452
+ cmd_list.append("--metadata")
453
+ if retries_sleep is not None:
454
+ cmd_list += ["--retries-sleep", retries_sleep]
455
+ if timeout is not None:
456
+ cmd_list += ["--timeout", timeout]
457
+ if max_backlog is not None:
458
+ cmd_list += ["--max-backlog", str(max_backlog)]
447
459
  if verbose:
448
460
  if not any(["-v" in x for x in other_args]):
449
461
  cmd_list.append("-vvvv")
@@ -13,41 +13,59 @@ 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
33
+ can_scan_two_deep = max_depth > 1 or max_depth == -1
34
+ ls_depth = 2 if can_scan_two_deep else 1
21
35
  with ThreadPoolExecutor(max_workers=2) as executor:
22
36
  t1 = executor.submit(
23
- src.ls, listing_option=ListingOption.DIRS_ONLY, order=order
37
+ src.ls,
38
+ listing_option=ListingOption.DIRS_ONLY,
39
+ order=order,
40
+ max_depth=ls_depth,
24
41
  )
25
42
  t2 = executor.submit(
26
- dst.ls, listing_option=ListingOption.DIRS_ONLY, order=order
43
+ dst.ls,
44
+ listing_option=ListingOption.DIRS_ONLY,
45
+ order=order,
46
+ max_depth=ls_depth,
27
47
  )
28
48
  src_dir_listing: DirListing = t1.result()
29
49
  dst_dir_listing: DirListing = t2.result()
30
- next_depth = max_depth - 1 if max_depth > 0 else max_depth
31
- dst_dirs: list[str] = [d.name for d in dst_dir_listing.dirs]
32
- 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]
33
53
  dst_files_set: set[str] = set(dst_dirs)
34
54
  matching_dirs: list[str] = []
35
- if order == Order.REVERSE:
36
- src_dirs.reverse()
37
- dst_dirs.reverse()
38
- elif order == Order.RANDOM:
39
- random.shuffle(src_dirs)
40
- random.shuffle(dst_dirs)
41
- for file in src_dirs:
42
- 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:
43
60
  queue_dir_listing: Queue[DirListing | None] = Queue()
44
61
  if next_depth > 0 or next_depth == -1:
45
62
  walk_runner_depth_first(
46
- dir=curr_src,
63
+ dir=src_dir_dir,
47
64
  out_queue=queue_dir_listing,
48
65
  order=order,
49
66
  max_depth=next_depth,
50
67
  )
68
+ out_queue.put(src)
51
69
  while dirlisting := queue_dir_listing.get():
52
70
  if dirlisting is None:
53
71
  break
@@ -55,13 +73,13 @@ def _async_diff_dir_walk_task(
55
73
  for d in dirlisting.dirs:
56
74
  out_queue.put(d)
57
75
  else:
58
- matching_dirs.append(file)
76
+ matching_dirs.append(src_dir)
59
77
 
60
78
  for matching_dir in matching_dirs:
61
79
  # print(f"matching dir: {matching_dir}")
62
80
  if next_depth > 0 or next_depth == -1:
63
- src_next = curr_src / matching_dir
64
- dst_next = curr_dst / matching_dir
81
+ src_next = src / matching_dir
82
+ dst_next = dst / matching_dir
65
83
  _async_diff_dir_walk_task(
66
84
  src=src_next,
67
85
  dst=dst_next,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.72
3
+ Version: 1.0.75
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