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

Sign up to get free protection for your applications and to get access to all the features.
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,,