rclone-api 1.1.8__tar.gz → 1.1.10__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 (85) hide show
  1. {rclone_api-1.1.8 → rclone_api-1.1.10}/PKG-INFO +1 -1
  2. {rclone_api-1.1.8 → rclone_api-1.1.10}/pyproject.toml +1 -1
  3. rclone_api-1.1.10/rclone-mounted-ranged-download.conf.old3393025366 +0 -0
  4. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/cmd/copy_large_s3.py +2 -2
  5. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/mount.py +16 -3
  6. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/rclone.py +6 -4
  7. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/types.py +19 -19
  8. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api.egg-info/PKG-INFO +1 -1
  9. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api.egg-info/SOURCES.txt +1 -0
  10. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_size_suffix.py +6 -1
  11. {rclone_api-1.1.8 → rclone_api-1.1.10}/.aiderignore +0 -0
  12. {rclone_api-1.1.8 → rclone_api-1.1.10}/.github/workflows/lint.yml +0 -0
  13. {rclone_api-1.1.8 → rclone_api-1.1.10}/.github/workflows/push_macos.yml +0 -0
  14. {rclone_api-1.1.8 → rclone_api-1.1.10}/.github/workflows/push_ubuntu.yml +0 -0
  15. {rclone_api-1.1.8 → rclone_api-1.1.10}/.github/workflows/push_win.yml +0 -0
  16. {rclone_api-1.1.8 → rclone_api-1.1.10}/.gitignore +0 -0
  17. {rclone_api-1.1.8 → rclone_api-1.1.10}/.pylintrc +0 -0
  18. {rclone_api-1.1.8 → rclone_api-1.1.10}/.vscode/launch.json +0 -0
  19. {rclone_api-1.1.8 → rclone_api-1.1.10}/.vscode/settings.json +0 -0
  20. {rclone_api-1.1.8 → rclone_api-1.1.10}/.vscode/tasks.json +0 -0
  21. {rclone_api-1.1.8 → rclone_api-1.1.10}/LICENSE +0 -0
  22. {rclone_api-1.1.8 → rclone_api-1.1.10}/MANIFEST.in +0 -0
  23. {rclone_api-1.1.8 → rclone_api-1.1.10}/README.md +0 -0
  24. {rclone_api-1.1.8 → rclone_api-1.1.10}/clean +0 -0
  25. {rclone_api-1.1.8 → rclone_api-1.1.10}/install +0 -0
  26. {rclone_api-1.1.8 → rclone_api-1.1.10}/lint +0 -0
  27. {rclone_api-1.1.8 → rclone_api-1.1.10}/requirements.testing.txt +0 -0
  28. {rclone_api-1.1.8 → rclone_api-1.1.10}/setup.cfg +0 -0
  29. {rclone_api-1.1.8 → rclone_api-1.1.10}/setup.py +0 -0
  30. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/__init__.py +0 -0
  31. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/assets/example.txt +0 -0
  32. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/cli.py +0 -0
  33. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/cmd/list_files.py +0 -0
  34. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/completed_process.py +0 -0
  35. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/config.py +0 -0
  36. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/convert.py +0 -0
  37. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/deprecated.py +0 -0
  38. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/diff.py +0 -0
  39. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/dir.py +0 -0
  40. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/dir_listing.py +0 -0
  41. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/exec.py +0 -0
  42. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/experimental/flags.py +0 -0
  43. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/experimental/flags_base.py +0 -0
  44. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/file.py +0 -0
  45. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/filelist.py +0 -0
  46. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/group_files.py +0 -0
  47. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/process.py +0 -0
  48. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/remote.py +0 -0
  49. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/rpath.py +0 -0
  50. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/s3/api.py +0 -0
  51. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/s3/basic_ops.py +0 -0
  52. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/s3/chunk_file.py +0 -0
  53. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/s3/chunk_types.py +0 -0
  54. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/s3/chunk_uploader.py +0 -0
  55. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/s3/create.py +0 -0
  56. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/s3/types.py +0 -0
  57. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/scan_missing_folders.py +0 -0
  58. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/util.py +0 -0
  59. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api/walk.py +0 -0
  60. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  61. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api.egg-info/entry_points.txt +0 -0
  62. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api.egg-info/requires.txt +0 -0
  63. {rclone_api-1.1.8 → rclone_api-1.1.10}/src/rclone_api.egg-info/top_level.txt +0 -0
  64. {rclone_api-1.1.8 → rclone_api-1.1.10}/test +0 -0
  65. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/archive/test_paramiko.py.disabled +0 -0
  66. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_cmd_list_files.py +0 -0
  67. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_copy.py +0 -0
  68. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_copy_files.py +0 -0
  69. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_diff.py +0 -0
  70. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_group_files.py +0 -0
  71. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_is_synced.py +0 -0
  72. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_ls.py +0 -0
  73. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_mount.py +0 -0
  74. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_mount_s3.py +0 -0
  75. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_mounted_ranged_download.py +0 -0
  76. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_obscure.py +0 -0
  77. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_rclone_config.py +0 -0
  78. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_remote_control.py +0 -0
  79. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_remotes.py +0 -0
  80. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_s3.py +0 -0
  81. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_scan_missing_folders.py +0 -0
  82. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_size_files.py +0 -0
  83. {rclone_api-1.1.8 → rclone_api-1.1.10}/tests/test_walk.py +0 -0
  84. {rclone_api-1.1.8 → rclone_api-1.1.10}/tox.ini +0 -0
  85. {rclone_api-1.1.8 → rclone_api-1.1.10}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.1.8
