rclone-api 1.2.6__py2.py3-none-any.whl → 1.2.8__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 +51 -80
- {rclone_api-1.2.6.dist-info → rclone_api-1.2.8.dist-info}/METADATA +1 -1
- {rclone_api-1.2.6.dist-info → rclone_api-1.2.8.dist-info}/RECORD +7 -7
- {rclone_api-1.2.6.dist-info → rclone_api-1.2.8.dist-info}/LICENSE +0 -0
- {rclone_api-1.2.6.dist-info → rclone_api-1.2.8.dist-info}/WHEEL +0 -0
- {rclone_api-1.2.6.dist-info → rclone_api-1.2.8.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.2.6.dist-info → rclone_api-1.2.8.dist-info}/top_level.txt +0 -0
rclone_api/mount.py
CHANGED
|
@@ -288,6 +288,32 @@ def _cache_dir_delete_on_exit(cache_dir: Path) -> None:
|
|
|
288
288
|
warnings.warn(f"Error removing cache directory {cache_dir}: {e}")
|
|
289
289
|
|
|
290
290
|
|
|
291
|
+
def _read_from_mount_task(
|
|
292
|
+
offset: int, size: int, path: Path, verbose: bool
|
|
293
|
+
) -> bytes | Exception:
|
|
294
|
+
if verbose or True:
|
|
295
|
+
print(f"Fetching chunk: offset={offset}, size={size}, path={path}")
|
|
296
|
+
try:
|
|
297
|
+
with path.open("rb") as f:
|
|
298
|
+
f.seek(offset)
|
|
299
|
+
sz = f.read(size)
|
|
300
|
+
assert len(sz) == size, f"Invalid read size: {len(sz)}"
|
|
301
|
+
return sz
|
|
302
|
+
except KeyboardInterrupt as e:
|
|
303
|
+
import _thread
|
|
304
|
+
|
|
305
|
+
warnings.warn(f"Error fetching file chunk: {e}")
|
|
306
|
+
|
|
307
|
+
_thread.interrupt_main()
|
|
308
|
+
return Exception(e)
|
|
309
|
+
except Exception as e:
|
|
310
|
+
stack_trace = traceback.format_exc()
|
|
311
|
+
warnings.warn(
|
|
312
|
+
f"Error fetching file chunk at offset {offset} + {size}: {e}\n{stack_trace}"
|
|
313
|
+
)
|
|
314
|
+
return e
|
|
315
|
+
|
|
316
|
+
|
|
291
317
|
class MultiMountFileChunker:
|
|
292
318
|
def __init__(
|
|
293
319
|
self,
|
|
@@ -319,89 +345,34 @@ class MultiMountFileChunker:
|
|
|
319
345
|
def fetch(self, offset: int, size: int) -> Future[bytes | Exception]:
|
|
320
346
|
if self.verbose:
|
|
321
347
|
print(f"Fetching data range: offset={offset}, size={size}")
|
|
348
|
+
|
|
349
|
+
assert size > 0, f"Invalid size: {size}"
|
|
350
|
+
assert offset >= 0, f"Invalid offset: {offset}"
|
|
351
|
+
assert (
|
|
352
|
+
offset + size <= self.filesize
|
|
353
|
+
), f"Invalid offset + size: {offset} + {size} ({offset+size}) <= {self.filesize}"
|
|
354
|
+
|
|
322
355
|
try:
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
return self.executor.submit(lambda: err)
|
|
337
|
-
|
|
338
|
-
chunks: list[tuple[int, int]] = []
|
|
339
|
-
start = offset
|
|
340
|
-
end = offset + size
|
|
341
|
-
while start < end:
|
|
342
|
-
chunk_size = min(self.chunk_size.as_int(), end - start)
|
|
343
|
-
chunks.append((start, chunk_size))
|
|
344
|
-
start += chunk_size
|
|
345
|
-
|
|
346
|
-
futures: list[Future[bytes | Exception]] = []
|
|
347
|
-
for start, chunk_size in chunks:
|
|
348
|
-
self.semaphore.acquire()
|
|
356
|
+
self.semaphore.acquire()
|
|
357
|
+
with self.lock:
|
|
358
|
+
mount = self.mounts_availabe.pop()
|
|
359
|
+
self.mounts_processing.append(mount)
|
|
360
|
+
|
|
361
|
+
path = mount.mount_path / self.filename
|
|
362
|
+
|
|
363
|
+
def task(
|
|
364
|
+
offset=offset, size=size, path=path, mount=mount, verbose=self.verbose
|
|
365
|
+
) -> bytes | Exception:
|
|
366
|
+
out = _read_from_mount_task(
|
|
367
|
+
offset=offset, size=size, path=path, verbose=verbose
|
|
368
|
+
)
|
|
349
369
|
with self.lock:
|
|
350
|
-
|
|
351
|
-
self.
|
|
352
|
-
|
|
353
|
-
|
|
370
|
+
self.mounts_processing.remove(mount)
|
|
371
|
+
self.mounts_availabe.append(mount)
|
|
372
|
+
self.semaphore.release()
|
|
373
|
+
return out
|
|
354
374
|
|
|
355
|
-
|
|
356
|
-
offset=start, size=chunk_size, path=path, mount=mount
|
|
357
|
-
) -> bytes | Exception:
|
|
358
|
-
if self.verbose:
|
|
359
|
-
print(
|
|
360
|
-
f"Fetching chunk: offset={offset}, size={size}, path={path}"
|
|
361
|
-
)
|
|
362
|
-
try:
|
|
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)
|
|
375
|
+
fut = self.executor.submit(task)
|
|
405
376
|
return fut
|
|
406
377
|
except Exception as e:
|
|
407
378
|
warnings.warn(f"Error fetching file chunk: {e}")
|
|
@@ -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=qdfPatPKGAAaNexJQCvunq_MdBJL6NSlGmin8cHCXGg,13255
|
|
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
|
|
@@ -33,9 +33,9 @@ rclone_api/s3/chunk_types.py,sha256=2n9U1BZ_5mcpoLLbSqkhvzgKj814jtSMnih9CWKcChU,
|
|
|
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.8.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
|
37
|
+
rclone_api-1.2.8.dist-info/METADATA,sha256=eWhq_lLs9m_Vp01kxODo85kaTye0kNaizIDMFXeIlmY,4536
|
|
38
|
+
rclone_api-1.2.8.dist-info/WHEEL,sha256=rF4EZyR2XVS6irmOHQIJx2SUqXLZKRMUrjsg8UwN-XQ,109
|
|
39
|
+
rclone_api-1.2.8.dist-info/entry_points.txt,sha256=TV8kwP3FRzYwUEr0RLC7aJh0W03SAefIJNXTJ-FdMIQ,200
|
|
40
|
+
rclone_api-1.2.8.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
|
41
|
+
rclone_api-1.2.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|