rclone-api 1.2.5__tar.gz → 1.2.7__tar.gz

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.
Files changed (86) hide show
  1. {rclone_api-1.2.5 → rclone_api-1.2.7}/PKG-INFO +1 -1
  2. {rclone_api-1.2.5 → rclone_api-1.2.7}/pyproject.toml +1 -1
  3. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/mount.py +47 -82
  4. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/s3/chunk_file.py +4 -8
  5. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api.egg-info/PKG-INFO +1 -1
  6. {rclone_api-1.2.5 → rclone_api-1.2.7}/.aiderignore +0 -0
  7. {rclone_api-1.2.5 → rclone_api-1.2.7}/.github/workflows/lint.yml +0 -0
  8. {rclone_api-1.2.5 → rclone_api-1.2.7}/.github/workflows/push_macos.yml +0 -0
  9. {rclone_api-1.2.5 → rclone_api-1.2.7}/.github/workflows/push_ubuntu.yml +0 -0
  10. {rclone_api-1.2.5 → rclone_api-1.2.7}/.github/workflows/push_win.yml +0 -0
  11. {rclone_api-1.2.5 → rclone_api-1.2.7}/.gitignore +0 -0
  12. {rclone_api-1.2.5 → rclone_api-1.2.7}/.pylintrc +0 -0
  13. {rclone_api-1.2.5 → rclone_api-1.2.7}/.vscode/launch.json +0 -0
  14. {rclone_api-1.2.5 → rclone_api-1.2.7}/.vscode/settings.json +0 -0
  15. {rclone_api-1.2.5 → rclone_api-1.2.7}/.vscode/tasks.json +0 -0
  16. {rclone_api-1.2.5 → rclone_api-1.2.7}/LICENSE +0 -0
  17. {rclone_api-1.2.5 → rclone_api-1.2.7}/MANIFEST.in +0 -0
  18. {rclone_api-1.2.5 → rclone_api-1.2.7}/README.md +0 -0
  19. {rclone_api-1.2.5 → rclone_api-1.2.7}/clean +0 -0
  20. {rclone_api-1.2.5 → rclone_api-1.2.7}/install +0 -0
  21. {rclone_api-1.2.5 → rclone_api-1.2.7}/lint +0 -0
  22. {rclone_api-1.2.5 → rclone_api-1.2.7}/requirements.testing.txt +0 -0
  23. {rclone_api-1.2.5 → rclone_api-1.2.7}/setup.cfg +0 -0
  24. {rclone_api-1.2.5 → rclone_api-1.2.7}/setup.py +0 -0
  25. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/__init__.py +0 -0
  26. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/assets/example.txt +0 -0
  27. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/cli.py +0 -0
  28. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/cmd/copy_large_s3.py +0 -0
  29. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/cmd/list_files.py +0 -0
  30. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/completed_process.py +0 -0
  31. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/config.py +0 -0
  32. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/convert.py +0 -0
  33. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/deprecated.py +0 -0
  34. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/diff.py +0 -0
  35. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/dir.py +0 -0
  36. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/dir_listing.py +0 -0
  37. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/exec.py +0 -0
  38. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/experimental/flags.py +0 -0
  39. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/experimental/flags_base.py +0 -0
  40. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/file.py +0 -0
  41. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/filelist.py +0 -0
  42. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/group_files.py +0 -0
  43. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/process.py +0 -0
  44. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/profile/mount_copy_bytes.py +0 -0
  45. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/rclone.py +0 -0
  46. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/remote.py +0 -0
  47. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/rpath.py +0 -0
  48. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/s3/api.py +0 -0
  49. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/s3/basic_ops.py +0 -0
  50. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/s3/chunk_types.py +0 -0
  51. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/s3/create.py +0 -0
  52. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/s3/types.py +0 -0
  53. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/s3/upload_file_multipart.py +0 -0
  54. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/scan_missing_folders.py +0 -0
  55. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/types.py +0 -0
  56. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/util.py +0 -0
  57. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api/walk.py +0 -0
  58. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api.egg-info/SOURCES.txt +0 -0
  59. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  60. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api.egg-info/entry_points.txt +0 -0
  61. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api.egg-info/requires.txt +0 -0
  62. {rclone_api-1.2.5 → rclone_api-1.2.7}/src/rclone_api.egg-info/top_level.txt +0 -0
  63. {rclone_api-1.2.5 → rclone_api-1.2.7}/test +0 -0
  64. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/archive/test_paramiko.py.disabled +0 -0
  65. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_cmd_list_files.py +0 -0
  66. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_copy.py +0 -0
  67. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_copy_bytes.py +0 -0
  68. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_copy_file_resumable_s3.py +0 -0
  69. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_copy_files.py +0 -0
  70. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_diff.py +0 -0
  71. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_group_files.py +0 -0
  72. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_is_synced.py +0 -0
  73. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_ls.py +0 -0
  74. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_mount.py +0 -0
  75. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_mount_s3.py +0 -0
  76. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_obscure.py +0 -0
  77. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_rclone_config.py +0 -0
  78. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_remote_control.py +0 -0
  79. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_remotes.py +0 -0
  80. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_s3.py +0 -0
  81. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_scan_missing_folders.py +0 -0
  82. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_size_files.py +0 -0
  83. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_size_suffix.py +0 -0
  84. {rclone_api-1.2.5 → rclone_api-1.2.7}/tests/test_walk.py +0 -0
  85. {rclone_api-1.2.5 → rclone_api-1.2.7}/tox.ini +0 -0
  86. {rclone_api-1.2.5 → rclone_api-1.2.7}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.2.5
3
+ Version: 1.2.7
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
@@ -23,7 +23,7 @@ dependencies = [
23
23
  ]
24
24
 
25
25
  # Change this with the version number bump.
26
- version = "1.2.5"
26
+ version = "1.2.7"
27
27
 
28
28
  [tool.setuptools]
29
29
  package-dir = {"" = "src"}
@@ -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
- try:
324
- if offset + size > self.filesize:
325
- size = self.filesize - offset
326
- assert (
327
- offset + size <= self.filesize
328
- ), f"Invalid offset + size: {offset + size}, it is beyond the end of the file."
329
- assert size > 0, f"Invalid size: {size}"
330
- assert offset >= 0, f"Invalid offset: {offset}"
331
- except AssertionError as e:
332
- warnings.warn(f"Invalid chunk request: {e}")
333
- # return ValueError(e)
334
- # return self.executor.submit(lambda: Exception(e))
335
- err = Exception(e)
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()
349
- with self.lock:
350
- mount = self.mounts_availabe.pop()
351
- self.mounts_processing.append(mount)
352
-
353
- path = mount.mount_path / self.filename
354
-
355
- def task(
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)
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}")
@@ -105,15 +105,11 @@ def file_chunker(
105
105
  )
106
106
  return
107
107
 
108
- if isinstance(data, Exception):
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,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.2.5
3
+ Version: 1.2.7
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes