rclone-api 1.0.58__py2.py3-none-any.whl → 1.0.60__py2.py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
rclone_api/diff.py CHANGED
@@ -1,3 +1,4 @@
1
+ import warnings
1
2
  from dataclasses import dataclass
2
3
  from enum import Enum
3
4
  from queue import Queue
@@ -104,9 +105,9 @@ def _async_diff_stream_from_running_process(
104
105
  _thread.interrupt_main()
105
106
  if count == 0 and check:
106
107
  first_lines_str = "\n".join(first_few_lines)
107
- raise ValueError(
108
- f"No output from rclone check, first few lines: {first_lines_str}"
109
- )
108
+ warning_msg = f"No output from rclone check, first few lines: {first_lines_str}"
109
+ warnings.warn(warning_msg)
110
+ raise ValueError(warning_msg)
110
111
 
111
112
 
112
113
  def diff_stream_from_running_process(
rclone_api/dir.py CHANGED
@@ -41,11 +41,11 @@ class Dir:
41
41
  # self.path.set_rclone(self.path.remote.rclone)
42
42
  assert self.path.rclone is not None
43
43
 
44
- def ls(self, max_depth: int = 0) -> DirListing:
44
+ def ls(self, max_depth: int = 0, reverse: bool = False) -> DirListing:
45
45
  """List files and directories in the given path."""
46
46
  assert self.path.rclone is not None
47
47
  dir = Dir(self.path)
48
- return self.path.rclone.ls(dir, max_depth=max_depth)
48
+ return self.path.rclone.ls(dir, max_depth=max_depth, reverse=reverse)
49
49
 
50
50
  def walk(
51
51
  self, breadth_first: bool, max_depth: int = -1
rclone_api/rclone.py CHANGED
@@ -27,6 +27,7 @@ from rclone_api.process import Process
27
27
  from rclone_api.remote import Remote
28
28
  from rclone_api.rpath import RPath
29
29
  from rclone_api.util import (
30
+ get_check,
30
31
  get_rclone_exe,
31
32
  get_verbose,
32
33
  to_path,
@@ -56,7 +57,7 @@ class Rclone:
56
57
  self._exec = RcloneExec(rclone_conf, get_rclone_exe(rclone_exe))
57
58
 
58
59
  def _run(
59
- self, cmd: list[str], check: bool = True, capture: bool | None = None
60
+ self, cmd: list[str], check: bool = False, capture: bool | None = None
60
61
  ) -> subprocess.CompletedProcess:
61
62
  return self._exec.execute(cmd, check=check, capture=capture)
62
63
 
@@ -72,7 +73,7 @@ class Rclone:
72
73
 
73
74
  def launch_server(
74
75
  self,
75
- addr: str | None = None,
76
+ addr: str,
76
77
  user: str | None = None,
77
78
  password: str | None = None,
78
79
  other_args: list[str] | None = None,
@@ -122,6 +123,7 @@ class Rclone:
122
123
  path: Dir | Remote | str,
123
124
  max_depth: int | None = None,
124
125
  glob: str | None = None,
126
+ reverse: bool = False,
125
127
  ) -> DirListing:
126
128
  """List files in the given path.
127
129
 
@@ -162,6 +164,9 @@ class Rclone:
162
164
  # do we have a glob pattern?
163
165
  if glob is not None:
164
166
  paths = [p for p in paths if fnmatch(p.path, glob)]
167
+
168
+ if reverse:
169
+ paths.reverse()
165
170
  return DirListing(paths)
166
171
 
167
172
  def listremotes(self) -> list[Remote]:
@@ -175,9 +180,21 @@ class Rclone:
175
180
  out = [Remote(name=t, rclone=self) for t in tmp]
176
181
  return out
177
182
 
178
- def diff(self, src: str, dst: str) -> Generator[DiffItem, None, None]:
183
+ def diff(
184
+ self,
185
+ src: str,
186
+ dst: str,
187
+ min_size: (
188
+ str | None
189
+ ) = None, # e. g. "1MB" - see rclone documentation: https://rclone.org/commands/rclone_check/
190
+ max_size: (
191
+ str | None
192
+ ) = None, # e. g. "1GB" - see rclone documentation: https://rclone.org/commands/rclone_check/
193
+ other_args: list[str] | None = None,
194
+ ) -> Generator[DiffItem, None, None]:
179
195
  """Be extra careful with the src and dst values. If you are off by one
180
196
  parent directory, you will get a huge amount of false diffs."""
197
+ other_args = other_args or []
181
198
  cmd = [
182
199
  "check",
183
200
  src,
@@ -189,6 +206,12 @@ class Rclone:
189
206
  "--combined",
190
207
  "-",
191
208
  ]
209
+ if min_size:
210
+ cmd += ["--min-size", min_size]
211
+ if max_size:
212
+ cmd += ["--max-size", max_size]
213
+ if other_args:
214
+ cmd += other_args
192
215
  proc = self._launch_process(cmd, capture=True)
193
216
  item: DiffItem
194
217
  for item in diff_stream_from_running_process(proc, src_slug=src, dst_slug=dst):
@@ -197,7 +220,11 @@ class Rclone:
197
220
  yield item
198
221
 
199
222
  def walk(
200
- self, path: Dir | Remote | str, max_depth: int = -1, breadth_first: bool = True
223
+ self,
224
+ path: Dir | Remote | str,
225
+ max_depth: int = -1,
226
+ breadth_first: bool = True,
227
+ reverse: bool = False,
201
228
  ) -> Generator[DirListing, None, None]:
202
229
  """Walk through the given path recursively.
203
230
 
@@ -231,7 +258,9 @@ class Rclone:
231
258
  dir_obj = Dir(path) # shut up pyright
232
259
  assert f"Invalid type for path: {type(path)}"
233
260
 
234
- yield from walk(dir_obj, max_depth=max_depth, breadth_first=breadth_first)
261
+ yield from walk(
262
+ dir_obj, max_depth=max_depth, breadth_first=breadth_first, reverse=reverse
263
+ )
235
264
 
236
265
  def cleanup(
237
266
  self, path: str, other_args: list[str] | None = None
@@ -248,7 +277,7 @@ class Rclone:
248
277
  self,
249
278
  src: File | str,
250
279
  dst: File | str,
251
- check=True,
280
+ check: bool | None = None,
252
281
  other_args: list[str] | None = None,
253
282
  ) -> None:
254
283
  """Copy multiple files from source to destination.
@@ -258,6 +287,7 @@ class Rclone:
258
287
  Args:
259
288
  payload: Dictionary of source and destination file paths
260
289
  """
290
+ check = get_check(check)
261
291
  src = src if isinstance(src, str) else str(src.path)
262
292
  dst = dst if isinstance(dst, str) else str(dst.path)
263
293
  cmd_list: list[str] = ["copyto", src, dst]
@@ -270,7 +300,7 @@ class Rclone:
270
300
  src: str,
271
301
  dst: str,
272
302
  files: list[str],
273
- check=True,
303
+ check: bool | None = None,
274
304
  verbose: bool | None = None,
275
305
  checkers: int | None = None,
276
306
  transfers: int | None = None,
@@ -284,6 +314,7 @@ class Rclone:
284
314
  Args:
285
315
  payload: Dictionary of source and destination file paths
286
316
  """
317
+ check = get_check(check)
287
318
  max_partition_workers = max_partition_workers or 1
288
319
  low_level_retries = low_level_retries or 10
289
320
  retries = retries or 3
@@ -398,13 +429,14 @@ class Rclone:
398
429
  def delete_files(
399
430
  self,
400
431
  files: str | File | list[str] | list[File],
401
- check=True,
432
+ check: bool | None = None,
402
433
  rmdirs=False,
403
434
  verbose: bool | None = None,
404
435
  max_partition_workers: int | None = None,
405
436
  other_args: list[str] | None = None,
406
437
  ) -> CompletedProcess:
407
438
  """Delete a directory"""
439
+ check = get_check(check)
408
440
  verbose = get_verbose(verbose)
409
441
  payload: list[str] = convert_to_filestr_list(files)
410
442
  if len(payload) == 0:
@@ -494,7 +526,7 @@ class Rclone:
494
526
  dst = convert_to_str(dst)
495
527
  cmd_list: list[str] = ["check", str(src), str(dst)]
496
528
  try:
497
- self._run(cmd_list)
529
+ self._run(cmd_list, check=True)
498
530
  return True
499
531
  except subprocess.CalledProcessError:
500
532
  return False
rclone_api/util.py CHANGED
@@ -63,6 +63,13 @@ def get_verbose(verbose: bool | None) -> bool:
63
63
  return bool(int(os.getenv("RCLONE_API_VERBOSE", "0")))
64
64
 
65
65
 
66
+ def get_check(check: bool | None) -> bool:
67
+ if check is not None:
68
+ return check
69
+ # get it from the environment
70
+ return bool(int(os.getenv("RCLONE_API_CHECK", "1")))
71
+
72
+
66
73
  def get_rclone_exe(rclone_exe: Path | None) -> Path:
67
74
  if rclone_exe is None:
68
75
 
rclone_api/walk.py CHANGED
@@ -10,14 +10,17 @@ _MAX_OUT_QUEUE_SIZE = 50
10
10
 
11
11
 
12
12
  def _walk_runner_breadth_first(
13
- dir: Dir, max_depth: int, out_queue: Queue[DirListing | None]
13
+ dir: Dir,
14
+ max_depth: int,
15
+ out_queue: Queue[DirListing | None],
16
+ reverse: bool = False,
14
17
  ) -> None:
15
18
  queue: Queue[Dir] = Queue()
16
19
  queue.put(dir)
17
20
  try:
18
21
  while not queue.empty():
19
22
  current_dir = queue.get()
20
- dirlisting = current_dir.ls()
23
+ dirlisting = current_dir.ls(max_depth=0, reverse=reverse)
21
24
  out_queue.put(dirlisting)
22
25
  dirs = dirlisting.dirs
23
26
 
@@ -38,20 +41,22 @@ def _walk_runner_breadth_first(
38
41
 
39
42
 
40
43
  def _walk_runner_depth_first(
41
- dir: Dir, max_depth: int, out_queue: Queue[DirListing | None]
44
+ dir: Dir, max_depth: int, out_queue: Queue[DirListing | None], reverse=False
42
45
  ) -> None:
43
46
  try:
44
47
  stack = [(dir, max_depth)]
45
48
  while stack:
46
49
  current_dir, depth = stack.pop()
47
50
  dirlisting = current_dir.ls()
51
+ if reverse:
52
+ dirlisting.dirs.reverse()
48
53
  if depth != 0:
49
- for subdir in reversed(
50
- dirlisting.dirs
51
- ): # Process deeper directories first
54
+ for subdir in dirlisting.dirs: # Process deeper directories first
52
55
  # stack.append((child, depth - 1 if depth > 0 else depth))
53
56
  next_depth = depth - 1 if depth > 0 else depth
54
- _walk_runner_depth_first(subdir, next_depth, out_queue)
57
+ _walk_runner_depth_first(
58
+ subdir, next_depth, out_queue, reverse=reverse
59
+ )
55
60
  out_queue.put(dirlisting)
56
61
  out_queue.put(None)
57
62
  except KeyboardInterrupt:
@@ -65,6 +70,7 @@ def walk(
65
70
  dir: Dir | Remote,
66
71
  breadth_first: bool,
67
72
  max_depth: int = -1,
73
+ reverse: bool = False,
68
74
  ) -> Generator[DirListing, None, None]:
69
75
  """Walk through the given directory recursively.
70
76
 
@@ -88,7 +94,7 @@ def walk(
88
94
  # Start worker thread
89
95
  worker = Thread(
90
96
  target=strategy,
91
- args=(dir, max_depth, out_queue),
97
+ args=(dir, max_depth, out_queue, reverse),
92
98
  daemon=True,
93
99
  )
94
100
  worker.start()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.58
3
+ Version: 1.0.60
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
@@ -4,24 +4,24 @@ rclone_api/completed_process.py,sha256=Pp-hXnLgej0IGO5ee9Fmx64dGzIofbQFEUyXdFCvO
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
- rclone_api/diff.py,sha256=ELUQD1Mv8qaoAav13sEE-iKynFph70rQHj7-a4Z1pyo,4137
8
- rclone_api/dir.py,sha256=vV-bcI2ESijmwF5rPID5WO2K7soAfZa35wv4KRh_GIo,2154
7
+ rclone_api/diff.py,sha256=36sXtAFDPoCVUN7E46OB2FywkaFauffsg2e9VsUMGhU,4200
8
+ rclone_api/dir.py,sha256=2-PFaDpjEs28z82DQ-TyaCgrm_OgpwlkwfTnx1-Wwpk,2194
9
9
  rclone_api/dir_listing.py,sha256=9Qqf2SUswrOEkyqmaH23V51I18X6ePiXb9B1vUwRF5o,1571
10
10
  rclone_api/exec.py,sha256=1ovvaMXDEfLiT7BrYZyE85u_yFhEUwUNW3jPOzqknR8,1023
11
11
  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=D9Qdibcqff0Vry7hk4f_-xxrB8JoZHJq-XYS1NITDzM,25466
15
+ rclone_api/rclone.py,sha256=XyA9_EOxdOMFv70KvMYjjjGz6ceBEO8xtZ2bKDTftRg,26388
16
16
  rclone_api/remote.py,sha256=c9hlRKBCg1BFB9MCINaQIoCg10qyAkeqiS4brl8ce-8,343
17
17
  rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
18
- rclone_api/util.py,sha256=IWNOOcPE0xdKvehzXQ9okIppGDBYWJPIfdbUME8BFVM,4015
19
- rclone_api/walk.py,sha256=kca0t1GAnF6FLclN01G8NG__Qe-ggodLtAbQSHyVPng,2968
18
+ rclone_api/util.py,sha256=_cvmHcJPRl2yXw4zgZiop3z-riA_8Ek6S5NDPw8cqSY,4198
19
+ rclone_api/walk.py,sha256=UaNOE3ICd8k5ouSFZvkVEH4r2GnnrD9TxfwkFcQnayo,3170
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.58.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
23
- rclone_api-1.0.58.dist-info/METADATA,sha256=UdbK32ilHGvATZ5ssYirx7I_2B0q19rJKQhEZnDC3yk,4489
24
- rclone_api-1.0.58.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
25
- rclone_api-1.0.58.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
26
- rclone_api-1.0.58.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
27
- rclone_api-1.0.58.dist-info/RECORD,,
22
+ rclone_api-1.0.60.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
23
+ rclone_api-1.0.60.dist-info/METADATA,sha256=lAw28UzFDwclf7UW2ke9ITEoOxicWHtrYChepRjklk0,4489
24
+ rclone_api-1.0.60.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
25
+ rclone_api-1.0.60.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
26
+ rclone_api-1.0.60.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
27
+ rclone_api-1.0.60.dist-info/RECORD,,