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 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 copyfiles(self, filelist: dict[File, File] | dict[str, str]) -> None:
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
- str_dict: dict[str, str] = {}
196
- for src, dst in filelist.items():
197
- src = src if isinstance(src, str) else str(src.path)
198
- dst = dst if isinstance(dst, str) else str(dst.path)
199
- str_dict[src] = dst
200
-
201
- with ThreadPoolExecutor(max_workers=64) as executor:
202
- for src, dst in str_dict.items(): # warning - slow
203
- cmd_list: list[str] = ["copyto", src, dst]
204
- # self._run(cmd_list)
205
- executor.submit(self._run, cmd_list)
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
- return True
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.35
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
@@ -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=0VwATZ8oTmW7wDRt2RsDjzk6nliLSNdxVNH22AvkKMg,18387
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=sUjH5NmsawmNbPMY7V6hD8vFJXCwbl44XM1kuij3tA0,3918
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.35.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
21
- rclone_api-1.0.35.dist-info/METADATA,sha256=Ubf6cdmIvU6NNFW2IBh7metZC3ZI3h4V2SPyHS6Q_Vg,4489
22
- rclone_api-1.0.35.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
23
- rclone_api-1.0.35.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
24
- rclone_api-1.0.35.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
25
- rclone_api-1.0.35.dist-info/RECORD,,
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,,