rclone-api 1.0.35__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/rclone.py +48 -29
- rclone_api/util.py +15 -0
- {rclone_api-1.0.35.dist-info → rclone_api-1.0.36.dist-info}/METADATA +1 -1
- {rclone_api-1.0.35.dist-info → rclone_api-1.0.36.dist-info}/RECORD +8 -8
- {rclone_api-1.0.35.dist-info → rclone_api-1.0.36.dist-info}/LICENSE +0 -0
- {rclone_api-1.0.35.dist-info → rclone_api-1.0.36.dist-info}/WHEEL +0 -0
- {rclone_api-1.0.35.dist-info → rclone_api-1.0.36.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.0.35.dist-info → rclone_api-1.0.36.dist-info}/top_level.txt +0 -0
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
|
@@ -23,7 +22,7 @@ from rclone_api.file import File
|
|
23
22
|
from rclone_api.process import Process
|
24
23
|
from rclone_api.remote import Remote
|
25
24
|
from rclone_api.rpath import RPath
|
26
|
-
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
|
27
26
|
from rclone_api.walk import walk
|
28
27
|
|
29
28
|
|
@@ -184,7 +183,7 @@ class Rclone:
|
|
184
183
|
cmd_list: list[str] = ["copyto", src, dst]
|
185
184
|
self._run(cmd_list)
|
186
185
|
|
187
|
-
def
|
186
|
+
def copy_to(self, src: File | str, dst: File | str) -> None:
|
188
187
|
"""Copy multiple files from source to destination.
|
189
188
|
|
190
189
|
Warning - slow.
|
@@ -192,17 +191,48 @@ class Rclone:
|
|
192
191
|
Args:
|
193
192
|
payload: Dictionary of source and destination file paths
|
194
193
|
"""
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
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
|
206
236
|
|
207
237
|
def copy(self, src: Dir | str, dst: Dir | str) -> subprocess.CompletedProcess:
|
208
238
|
"""Copy files from source to destination.
|
@@ -238,19 +268,7 @@ class Rclone:
|
|
238
268
|
stderr="",
|
239
269
|
)
|
240
270
|
|
241
|
-
datalists: dict[str, list[str]] =
|
242
|
-
|
243
|
-
for f in payload:
|
244
|
-
remote, path = f.split(":", 1)
|
245
|
-
if "/" in path:
|
246
|
-
bucket, path = path.split("/", 1)
|
247
|
-
remote = f"{remote}:{bucket}"
|
248
|
-
else:
|
249
|
-
remote = f"{remote}:"
|
250
|
-
if remote not in datalists:
|
251
|
-
datalists[remote] = []
|
252
|
-
datalists[remote].append(path)
|
253
|
-
|
271
|
+
datalists: dict[str, list[str]] = partition_files(payload)
|
254
272
|
out: subprocess.CompletedProcess | None = None
|
255
273
|
|
256
274
|
for remote, files in datalists.items():
|
@@ -288,8 +306,9 @@ class Rclone:
|
|
288
306
|
arg: str = convert_to_str(path)
|
289
307
|
assert isinstance(arg, str)
|
290
308
|
try:
|
291
|
-
self.ls(arg)
|
292
|
-
|
309
|
+
dir_listing = self.ls(arg)
|
310
|
+
# print(dir_listing)
|
311
|
+
return len(dir_listing.dirs) > 0 or len(dir_listing.files) > 0
|
293
312
|
except subprocess.CalledProcessError:
|
294
313
|
return False
|
295
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
|
@@ -10,16 +10,16 @@ rclone_api/exec.py,sha256=HWmnU2Jwb-3EttSbAJSaLloYA7YI2mHTzRJ5VEri9aM,941
|
|
10
10
|
rclone_api/file.py,sha256=D02iHJW1LhfOiM_R_yPHP8_ApnDiYrkuraVcrV8-qkw,1246
|
11
11
|
rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
12
12
|
rclone_api/process.py,sha256=RrMfTe0bndmJ6gBK67ioqNvCstJ8aTC8RlGX1XBLlcw,4191
|
13
|
-
rclone_api/rclone.py,sha256=
|
13
|
+
rclone_api/rclone.py,sha256=XWk3aIyEqIQHv7Oq7z8W2wt7kxiypO6KHCVA_lnXV7Y,19038
|
14
14
|
rclone_api/remote.py,sha256=c9hlRKBCg1BFB9MCINaQIoCg10qyAkeqiS4brl8ce-8,343
|
15
15
|
rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
|
16
|
-
rclone_api/util.py,sha256=
|
16
|
+
rclone_api/util.py,sha256=N1n2Fxt-pU_xKwQdwXM3zAThBHG0zwDQY30s0iQao-0,4374
|
17
17
|
rclone_api/walk.py,sha256=kca0t1GAnF6FLclN01G8NG__Qe-ggodLtAbQSHyVPng,2968
|
18
18
|
rclone_api/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
19
19
|
rclone_api/cmd/list_files.py,sha256=x8FHODEilwKqwdiU1jdkeJbLwOqUkUQuDWPo2u_zpf0,741
|
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.
|
25
|
-
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
|