rclone-api 1.0.70__py2.py3-none-any.whl → 1.0.72__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rclone_api/__init__.py CHANGED
@@ -1,14 +1,15 @@
1
1
  from .completed_process import CompletedProcess
2
2
  from .config import Config
3
- from .diff import DiffItem, DiffType
3
+ from .diff import DiffItem, DiffOption, DiffType
4
4
  from .dir import Dir
5
5
  from .dir_listing import DirListing
6
6
  from .file import File
7
7
  from .filelist import FileList
8
8
  from .process import Process
9
- from .rclone import DiffOption, ListingOption, Rclone, rclone_verbose
9
+ from .rclone import Rclone, rclone_verbose
10
10
  from .remote import Remote
11
11
  from .rpath import RPath
12
+ from .types import ListingOption, Order
12
13
 
13
14
  __all__ = [
14
15
  "Rclone",
@@ -26,4 +27,6 @@ __all__ = [
26
27
  "CompletedProcess",
27
28
  "DiffOption",
28
29
  "ListingOption",
30
+ "Order",
31
+ "ListingOption",
29
32
  ]
rclone_api/dir.py CHANGED
@@ -5,7 +5,7 @@ from typing import Generator
5
5
  from rclone_api.dir_listing import DirListing
6
6
  from rclone_api.remote import Remote
7
7
  from rclone_api.rpath import RPath
8
- from rclone_api.types import ListingOption
8
+ from rclone_api.types import ListingOption, Order
9
9
 
10
10
 
11
11
  class Dir:
@@ -47,7 +47,7 @@ class Dir:
47
47
  self,
48
48
  max_depth: int | None = None,
49
49
  glob: str | None = None,
50
- reverse: bool = False,
50
+ order: Order = Order.NORMAL,
51
51
  listing_option: ListingOption = ListingOption.ALL,
52
52
  ) -> DirListing:
53
53
  """List files and directories in the given path."""
@@ -57,7 +57,7 @@ class Dir:
57
57
  dir,
58
58
  max_depth=max_depth,
59
59
  glob=glob,
60
- reverse=reverse,
60
+ order=order,
61
61
  listing_option=listing_option,
62
62
  )
63
63
 
rclone_api/rclone.py CHANGED
@@ -3,6 +3,7 @@ Unit test file.
3
3
  """
4
4
 
5
5
  import os
6
+ import random
6
7
  import subprocess
7
8
  import time
8
9
  import warnings
@@ -25,7 +26,7 @@ from rclone_api.group_files import group_files
25
26
  from rclone_api.process import Process
26
27
  from rclone_api.remote import Remote
27
28
  from rclone_api.rpath import RPath
28
- from rclone_api.types import ListingOption, ModTimeStrategy
29
+ from rclone_api.types import ListingOption, ModTimeStrategy, Order
29
30
  from rclone_api.util import (
30
31
  get_check,
31
32
  get_rclone_exe,
@@ -118,7 +119,7 @@ class Rclone:
118
119
  path: Dir | Remote | str,
119
120
  max_depth: int | None = None,
120
121
  glob: str | None = None,
121
- reverse: bool = False,
122
+ order: Order = Order.NORMAL,
122
123
  listing_option: ListingOption = ListingOption.ALL,
123
124
  ) -> DirListing:
124
125
  """List files in the given path.
@@ -164,8 +165,10 @@ class Rclone:
164
165
  if glob is not None:
165
166
  paths = [p for p in paths if fnmatch(p.path, glob)]
166
167
 
167
- if reverse:
168
+ if order == Order.REVERSE:
168
169
  paths.reverse()
170
+ elif order == Order.RANDOM:
171
+ random.shuffle(paths)
169
172
  return DirListing(paths)
170
173
 
171
174
  def listremotes(self) -> list[Remote]:
@@ -242,7 +245,7 @@ class Rclone:
242
245
  path: Dir | Remote | str,
243
246
  max_depth: int = -1,
244
247
  breadth_first: bool = True,
245
- reverse: bool = False,
248
+ order: Order = Order.NORMAL,
246
249
  ) -> Generator[DirListing, None, None]:
