rclone-api 1.0.39__tar.gz → 1.0.41__tar.gz

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rclone-api might be problematic. Click here for more details.

Files changed (62) hide show
  1. {rclone_api-1.0.39 → rclone_api-1.0.41}/PKG-INFO +1 -1
  2. {rclone_api-1.0.39 → rclone_api-1.0.41}/pyproject.toml +1 -1
  3. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/rclone.py +79 -46
  4. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/util.py +6 -9
  5. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api.egg-info/PKG-INFO +1 -1
  6. {rclone_api-1.0.39 → rclone_api-1.0.41}/.aiderignore +0 -0
  7. {rclone_api-1.0.39 → rclone_api-1.0.41}/.github/workflows/lint.yml +0 -0
  8. {rclone_api-1.0.39 → rclone_api-1.0.41}/.github/workflows/push_macos.yml +0 -0
  9. {rclone_api-1.0.39 → rclone_api-1.0.41}/.github/workflows/push_ubuntu.yml +0 -0
  10. {rclone_api-1.0.39 → rclone_api-1.0.41}/.github/workflows/push_win.yml +0 -0
  11. {rclone_api-1.0.39 → rclone_api-1.0.41}/.gitignore +0 -0
  12. {rclone_api-1.0.39 → rclone_api-1.0.41}/.pylintrc +0 -0
  13. {rclone_api-1.0.39 → rclone_api-1.0.41}/.vscode/launch.json +0 -0
  14. {rclone_api-1.0.39 → rclone_api-1.0.41}/.vscode/settings.json +0 -0
  15. {rclone_api-1.0.39 → rclone_api-1.0.41}/.vscode/tasks.json +0 -0
  16. {rclone_api-1.0.39 → rclone_api-1.0.41}/LICENSE +0 -0
  17. {rclone_api-1.0.39 → rclone_api-1.0.41}/MANIFEST.in +0 -0
  18. {rclone_api-1.0.39 → rclone_api-1.0.41}/README.md +0 -0
  19. {rclone_api-1.0.39 → rclone_api-1.0.41}/clean +0 -0
  20. {rclone_api-1.0.39 → rclone_api-1.0.41}/install +0 -0
  21. {rclone_api-1.0.39 → rclone_api-1.0.41}/lint +0 -0
  22. {rclone_api-1.0.39 → rclone_api-1.0.41}/requirements.testing.txt +0 -0
  23. {rclone_api-1.0.39 → rclone_api-1.0.41}/setup.cfg +0 -0
  24. {rclone_api-1.0.39 → rclone_api-1.0.41}/setup.py +0 -0
  25. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/__init__.py +0 -0
  26. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/assets/example.txt +0 -0
  27. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/cli.py +0 -0
  28. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/cmd/list_files.py +0 -0
  29. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/completed_process.py +0 -0
  30. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/config.py +0 -0
  31. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/convert.py +0 -0
  32. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/deprecated.py +0 -0
  33. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/diff.py +0 -0
  34. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/dir.py +0 -0
  35. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/dir_listing.py +0 -0
  36. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/exec.py +0 -0
  37. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/file.py +0 -0
  38. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/filelist.py +0 -0
  39. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/process.py +0 -0
  40. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/remote.py +0 -0
  41. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/rpath.py +0 -0
  42. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api/walk.py +0 -0
  43. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api.egg-info/SOURCES.txt +0 -0
  44. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  45. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api.egg-info/entry_points.txt +0 -0
  46. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api.egg-info/requires.txt +0 -0
  47. {rclone_api-1.0.39 → rclone_api-1.0.41}/src/rclone_api.egg-info/top_level.txt +0 -0
  48. {rclone_api-1.0.39 → rclone_api-1.0.41}/test +0 -0
  49. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_cmd_list_files.py +0 -0
  50. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_copy.py +0 -0
  51. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_diff.py +0 -0
  52. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_is_synced.py +0 -0
  53. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_ls.py +0 -0
  54. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_mount.py +0 -0
  55. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_mount_s3.py +0 -0
  56. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_mount_webdav.py +0 -0
  57. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_obscure.py +0 -0
  58. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_remotes.py +0 -0
  59. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_serve_webdav.py +0 -0
  60. {rclone_api-1.0.39 → rclone_api-1.0.41}/tests/test_walk.py +0 -0
  61. {rclone_api-1.0.39 → rclone_api-1.0.41}/tox.ini +0 -0
  62. {rclone_api-1.0.39 → rclone_api-1.0.41}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.39