3
+ Version: 1.1.10
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
@@ -21,7 +21,7 @@ dependencies = [
21
21
  ]
22
22
 
23
23
  # Change this with the version number bump.
24
- version = "1.1.8"
24
+ version = "1.1.10"
25
25
 
26
26
  [tool.setuptools]
27
27
  package-dir = {"" = "src"}
@@ -38,13 +38,13 @@ def _parse_args() -> Args:
38
38
  "--chunk-size",
39
39
  help="Chunk size that will be read and uploaded in in SizeSuffix (i.e. 128M = 128 megabytes) form",
40
40
  type=str,
41
- default="512M",
41
+ default="1G",
42
42
  )
43
43
  parser.add_argument(
44
44
  "--threads",
45
45
  help="Number of threads to use per chunk",
46
46
  type=int,
47
- default=16,
47
+ default=64,
48
48
  )
49
49
  parser.add_argument("--retries", help="Number of retries", type=int, default=3)
50
50
  parser.add_argument(
@@ -18,12 +18,23 @@ class Mount:
18
18
 
19
19
  mount_path: Path
20
20
  process: Process
21
+ _closed: bool = False
21
22
 
22
23
  def __post_init__(self):
23
24
  assert isinstance(self.mount_path, Path)
24
25
  assert self.process is not None
25
26
  wait_for_mount(self.mount_path, self.process)
26
27
 
28
+ def close(self, wait=True) -> None:
29
+ """Clean up the mount."""
30
+ if self._closed:
31
+ return
32
+ self._closed = True
33
+ clean_mount(self, verbose=False)
34
+
35
+ def __del__(self):
36
+ self.close(wait=False)
37
+
27
38
 
28
39
  def run_command(cmd: str, verbose: bool) -> int:
29
40
  """Run a shell command and print its output if verbose is True."""
@@ -74,7 +85,7 @@ def wait_for_mount(path: Path, mount_process: Any, timeout: int = 10) -> None:
74
85
  time.sleep(1)
75
86
 
76
87
 
77
- def clean_mount(mount: Mount | Path, verbose: bool = False) -> None:
88
+ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
78
89
  """
79
90
  Clean up a mount path across Linux, macOS, and Windows.
80
91
 
@@ -98,7 +109,8 @@ def clean_mount(mount: Mount | Path, verbose: bool = False) -> None:
98
109
  mount_exists = True
99
110
 
100
111
  # Give the system a moment (if unmount is in progress, etc.)
101
- time.sleep(2)
112
+ if wait:
113
+ time.sleep(2)
102
114
 
103
115
  if not mount_exists:
104
116
  if verbose:
@@ -132,7 +144,8 @@ def clean_mount(mount: Mount | Path, verbose: bool = False) -> None:
132
144
  warnings.warn(f"Unsupported platform: {_SYSTEM}")
133
145
 
134
146
  # Allow some time for the unmount commands to take effect.
135
- time.sleep(2)
147
+ if wait:
148
+ time.sleep(2)
136
149
 
137
150
  # Re-check if the mount path still exists.
138
151
  try:
@@ -695,6 +695,7 @@ class Rclone:
695
695
  vfs_read_chunk_size = unit_chunk_size
696
696
  vfs_read_chunk_size_limit = chunk_size
697
697
  vfs_read_chunk_streams = threads
698
+ vfs_disk_space_total_size = chunk_size
698
699
  assert (
699
700
  chunk_size.as_int() % vfs_read_chunk_size.as_int() == 0
700
701
  ), f"chunk_size {chunk_size} must be a multiple of vfs_read_chunk_size {vfs_read_chunk_size}"
@@ -704,6 +705,10 @@ class Rclone:
704
705
  vfs_read_chunk_size_limit.as_str(),
705
706
  ]
706
707
  other_args += ["--vfs-read-chunk-streams", str(vfs_read_chunk_streams)]
708
+ other_args += [
709
+ "--vfs-disk-space-total-size",
710
+ vfs_disk_space_total_size.as_str(),
711
+ ]
707
712
  mount_path = mount_path or Path("tmp_mnts") / random_str(12)
708
713
  src_path = Path(src)
709
714
  name = src_path.name
@@ -903,11 +908,8 @@ class Rclone:
903
908
  warnings.warn(f"Error in scoped_mount: {e}\n\nStack Trace:\n{stack_trace}")
904
909
  raise
905
910
  finally:
906
-
907
911
  if not error_happened:
908
- from rclone_api.mount import clean_mount
909
-
910
- clean_mount(mount, verbose=verbose)
912
+ mount.close()
911
913
 
912
914
  # Settings optimized for s3.
913
915
  def mount_s3(
@@ -52,33 +52,33 @@ def _to_size_suffix(size: int) -> str:
52
52
  raise ValueError(f"Invalid size: {size}")
53
53
 
54
54
 
55
- _PATTERN_SIZE_SUFFIX = re.compile(r"^(\d+)([A-Za-z]+)$")
55
+ # Update regex to allow decimals (e.g., 16.5MB)
56
+ _PATTERN_SIZE_SUFFIX = re.compile(r"^(\d+(?:\.\d+)?)([A-Za-z]+)$")
56
57
 
57
58
 
58
59
  def _from_size_suffix(size: str) -> int:
59
- # 16MiB
60
- # parse out number and suffix
61
60
  if size == "0":
62
61
  return 0
63
62
  match = _PATTERN_SIZE_SUFFIX.match(size)
64
63
  if match is None:
65
64
  raise ValueError(f"Invalid size suffix: {size}")
66
- size = match.group(1)
67
- suffix = match.group(2)[0:1].upper()
68
- n = int(size)
69
- if suffix == "B":
70
- return n
71
- if suffix == "K":
72
- return n * 1024
73
- if suffix == "M":
74
- return n * 1024 * 1024
75
- if suffix == "G":
76
- return n * 1024 * 1024 * 1024
77
- if suffix == "T":
78
- return n * 1024 * 1024 * 1024 * 1024
79
- if suffix == "P":
80
- return n * 1024 * 1024 * 1024 * 1024 * 1024
81
- raise ValueError(f"Invalid size suffix: {size}")
65
+ num_str, suffix = match.group(1), match.group(2)
66
+ n = float(num_str)
67
+ # Determine the unit from the first letter (e.g., "M" from "MB")
68
+ unit = suffix[0].upper()
69
+ if unit == "B":
70
+ return int(n)
71
+ if unit == "K":
72
+ return int(n * 1024)
73
+ if unit == "M":
74
+ return int(n * 1024 * 1024)
75
+ if unit == "G":
76
+ return int(n * 1024 * 1024 * 1024)
77
+ if unit == "T":
78
+ return int(n * 1024**4)
79
+ if unit == "P":
80
+ return int(n * 1024**5)
81
+ raise ValueError(f"Invalid size suffix: {suffix}")
82
82
 
83
83
 
84
84
  class SizeSuffix:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.1.8
3
+ Version: 1.1.10
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
@@ -8,6 +8,7 @@ clean
8
8
  install
9
9
  lint
10
10
  pyproject.toml
11
+ rclone-mounted-ranged-download.conf.old3393025366
11
12
  requirements.testing.txt
12
13
  setup.py
13
14
  test
@@ -10,12 +10,17 @@ from rclone_api import SizeSuffix
10
10
  class RcloneSuffixSize(unittest.TestCase):
11
11
  """Test rclone functionality."""
12
12
 
13
- def test_list_remotes(self) -> None:
13
+ def test_simple_suffix(self) -> None:
14
14
  size_suffix = SizeSuffix(1024)
15
15
  size_suffix = SizeSuffix("16MB")
16
16
  size_int = size_suffix.as_int()
17
17
  self.assertEqual(size_int, 16 * 1024 * 1024)
18
18
 
19
+ def test_float_suffix(self) -> None:
20
+ size_suffix = SizeSuffix("16.5MB")
21
+ size_int = size_suffix.as_int()
22
+ self.assertEqual(size_int, int(16.5 * 1024 * 1024))
23
+
19
24
 
20
25
  if __name__ == "__main__":
21
26
  unittest.main()
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