247
250
  """Walk through the given path recursively.
248
251
 
@@ -277,15 +280,15 @@ class Rclone:
277
280
  assert f"Invalid type for path: {type(path)}"
278
281
 
279
282
  yield from walk(
280
- dir_obj, max_depth=max_depth, breadth_first=breadth_first, reverse=reverse
283
+ dir_obj, max_depth=max_depth, breadth_first=breadth_first, order=order
281
284
  )
282
285
 
283
- def diff_walk(
286
+ def scan_missing_folders(
284
287
  self,
285
288
  src: Dir | Remote | str,
286
289
  dst: Dir | Remote | str,
287
290
  max_depth: int = -1,
288
- reverse: bool = False,
291
+ order: Order = Order.NORMAL,
289
292
  ) -> Generator[Dir, None, None]:
290
293
  """Walk through the given path recursively.
291
294
 
@@ -299,12 +302,12 @@ class Rclone:
299
302
  Yields:
300
303
  DirListing: Directory listing for each directory encountered
301
304
  """
302
- from rclone_api.diff_walk import diff_walk
305
+ from rclone_api.scan_missing_folders import scan_missing_folders
303
306
 
304
307
  src_dir = Dir(to_path(src, self))
305
308
  dst_dir = Dir(to_path(dst, self))
306
- yield from diff_walk(
307
- src=src_dir, dst=dst_dir, max_depth=max_depth, reverse=reverse
309
+ yield from scan_missing_folders(
310
+ src=src_dir, dst=dst_dir, max_depth=max_depth, order=order
308
311
  )
309
312
 
310
313
  def cleanup(
@@ -426,10 +429,6 @@ class Rclone:
426
429
  chunk = files_fqdn[i : i + chunk_size]
427
430
  files_str = "\n".join(chunk)
428
431
  print(f"{files_str}")
429
- # files_str = "\n".join(files_fqdn)
430
- # print(f"Copying {nfiles} files: \n{files_str}")
431
-
432
- # print(include_files_txt)
433
432
  cmd_list: list[str] = [
434
433
  "copy",
435
434
  src_path,
@@ -1,3 +1,4 @@
1
+ import random
1
2
  import time
2
3
  from concurrent.futures import ThreadPoolExecutor
3
4
  from queue import Empty, Queue
@@ -6,7 +7,7 @@ from typing import Generator
6
7
 
7
8
  from rclone_api import Dir
8
9
  from rclone_api.dir_listing import DirListing
9
- from rclone_api.types import ListingOption
10
+ from rclone_api.types import ListingOption, Order
10
11
  from rclone_api.walk import walk_runner_depth_first
11
12
 
12
13
  _MAX_OUT_QUEUE_SIZE = 50
@@ -14,34 +15,37 @@ _MAX_OUT_QUEUE_SIZE = 50
14
15
 
15
16
  # ONLY Works from src -> dst diffing.
16
17
  def _async_diff_dir_walk_task(
17
- src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], reverse
18
+ src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], order: Order
18
19
  ) -> None:
19
20
  curr_src, curr_dst = src, dst
20
21
  with ThreadPoolExecutor(max_workers=2) as executor:
21
- # src_dir_listing = src.ls(listing_option=ListingOption.DIRS_ONLY)
22
- # dst_dir_listing = dst.ls(listing_option=ListingOption.DIRS_ONLY)
23
22
  t1 = executor.submit(
24
- src.ls, listing_option=ListingOption.DIRS_ONLY, reverse=reverse
23
+ src.ls, listing_option=ListingOption.DIRS_ONLY, order=order
25
24
  )
26
25
  t2 = executor.submit(
27
- dst.ls, listing_option=ListingOption.DIRS_ONLY, reverse=reverse
26
+ dst.ls, listing_option=ListingOption.DIRS_ONLY, order=order
28
27
  )
29
28
  src_dir_listing: DirListing = t1.result()
30
29
  dst_dir_listing: DirListing = t2.result()
31
30
  next_depth = max_depth - 1 if max_depth > 0 else max_depth
32
- dst_files: list[str] = [d.name for d in dst_dir_listing.dirs]
33
- src_files: list[str] = [d.name for d in src_dir_listing.dirs]
34
- dst_files_set: set[str] = set(dst_files)
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]
33
+ dst_files_set: set[str] = set(dst_dirs)
35
34
  matching_dirs: list[str] = []
36
- for file in src_files:
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:
37
42
  if file not in dst_files_set:
38
- # print(f"missing dir on src: {file}")
39
43
  queue_dir_listing: Queue[DirListing | None] = Queue()
40
44
  if next_depth > 0 or next_depth == -1:
41
45
  walk_runner_depth_first(
42
46
  dir=curr_src,
43
47
  out_queue=queue_dir_listing,
44
- reverse=reverse,
48
+ order=order,
45
49
  max_depth=next_depth,
46
50
  )
47
51
  while dirlisting := queue_dir_listing.get():
@@ -63,15 +67,17 @@ def _async_diff_dir_walk_task(
63
67
  dst=dst_next,
64
68
  max_depth=next_depth,
65
69
  out_queue=out_queue,
66
- reverse=reverse,
70
+ order=order,
67
71
  )
68
72
 
69
73
 
70
74
  def async_diff_dir_walk_task(
71
- src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], reverse=False
75
+ src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], order: Order
72
76
  ) -> None:
73
77
  try:
74
- _async_diff_dir_walk_task(src, dst, max_depth, out_queue, reverse)
78
+ _async_diff_dir_walk_task(
79
+ src=src, dst=dst, max_depth=max_depth, out_queue=out_queue, order=order
80
+ )
75
81
  except Exception:
76
82
  import _thread
77
83
 
@@ -81,11 +87,11 @@ def async_diff_dir_walk_task(
81
87
  out_queue.put(None)
82
88
 
83
89
 
84
- def diff_walk(
90
+ def scan_missing_folders(
85
91
  src: Dir,
86
92
  dst: Dir,
87
93
  max_depth: int = -1,
88
- reverse: bool = False,
94
+ order: Order = Order.NORMAL,
89
95
  ) -> Generator[Dir, None, None]:
90
96
  """Walk through the given directory recursively.