3
+ Version: 1.0.41
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.39"
18
+ version = "1.0.41"
19
19
 
20
20
  [tool.setuptools]
21
21
  package-dir = {"" = "src"}
@@ -5,6 +5,7 @@ Unit test file.
5
5
  import subprocess
6
6
  import time
7
7
  import warnings
8
+ from concurrent.futures import Future, ThreadPoolExecutor
8
9
  from enum import Enum
9
10
  from fnmatch import fnmatch
10
11
  from pathlib import Path
@@ -23,9 +24,17 @@ from rclone_api.file import File
23
24
  from rclone_api.process import Process
24
25
  from rclone_api.remote import Remote
25
26
  from rclone_api.rpath import RPath
26
- from rclone_api.util import get_rclone_exe, partition_files, to_path, wait_for_mount
27
+ from rclone_api.util import (
28
+ get_rclone_exe,
29
+ get_verbose,
30
+ partition_files,
31
+ to_path,
32
+ wait_for_mount,
33
+ )
27
34
  from rclone_api.walk import walk
28
35
 
36
+ EXECUTOR = ThreadPoolExecutor(16)
37
+
29
38
 
30
39
  class ModTimeStrategy(Enum):
31
40
  USE_SERVER_MODTIME = "use-server-modtime"
@@ -197,7 +206,7 @@ class Rclone:
197
206
  cmd_list: list[str] = ["copyto", src, dst]
198
207
  self._run(cmd_list)
199
208
 
200
- def copyfiles(self, files: str | File | list[str] | list[File]) -> None:
209
+ def copyfiles(self, files: str | File | list[str] | list[File], check=True) -> None:
201
210
  """Copy multiple files from source to destination.
202
211
 
203
212
  Warning - slow.
@@ -212,28 +221,39 @@ class Rclone:
212
221
  datalists: dict[str, list[str]] = partition_files(payload)
213
222
  out: subprocess.CompletedProcess | None = None
214
223
 
224
+ futures: list[Future] = []
225
+
215
226
  for remote, files in datalists.items():
216
- with TemporaryDirectory() as tmpdir:
217
- include_files_txt = Path(tmpdir) / "include_files.txt"
218
- include_files_txt.write_text("\n".join(files), encoding="utf-8")
219
-
220
- # print(include_files_txt)
221
- cmd_list: list[str] = [
222
- "delete",
223
- remote,
224
- "--files-from",
225
- str(include_files_txt),
226
- "--checkers",
227
- "1000",
228
- "--transfers",
229
- "1000",
230
- ]
231
- out = self._run(cmd_list)
232
- if out.returncode != 0:
233
- print(out)
234
- raise ValueError(f"Error deleting files: {out.stderr}")
235
227
 
236
- assert out is not None
228
+ def _task(files=files) -> subprocess.CompletedProcess:
229
+ with TemporaryDirectory() as tmpdir:
230
+ include_files_txt = Path(tmpdir) / "include_files.txt"
231
+ include_files_txt.write_text("\n".join(files), encoding="utf-8")
232
+
233
+ # print(include_files_txt)
234
+ cmd_list: list[str] = [
235
+ "delete",
236
+ remote,
237
+ "--files-from",
238
+ str(include_files_txt),
239
+ "--checkers",
240
+ "1000",
241
+ "--transfers",
242
+ "1000",
243
+ ]
244
+ out = self._run(cmd_list)
245
+ return out
246
+
247
+ fut: Future = EXECUTOR.submit(_task)
248
+ futures.append(fut)
249
+ for fut in futures:
250
+ out = fut.result()
251
+ assert out is not None
252
+ if out.returncode != 0:
253
+ if check:
254
+ raise ValueError(f"Error deleting files: {out.stderr}")
255
+ else:
256
+ warnings.warn(f"Error deleting files: {out.stderr}")
237
257
 
238
258
  def copy(self, src: Dir | str, dst: Dir | str) -> CompletedProcess:
239
259
  """Copy files from source to destination.
