rclone-api 1.0.34__py2.py3-none-any.whl → 1.0.36__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/deprecated.py +24 -0
- rclone_api/rclone.py +56 -30
- rclone_api/util.py +15 -0
- {rclone_api-1.0.34.dist-info → rclone_api-1.0.36.dist-info}/METADATA +2 -2
- {rclone_api-1.0.34.dist-info → rclone_api-1.0.36.dist-info}/RECORD +9 -8
- {rclone_api-1.0.34.dist-info → rclone_api-1.0.36.dist-info}/LICENSE +0 -0
- {rclone_api-1.0.34.dist-info → rclone_api-1.0.36.dist-info}/WHEEL +0 -0
- {rclone_api-1.0.34.dist-info → rclone_api-1.0.36.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.0.34.dist-info → rclone_api-1.0.36.dist-info}/top_level.txt +0 -0
rclone_api/deprecated.py
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
import functools
|
2
|
+
import warnings
|
3
|
+
|
4
|
+
|
5
|
+
def deprecated(new_func_name: str):
|
6
|
+
"""Decorator to mark functions as deprecated.
|
7
|
+
|
8
|
+
Args:
|
9
|
+
new_func_name: The name of the function that should be used instead.
|
10
|
+
"""
|
11
|
+
|
12
|
+
def decorator(func):
|
13
|
+
@functools.wraps(func)
|
14
|
+
def wrapper(*args, **kwargs):
|
15
|
+
warnings.warn(
|
16
|
+
f"{func.__name__}() is deprecated; use {new_func_name}() instead.",
|
17
|
+
DeprecationWarning,
|
18
|
+
stacklevel=2,
|
19
|
+
)
|
20
|
+
return func(*args, **kwargs)
|
21
|
+
|
22
|
+
return wrapper
|
23
|
+
|
24
|
+
return decorator
|
rclone_api/rclone.py
CHANGED
@@ -5,7 +5,6 @@ Unit test file.
|
|
5
5
|
import subprocess
|
6
6
|
import time
|
7
7
|
import warnings
|
8
|
-
from concurrent.futures import ThreadPoolExecutor
|
9
8
|
from enum import Enum
|
10
9
|
from fnmatch import fnmatch
|
11
10
|
from pathlib import Path
|
@@ -15,6 +14,7 @@ from typing import Generator
|
|
15
14
|
from rclone_api import Dir
|
16
15
|
from rclone_api.config import Config
|
17
16
|
from rclone_api.convert import convert_to_filestr_list, convert_to_str
|
17
|
+
from rclone_api.deprecated import deprecated
|
18
18
|
from rclone_api.diff import DiffItem, diff_stream_from_running_process
|
19
19
|
from rclone_api.dir_listing import DirListing
|
20
20
|
from rclone_api.exec import RcloneExec
|
@@ -22,7 +22,7 @@ from rclone_api.file import File
|
|
22
22
|
from rclone_api.process import Process
|
23
23
|
from rclone_api.remote import Remote
|
24
24
|
from rclone_api.rpath import RPath
|
25
|
-
from rclone_api.util import get_rclone_exe, to_path, wait_for_mount
|
25
|
+
from rclone_api.util import get_rclone_exe, partition_files, to_path, wait_for_mount
|
26
26
|
from rclone_api.walk import walk
|
27
27
|
|
28
28
|
|
@@ -183,7 +183,7 @@ class Rclone:
|
|
183
183
|
cmd_list: list[str] = ["copyto", src, dst]
|
184
184
|
self._run(cmd_list)
|
185
185
|
|
186
|
-
def
|
186
|
+
def copy_to(self, src: File | str, dst: File | str) -> None:
|
187
187
|
"""Copy multiple files from source to destination.
|
188
188
|
|
189
189
|
Warning - slow.
|
@@ -191,17 +191,48 @@ class Rclone:
|
|
191
191
|
Args:
|
192
192
|
payload: Dictionary of source and destination file paths
|
193
193
|
"""
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
194
|
+
src = str(src)
|
195
|
+
dst = str(dst)
|
196
|
+
cmd_list: list[str] = ["copyto", src, dst]
|
197
|
+
self._run(cmd_list)
|
198
|
+
|
199
|
+
def copyfiles(self, files: str | File | list[str] | list[File]) -> None:
|
200
|
+
"""Copy multiple files from source to destination.
|
201
|
+
|
202
|
+
Warning - slow.
|
203
|
+
|
204
|
+
Args:
|
205
|
+
payload: Dictionary of source and destination file paths
|
206
|
+
"""
|
207
|
+
payload: list[str] = convert_to_filestr_list(files)
|
208
|
+
if len(payload) == 0:
|
209
|
+
return
|
210
|
+
|
211
|
+
datalists: dict[str, list[str]] = partition_files(payload)
|
212
|
+
out: subprocess.CompletedProcess | None = None
|
213
|
+
|
214
|
+
for remote, files in datalists.items():
|
215
|
+
with TemporaryDirectory() as tmpdir:
|
216
|
+
include_files_txt = Path(tmpdir) / "include_files.txt"
|
217
|
+
include_files_txt.write_text("\n".join(files), encoding="utf-8")
|
218
|
+
|
219
|
+
print(include_files_txt)
|
220
|
+
cmd_list: list[str] = [
|
221
|
+
"delete",
|
222
|
+
remote,
|
223
|
+
"--files-from",
|
224
|
+
str(include_files_txt),
|
225
|
+
"--checkers",
|
226
|
+
"1000",
|
227
|
+
"--transfers",
|
228
|
+
"1000",
|
229
|
+
]
|
230
|
+
out = self._run(cmd_list)
|
231
|
+
if out.returncode != 0:
|
232
|
+
print(out)
|
233
|
+
raise ValueError(f"Error deleting files: {out.stderr}")
|
234
|
+
|
235
|
+
assert out is not None
|
205
236
|
|
206
237
|
def copy(self, src: Dir | str, dst: Dir | str) -> subprocess.CompletedProcess:
|
207
238
|
"""Copy files from source to destination.
|
@@ -224,7 +255,7 @@ class Rclone:
|
|
224
255
|
cmd_list: list[str] = ["purge", str(path)]
|
225
256
|
return self._run(cmd_list)
|
226
257
|
|
227
|
-
def
|
258
|
+
def delete_files(
|
228
259
|
self, files: str | File | list[str] | list[File]
|
229
260
|
) -> subprocess.CompletedProcess:
|
230
261
|
"""Delete a directory"""
|
@@ -237,19 +268,7 @@ class Rclone:
|
|
237
268
|
stderr="",
|
238
269
|
)
|
239
270
|
|
240
|
-
datalists: dict[str, list[str]] =
|
241
|
-
|
242
|
-
for f in payload:
|
243
|
-
remote, path = f.split(":", 1)
|
244
|
-
if "/" in path:
|
245
|
-
bucket, path = path.split("/", 1)
|
246
|
-
remote = f"{remote}:{bucket}"
|
247
|
-
else:
|
248
|
-
remote = f"{remote}:"
|
249
|
-
if remote not in datalists:
|
250
|
-
datalists[remote] = []
|
251
|
-
datalists[remote].append(path)
|
252
|
-
|
271
|
+
datalists: dict[str, list[str]] = partition_files(payload)
|
253
272
|
out: subprocess.CompletedProcess | None = None
|
254
273
|
|
255
274
|
for remote, files in datalists.items():
|
@@ -276,13 +295,20 @@ class Rclone:
|
|
276
295
|
assert out is not None
|
277
296
|
return out
|
278
297
|
|
298
|
+
@deprecated("delete_files")
|
299
|
+
def deletefiles(
|
300
|
+
self, files: str | File | list[str] | list[File]
|
301
|
+
) -> subprocess.CompletedProcess:
|
302
|
+
return self.delete_files(files)
|
303
|
+
|
279
304
|
def exists(self, path: Dir | Remote | str | File) -> bool:
|
280
305
|
"""Check if a file or directory exists."""
|
281
306
|
arg: str = convert_to_str(path)
|
282
307
|
assert isinstance(arg, str)
|
283
308
|
try:
|
284
|
-
self.ls(arg)
|
285
|
-
|
309
|
+
dir_listing = self.ls(arg)
|
310
|
+
# print(dir_listing)
|
311
|
+
return len(dir_listing.dirs) > 0 or len(dir_listing.files) > 0
|
286
312
|
except subprocess.CalledProcessError:
|
287
313
|
return False
|
288
314
|
|
rclone_api/util.py
CHANGED
@@ -129,3 +129,18 @@ def wait_for_mount(path: Path, mount_process: Any, timeout: int = 60) -> None:
|
|
129
129
|
if path.exists():
|
130
130
|
return
|
131
131
|
raise TimeoutError(f"Path {path} did not exist after {timeout} seconds")
|
132
|
+
|
133
|
+
|
134
|
+
def partition_files(files: list[str]) -> dict[str, list[str]]:
|
135
|
+
datalists: dict[str, list[str]] = {}
|
136
|
+
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)
|
146
|
+
return datalists
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: rclone_api
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.36
|
4
4
|
Summary: rclone api in python
|
5
5
|
Home-page: https://github.com/zackees/rclone-api
|
6
6
|
Maintainer: Zachary Vorhies
|
@@ -127,7 +127,7 @@ if listing.files:
|
|
127
127
|
# Delete a File
|
128
128
|
print("\n=== Deleting a File ===")
|
129
129
|
file_to_delete = f"dst:{BUCKET_NAME}/zachs_video/sample.png_copy"
|
130
|
-
rclone.
|
130
|
+
rclone.delete_files([file_to_delete])
|
131
131
|
print(f"Deleted {file_to_delete}")
|
132
132
|
|
133
133
|
# Walk Through a Directory
|
@@ -2,6 +2,7 @@ rclone_api/__init__.py,sha256=L_ulzYG9WmQqmrVANt-Omi1FJUQVTkXA7SVZx9QH_9M,457
|
|
2
2
|
rclone_api/cli.py,sha256=dibfAZIh0kXWsBbfp3onKLjyZXo54mTzDjUdzJlDlWo,231
|
3
3
|
rclone_api/config.py,sha256=tP6cU9DnCCEIRc_KP9HPur1jFLLg2QGFSxNwFm6_MVw,118
|
4
4
|
rclone_api/convert.py,sha256=Mx9Qo7zhkOedJd8LdhPvNGHp8znJzOk4f_2KWnoGc78,1012
|
5
|
+
rclone_api/deprecated.py,sha256=qWKpnZdYcBK7YQZKuVoWWXDwi-uqiAtbjgPcci_efow,590
|
5
6
|
rclone_api/diff.py,sha256=UqAiWJjAeTTy2ewH6idYKt92Y_JltGAWvrZuE9RNKX8,4159
|
6
7
|
rclone_api/dir.py,sha256=vV-bcI2ESijmwF5rPID5WO2K7soAfZa35wv4KRh_GIo,2154
|
7
8
|
rclone_api/dir_listing.py,sha256=9Qqf2SUswrOEkyqmaH23V51I18X6ePiXb9B1vUwRF5o,1571
|
@@ -9,16 +10,16 @@ rclone_api/exec.py,sha256=HWmnU2Jwb-3EttSbAJSaLloYA7YI2mHTzRJ5VEri9aM,941
|
|
9
10
|
rclone_api/file.py,sha256=D02iHJW1LhfOiM_R_yPHP8_ApnDiYrkuraVcrV8-qkw,1246
|
10
11
|
rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
11
12
|
rclone_api/process.py,sha256=RrMfTe0bndmJ6gBK67ioqNvCstJ8aTC8RlGX1XBLlcw,4191
|
12
|
-
rclone_api/rclone.py,sha256=
|
13
|
+
rclone_api/rclone.py,sha256=XWk3aIyEqIQHv7Oq7z8W2wt7kxiypO6KHCVA_lnXV7Y,19038
|
13
14
|
rclone_api/remote.py,sha256=c9hlRKBCg1BFB9MCINaQIoCg10qyAkeqiS4brl8ce-8,343
|
14
15
|
rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
|
15
|
-
rclone_api/util.py,sha256=
|
16
|
+
rclone_api/util.py,sha256=N1n2Fxt-pU_xKwQdwXM3zAThBHG0zwDQY30s0iQao-0,4374
|
16
17
|
rclone_api/walk.py,sha256=kca0t1GAnF6FLclN01G8NG__Qe-ggodLtAbQSHyVPng,2968
|
17
18
|
rclone_api/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
18
19
|
rclone_api/cmd/list_files.py,sha256=x8FHODEilwKqwdiU1jdkeJbLwOqUkUQuDWPo2u_zpf0,741
|
19
|
-
rclone_api-1.0.
|
20
|
-
rclone_api-1.0.
|
21
|
-
rclone_api-1.0.
|
22
|
-
rclone_api-1.0.
|
23
|
-
rclone_api-1.0.
|
24
|
-
rclone_api-1.0.
|
20
|
+
rclone_api-1.0.36.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
21
|
+
rclone_api-1.0.36.dist-info/METADATA,sha256=dRfp6LOgaS5s_QIrSN_JoD2V8CLHDMWH9QApRvsCJjc,4489
|
22
|
+
rclone_api-1.0.36.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
|
23
|
+
rclone_api-1.0.36.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
|
24
|
+
rclone_api-1.0.36.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
25
|
+
rclone_api-1.0.36.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|