91
97
 
@@ -101,7 +107,13 @@ def diff_walk(
101
107
  out_queue: Queue[Dir | None] = Queue(maxsize=_MAX_OUT_QUEUE_SIZE)
102
108
 
103
109
  def task() -> None:
104
- async_diff_dir_walk_task(src, dst, max_depth, out_queue, reverse=reverse)
110
+ async_diff_dir_walk_task(
111
+ src=src,
112
+ dst=dst,
113
+ max_depth=max_depth,
114
+ out_queue=out_queue,
115
+ order=order,
116
+ )
105
117
 
106
118
  worker = Thread(
107
119
  target=task,
@@ -111,10 +123,10 @@ def diff_walk(
111
123
 
112
124
  while True:
113
125
  try:
114
- dirlisting = out_queue.get_nowait()
115
- if dirlisting is None:
126
+ dir = out_queue.get_nowait()
127
+ if dir is None:
116
128
  break
117
- yield dirlisting
129
+ yield dir
118
130
  except Empty:
119
131
  time.sleep(0.1)
120
132
 
rclone_api/types.py CHANGED
@@ -10,3 +10,9 @@ class ListingOption(Enum):
10
10
  DIRS_ONLY = "dirs-only"
11
11
  FILES_ONLY = "files-only"
12
12
  ALL = "all"
13
+
14
+
15
+ class Order(Enum):
16
+ NORMAL = "normal"
17
+ REVERSE = "reverse"
18
+ RANDOM = "random"
rclone_api/walk.py CHANGED
@@ -1,3 +1,4 @@
1
+ import random
1
2
  from queue import Queue
2
3
  from threading import Thread
3
4
  from typing import Generator
@@ -5,6 +6,7 @@ from typing import Generator
5
6
  from rclone_api import Dir
6
7
  from rclone_api.dir_listing import DirListing
7
8
  from rclone_api.remote import Remote
9
+ from rclone_api.types import Order
8
10
 
9
11
  _MAX_OUT_QUEUE_SIZE = 50
10
12
 
@@ -13,14 +15,14 @@ def walk_runner_breadth_first(
13
15
  dir: Dir,
14
16
  max_depth: int,
15
17
  out_queue: Queue[DirListing | None],
16
- reverse: bool = False,
18
+ order: Order = Order.NORMAL,
17
19
  ) -> None:
18
20
  queue: Queue[Dir] = Queue()
19
21
  queue.put(dir)
20
22
  try:
21
23
  while not queue.empty():
22
24
  current_dir = queue.get()
23
- dirlisting = current_dir.ls(max_depth=0, reverse=reverse)
25
+ dirlisting = current_dir.ls(max_depth=0, order=order)
24
26
  out_queue.put(dirlisting)
25
27
  dirs = dirlisting.dirs
26
28
 
@@ -41,22 +43,26 @@ def walk_runner_breadth_first(
41
43
 
42
44
 
43
45
  def walk_runner_depth_first(
44
- dir: Dir, max_depth: int, out_queue: Queue[DirListing | None], reverse=False
46
+ dir: Dir,
47
+ max_depth: int,
48
+ out_queue: Queue[DirListing | None],
49
+ order: Order = Order.NORMAL,
45
50
  ) -> None:
46
51
  try:
47
52
  stack = [(dir, max_depth)]
48
53
  while stack:
49
54
  current_dir, depth = stack.pop()
50
55
  dirlisting = current_dir.ls()
51
- if reverse:
56
+ if order == Order.REVERSE:
52
57
  dirlisting.dirs.reverse()
58
+ if order == Order.RANDOM:
59
+
60
+ random.shuffle(dirlisting.dirs)
53
61
  if depth != 0:
54
62
  for subdir in dirlisting.dirs: # Process deeper directories first
55
63
  # stack.append((child, depth - 1 if depth > 0 else depth))
56
64
  next_depth = depth - 1 if depth > 0 else depth
57
- walk_runner_depth_first(
58
- subdir, next_depth, out_queue, reverse=reverse
59
- )
65
+ walk_runner_depth_first(subdir, next_depth, out_queue, order=order)
60
66
  out_queue.put(dirlisting)
61
67
  out_queue.put(None)
62
68
  except KeyboardInterrupt:
@@ -70,7 +76,7 @@ def walk(
70
76
  dir: Dir | Remote,
71
77
  breadth_first: bool,
72
78
  max_depth: int = -1,
73
- reverse: bool = False,
79
+ order: Order = Order.NORMAL,
74
80
  ) -> Generator[DirListing, None, None]:
75
81
  """Walk through the given directory recursively.
76
82
 
@@ -89,9 +95,9 @@ def walk(
89
95
 
90
96
  def _task() -> None:
91
97
  if breadth_first:
92
- walk_runner_breadth_first(dir, max_depth, out_queue, reverse)
98
+ walk_runner_breadth_first(dir, max_depth, out_queue, order)
93
99
  else:
94
- walk_runner_depth_first(dir, max_depth, out_queue, reverse)
100
+ walk_runner_depth_first(dir, max_depth, out_queue, order)
95
101
 
96
102
  # Start worker thread
97
103
  worker = Thread(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.70
3
+ Version: 1.0.72
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
@@ -1,29 +1,29 @@
1
- rclone_api/__init__.py,sha256=B9q_4JU5Myh0DN-wqr_IgF5hZeAvszrGcqs2x-3hq-Q,633
1
+ rclone_api/__init__.py,sha256=kJUk9KAxQ2AEms9lM5yqw-dqlabarhU69b2FAxJVBlY,692
2
2
  rclone_api/cli.py,sha256=dibfAZIh0kXWsBbfp3onKLjyZXo54mTzDjUdzJlDlWo,231
3
3
  rclone_api/completed_process.py,sha256=Pp-hXnLgej0IGO5ee9Fmx64dGzIofbQFEUyXdFCvO54,1371
4
4
  rclone_api/config.py,sha256=tP6cU9DnCCEIRc_KP9HPur1jFLLg2QGFSxNwFm6_MVw,118
5
5
  rclone_api/convert.py,sha256=Mx9Qo7zhkOedJd8LdhPvNGHp8znJzOk4f_2KWnoGc78,1012
6
6
  rclone_api/deprecated.py,sha256=qWKpnZdYcBK7YQZKuVoWWXDwi-uqiAtbjgPcci_efow,590
7
7
  rclone_api/diff.py,sha256=ggdDLUZxa13jMcPzKBcwAElmPCNWMOSR89D4yhpO74M,5264
8
- rclone_api/diff_walk.py,sha256=fnCjzenKBBocu6sEd9CDEcwNqCUYwz3rZsxUuKNaYEg,4049
9
- rclone_api/dir.py,sha256=BuXPd-bAvZund8k7mXjvx_UylsPFwbWq2zaUdflTX04,3520
8
+ rclone_api/dir.py,sha256=hL0i4zrNUbpvFWI3TvKyOyanJ2okcb1lz4r2kxlvSi4,3529
10
9
  rclone_api/dir_listing.py,sha256=9Qqf2SUswrOEkyqmaH23V51I18X6ePiXb9B1vUwRF5o,1571
11
10
  rclone_api/exec.py,sha256=1ovvaMXDEfLiT7BrYZyE85u_yFhEUwUNW3jPOzqknR8,1023
12
11
  rclone_api/file.py,sha256=YtR5Y6c0YfXTS-sReOy2UgiSnafcAeO6b2hnbojBQD4,1423
13
12
  rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
14
13
  rclone_api/group_files.py,sha256=kOHh6ysFDkxjldSwvW6KqmiADUC1yFCdrZRY57TvbGY,5328
15
14
  rclone_api/process.py,sha256=RrMfTe0bndmJ6gBK67ioqNvCstJ8aTC8RlGX1XBLlcw,4191
16
- rclone_api/rclone.py,sha256=nN1bqUmiopCKP6VNG4XpSfBfWx4EuAIyxB9NevYp-OA,28854
15
+ rclone_api/rclone.py,sha256=kIamoje3fUaWboMdF_d_a4WVaSa8BfK6zDFY8U6pNbs,28820
17
16
  rclone_api/remote.py,sha256=c9hlRKBCg1BFB9MCINaQIoCg10qyAkeqiS4brl8ce-8,343
18
17
  rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
19
- rclone_api/types.py,sha256=VXA-56va2S41onAWM_UmhHlG4qeyMUEF5dsVFyfLlH8,232
18
+ rclone_api/scan_missing_folders.py,sha256=ke2AVIdX-MiuJUi7poJBzP8GxjzzMhCsr1Mxbg0EIu4,4217
19
+ rclone_api/types.py,sha256=DcbNw1R6j2f_1zHrhqEJcpCR-8kJfFJawMY0AmPsCnM,321
20
20
  rclone_api/util.py,sha256=_cvmHcJPRl2yXw4zgZiop3z-riA_8Ek6S5NDPw8cqSY,4198
21
- rclone_api/walk.py,sha256=ndWV7WBVQLbpZu3HuJrAe1cXcmQVjT9_YPsbat158bQ,3231
21
+ rclone_api/walk.py,sha256=-54NVE8EJcCstwDoaC_UtHm73R2HrZwVwQmsnv55xNU,3369
22
22
  rclone_api/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
23
23
  rclone_api/cmd/list_files.py,sha256=x8FHODEilwKqwdiU1jdkeJbLwOqUkUQuDWPo2u_zpf0,741
24
- rclone_api-1.0.70.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
25
- rclone_api-1.0.70.dist-info/METADATA,sha256=73129SIcLoTZ3R35zB0vuZZ65SC0RBttGk1LtPARAx8,4489
26
- rclone_api-1.0.70.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
27
- rclone_api-1.0.70.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
28
- rclone_api-1.0.70.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
29
- rclone_api-1.0.70.dist-info/RECORD,,
24
+ rclone_api-1.0.72.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
25
+ rclone_api-1.0.72.dist-info/METADATA,sha256=xzlW0jfYuqOPGSCI9k8MxNvp4BpI0Duojacxq_l-C-M,4489
26
+ rclone_api-1.0.72.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
27
+ rclone_api-1.0.72.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
28
+ rclone_api-1.0.72.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
29
+ rclone_api-1.0.72.dist-info/RECORD,,