@@ -263,6 +283,7 @@ class Rclone:
263
283
  files: str | File | list[str] | list[File],
264
284
  check=True,
265
285
  rmdirs=False,
286
+ verbose: bool | None = None,
266
287
  other_args: list[str] | None = None,
267
288
  ) -> CompletedProcess:
268
289
  """Delete a directory"""
@@ -277,40 +298,52 @@ class Rclone:
277
298
  return CompletedProcess.from_subprocess(cp)
278
299
 
279
300
  datalists: dict[str, list[str]] = partition_files(payload)
280
- out: subprocess.CompletedProcess | None = None
281
-
282
301
  completed_processes: list[subprocess.CompletedProcess] = []
302
+ verbose = get_verbose(verbose)
303
+
304
+ futures: list[Future] = []
283
305
 
284
306
  for remote, files in datalists.items():
285
- with TemporaryDirectory() as tmpdir:
286
- include_files_txt = Path(tmpdir) / "include_files.txt"
287
- include_files_txt.write_text("\n".join(files), encoding="utf-8")
288
-
289
- # print(include_files_txt)
290
- cmd_list: list[str] = [
291
- "delete",
292
- remote,
293
- "--files-from",
294
- str(include_files_txt),
295
- "--checkers",
296
- "1000",
297
- "--transfers",
298
- "1000",
299
- ]
300
- if rmdirs:
301
- cmd_list.append("--rmdirs")
302
- if other_args:
303
- cmd_list += other_args
304
- out = self._run(cmd_list)
305
- completed_processes.append(out)
307
+
308
+ def _task(files=files, check=check) -> subprocess.CompletedProcess:
309
+ with TemporaryDirectory() as tmpdir:
310
+ include_files_txt = Path(tmpdir) / "include_files.txt"
311
+ include_files_txt.write_text("\n".join(files), encoding="utf-8")
312
+
313
+ # print(include_files_txt)
314
+ cmd_list: list[str] = [
315
+ "delete",
316
+ remote,
317
+ "--files-from",
318
+ str(include_files_txt),
319
+ "--checkers",
320
+ "1000",
321
+ "--transfers",
322
+ "1000",
323
+ ]
324
+ if verbose:
325
+ cmd_list.append("-vvvv")
326
+ if rmdirs:
327
+ cmd_list.append("--rmdirs")
328
+ if other_args:
329
+ cmd_list += other_args
330
+ out = self._run(cmd_list, check=check)
306
331
  if out.returncode != 0:
307
332
  if check:
308
333
  completed_processes.append(out)
309
334
  raise ValueError(f"Error deleting files: {out}")
310
335
  else:
311
336
  warnings.warn(f"Error deleting files: {out}")
337
+ return out
338
+
339
+ fut: Future = EXECUTOR.submit(_task)
340
+ futures.append(fut)
341
+
342
+ for fut in futures:
343
+ out = fut.result()
344
+ assert out is not None
345
+ completed_processes.append(out)
312
346
 
313
- assert out is not None
314
347
  return CompletedProcess(completed_processes)
315
348
 
316
349
  @deprecated("delete_files")
@@ -132,15 +132,12 @@ def wait_for_mount(path: Path, mount_process: Any, timeout: int = 60) -> None:
132
132
 
133
133
 
134
134
  def partition_files(files: list[str]) -> dict[str, list[str]]:
135
+ """split between filename and parent directory path"""
135
136
  datalists: dict[str, list[str]] = {}
136
137
  for f in files:
137
- remote, path = f.split(":", 1)
138
- if "/" in path:
139
- bucket, path = path.split("/", 1)
140
- remote = f"{remote}:{bucket}"
141
- else:
142
- remote = f"{remote}:"
143
- if remote not in datalists:
144
- datalists[remote] = []
145
- datalists[remote].append(path)
138
+ base = os.path.basename(f)
139
+ parent_path = os.path.dirname(f)
140
+ if parent_path not in datalists:
141
+ datalists[parent_path] = []
142
+ datalists[parent_path].append(base)
146
143
  return datalists
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.39
3
+ Version: 1.0.41
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
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