rclone-api 1.2.5__py2.py3-none-any.whl → 1.2.7__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/mount.py +47 -82
- rclone_api/s3/chunk_file.py +4 -8
- {rclone_api-1.2.5.dist-info → rclone_api-1.2.7.dist-info}/METADATA +1 -1
- {rclone_api-1.2.5.dist-info → rclone_api-1.2.7.dist-info}/RECORD +8 -8
- {rclone_api-1.2.5.dist-info → rclone_api-1.2.7.dist-info}/LICENSE +0 -0
- {rclone_api-1.2.5.dist-info → rclone_api-1.2.7.dist-info}/WHEEL +0 -0
- {rclone_api-1.2.5.dist-info → rclone_api-1.2.7.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.2.5.dist-info → rclone_api-1.2.7.dist-info}/top_level.txt +0 -0
rclone_api/mount.py
CHANGED
|
@@ -319,89 +319,54 @@ class MultiMountFileChunker:
|
|
|
319
319
|
def fetch(self, offset: int, size: int) -> Future[bytes | Exception]:
|
|
320
320
|
if self.verbose:
|
|
321
321
|
print(f"Fetching data range: offset={offset}, size={size}")
|
|
322
|
+
|
|
323
|
+
assert size > 0, f"Invalid size: {size}"
|
|
324
|
+
assert offset >= 0, f"Invalid offset: {offset}"
|
|
325
|
+
assert (
|
|
326
|
+
offset + size <= self.filesize
|
|
327
|
+
), f"Invalid offset + size: {offset} + {size} ({offset+size}) <= {self.filesize}"
|
|
328
|
+
|
|
322
329
|
try:
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
# make sure we don't overflow the file size
|
|
364
|
-
# assert (
|
|
365
|
-
# offset + size <= self.chunk_size.as_int()
|
|
366
|
-
# ), f"Invalid offset + size: {offset + size}, it is beyond the end of the file."
|
|
367
|
-
if offset + size > self.filesize:
|
|
368
|
-
size = self.filesize - offset
|
|
369
|
-
with path.open("rb") as f:
|
|
370
|
-
f.seek(offset)
|
|
371
|
-
return f.read(size)
|
|
372
|
-
except KeyboardInterrupt as e:
|
|
373
|
-
import _thread
|
|
374
|
-
|
|
375
|
-
warnings.warn(f"Error fetching file chunk: {e}")
|
|
376
|
-
|
|
377
|
-
_thread.interrupt_main()
|
|
378
|
-
return Exception(e)
|
|
379
|
-
except Exception as e:
|
|
380
|
-
stack_trace = traceback.format_exc()
|
|
381
|
-
warnings.warn(
|
|
382
|
-
f"Error fetching file chunk at offset {offset} + {size}: {e}\n{stack_trace}"
|
|
383
|
-
)
|
|
384
|
-
return e
|
|
385
|
-
finally:
|
|
386
|
-
with self.lock:
|
|
387
|
-
self.mounts_processing.remove(mount)
|
|
388
|
-
self.mounts_availabe.append(mount)
|
|
389
|
-
self.semaphore.release()
|
|
390
|
-
|
|
391
|
-
fut = self.executor.submit(task)
|
|
392
|
-
futures.append(fut)
|
|
393
|
-
|
|
394
|
-
def combine(futs: list[Future[bytes | Exception]]) -> bytes | Exception:
|
|
395
|
-
finished_list: list[bytes | Exception] = [f.result() for f in futs]
|
|
396
|
-
bytes_list = [f for f in finished_list if isinstance(f, bytes)]
|
|
397
|
-
if len(bytes_list) != len(finished_list):
|
|
398
|
-
exceptions = [f for f in finished_list if isinstance(f, Exception)]
|
|
399
|
-
return Exception(f"Error fetching file chunk: {exceptions}")
|
|
400
|
-
return b"".join(bytes_list)
|
|
401
|
-
|
|
402
|
-
if len(futures) == 1:
|
|
403
|
-
return futures[0]
|
|
404
|
-
fut = self.executor.submit(combine, futures)
|
|
330
|
+
self.semaphore.acquire()
|
|
331
|
+
with self.lock:
|
|
332
|
+
mount = self.mounts_availabe.pop()
|
|
333
|
+
self.mounts_processing.append(mount)
|
|
334
|
+
|
|
335
|
+
path = mount.mount_path / self.filename
|
|
336
|
+
|
|
337
|
+
def task(
|
|
338
|
+
offset=offset, size=size, path=path, mount=mount
|
|
339
|
+
) -> bytes | Exception:
|
|
340
|
+
if self.verbose or True:
|
|
341
|
+
print(f"Fetching chunk: offset={offset}, size={size}, path={path}")
|
|
342
|
+
try:
|
|
343
|
+
if offset + size > self.filesize:
|
|
344
|
+
raise ValueError(f"Invalid offset + size: {offset + size}")
|
|
345
|
+
with path.open("rb") as f:
|
|
346
|
+
f.seek(offset)
|
|
347
|
+
sz = f.read(size)
|
|
348
|
+
assert len(sz) == size, f"Invalid read size: {len(sz)}"
|
|
349
|
+
return sz
|
|
350
|
+
except KeyboardInterrupt as e:
|
|
351
|
+
import _thread
|
|
352
|
+
|
|
353
|
+
warnings.warn(f"Error fetching file chunk: {e}")
|
|
354
|
+
|
|
355
|
+
_thread.interrupt_main()
|
|
356
|
+
return Exception(e)
|
|
357
|
+
except Exception as e:
|
|
358
|
+
stack_trace = traceback.format_exc()
|
|
359
|
+
warnings.warn(
|
|
360
|
+
f"Error fetching file chunk at offset {offset} + {size}: {e}\n{stack_trace}"
|
|
361
|
+
)
|
|
362
|
+
return e
|
|
363
|
+
finally:
|
|
364
|
+
with self.lock:
|
|
365
|
+
self.mounts_processing.remove(mount)
|
|
366
|
+
self.mounts_availabe.append(mount)
|
|
367
|
+
self.semaphore.release()
|
|
368
|
+
|
|
369
|
+
fut = self.executor.submit(task)
|
|
405
370
|
return fut
|
|
406
371
|
except Exception as e:
|
|
407
372
|
warnings.warn(f"Error fetching file chunk: {e}")
|
rclone_api/s3/chunk_file.py
CHANGED
|
@@ -105,15 +105,11 @@ def file_chunker(
|
|
|
105
105
|
)
|
|
106
106
|
return
|
|
107
107
|
|
|
108
|
-
if
|
|
109
|
-
err: Exception = data
|
|
110
|
-
warnings.warn(
|
|
111
|
-
f"Error reading file: {err}, skipping part {part_number}"
|
|
112
|
-
)
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
if not data:
|
|
108
|
+
if not data or len(data) == 0:
|
|
116
109
|
warnings.warn(f"Empty data for part {part_number} of {file_path}")
|
|
110
|
+
raise ValueError(
|
|
111
|
+
f"Empty data for part {part_number} of {file_path}"
|
|
112
|
+
)
|
|
117
113
|
|
|
118
114
|
file_chunk = FileChunk(
|
|
119
115
|
src,
|
|
@@ -11,7 +11,7 @@ rclone_api/exec.py,sha256=Pd7pUBd8ib5MzqvMybG2DQISPRbDRu20VjVRL2mLAVY,1076
|
|
|
11
11
|
rclone_api/file.py,sha256=EP5yT2dZ0H2p7CY5n0y5k5pHhIliV25pm8KOwBklUTk,1863
|
|
12
12
|
rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
|
13
13
|
rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
|
|
14
|
-
rclone_api/mount.py,sha256=
|
|
14
|
+
rclone_api/mount.py,sha256=bnujsYZ0uNvIovfgkvoCyz0qZ71GHIcqfVbjESNMgGI,13375
|
|
15
15
|
rclone_api/process.py,sha256=rBj_S86jC6nqCYop-jq8r9eMSteKeObxUrJMgH8LZvI,5084
|
|
16
16
|
rclone_api/rclone.py,sha256=V4oeepsleic2llCA7JekMw1iOwN7uYE3ktJ-gEA7wcw,49277
|
|
17
17
|
rclone_api/remote.py,sha256=O9WDUFQy9f6oT1HdUbTixK2eg0xtBBm8k4Xl6aa6K00,431
|
|
@@ -28,14 +28,14 @@ rclone_api/experimental/flags_base.py,sha256=ajU_czkTcAxXYU-SlmiCfHY7aCQGHvpCLqJ
|
|
|
28
28
|
rclone_api/profile/mount_copy_bytes.py,sha256=_bd9oergTuCdj1P6AVh_pC6GmtCpLFQYwiTdhwXeYZE,8404
|
|
29
29
|
rclone_api/s3/api.py,sha256=PafsIEyWDpLWAXsZAjFm9CY14vJpsDr9lOsn0kGRLZ0,4009
|
|
30
30
|
rclone_api/s3/basic_ops.py,sha256=hK3366xhVEzEcjz9Gk_8lFx6MRceAk72cax6mUrr6ko,2104
|
|
31
|
-
rclone_api/s3/chunk_file.py,sha256=
|
|
31
|
+
rclone_api/s3/chunk_file.py,sha256=2YLWPzQnVVtdBUOlZkLATcRcQGE18cI2TJZzfj4LAoc,4402
|
|
32
32
|
rclone_api/s3/chunk_types.py,sha256=2n9U1BZ_5mcpoLLbSqkhvzgKj814jtSMnih9CWKcChU,10592
|
|
33
33
|
rclone_api/s3/create.py,sha256=wgfkapv_j904CfKuWyiBIWJVxfAx_ftemFSUV14aT68,3149
|
|
34
34
|
rclone_api/s3/types.py,sha256=ZUw9s164wljCEMTS4CoHXNzFIhYJEgKD6NDAu-RXyr8,1551
|
|
35
35
|
rclone_api/s3/upload_file_multipart.py,sha256=aDaLF2FWSvU_jurxiFphGZBncvkPqWN47VFNzYSSTWM,10906
|
|
36
|
-
rclone_api-1.2.
|
|
37
|
-
rclone_api-1.2.
|
|
38
|
-
rclone_api-1.2.
|
|
39
|
-
rclone_api-1.2.
|
|
40
|
-
rclone_api-1.2.
|
|
41
|
-
rclone_api-1.2.
|
|
36
|
+
rclone_api-1.2.7.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
|
37
|
+
rclone_api-1.2.7.dist-info/METADATA,sha256=P6YPH1dHv2MVivIFK7NJqhErXVikuans9oR7kX1Pn4Q,4536
|
|
38
|
+
rclone_api-1.2.7.dist-info/WHEEL,sha256=rF4EZyR2XVS6irmOHQIJx2SUqXLZKRMUrjsg8UwN-XQ,109
|
|
39
|
+
rclone_api-1.2.7.dist-info/entry_points.txt,sha256=TV8kwP3FRzYwUEr0RLC7aJh0W03SAefIJNXTJ-FdMIQ,200
|
|
40
|
+
rclone_api-1.2.7.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
|
41
|
+
rclone_api-1.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|