rclone-api 1.1.44__tar.gz → 1.1.46__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.1.44 → rclone_api-1.1.46}/PKG-INFO +1 -1
  2. {rclone_api-1.1.44 → rclone_api-1.1.46}/pyproject.toml +1 -1
  3. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/mount.py +20 -1
  4. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/profile/mount_copy_bytes.py +15 -5
  5. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/rclone.py +50 -28
  6. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api.egg-info/PKG-INFO +1 -1
  7. {rclone_api-1.1.44 → rclone_api-1.1.46}/.aiderignore +0 -0
  8. {rclone_api-1.1.44 → rclone_api-1.1.46}/.github/workflows/lint.yml +0 -0
  9. {rclone_api-1.1.44 → rclone_api-1.1.46}/.github/workflows/push_macos.yml +0 -0
  10. {rclone_api-1.1.44 → rclone_api-1.1.46}/.github/workflows/push_ubuntu.yml +0 -0
  11. {rclone_api-1.1.44 → rclone_api-1.1.46}/.github/workflows/push_win.yml +0 -0
  12. {rclone_api-1.1.44 → rclone_api-1.1.46}/.gitignore +0 -0
  13. {rclone_api-1.1.44 → rclone_api-1.1.46}/.pylintrc +0 -0
  14. {rclone_api-1.1.44 → rclone_api-1.1.46}/.vscode/launch.json +0 -0
  15. {rclone_api-1.1.44 → rclone_api-1.1.46}/.vscode/settings.json +0 -0
  16. {rclone_api-1.1.44 → rclone_api-1.1.46}/.vscode/tasks.json +0 -0
  17. {rclone_api-1.1.44 → rclone_api-1.1.46}/LICENSE +0 -0
  18. {rclone_api-1.1.44 → rclone_api-1.1.46}/MANIFEST.in +0 -0
  19. {rclone_api-1.1.44 → rclone_api-1.1.46}/README.md +0 -0
  20. {rclone_api-1.1.44 → rclone_api-1.1.46}/clean +0 -0
  21. {rclone_api-1.1.44 → rclone_api-1.1.46}/install +0 -0
  22. {rclone_api-1.1.44 → rclone_api-1.1.46}/lint +0 -0
  23. {rclone_api-1.1.44 → rclone_api-1.1.46}/requirements.testing.txt +0 -0
  24. {rclone_api-1.1.44 → rclone_api-1.1.46}/setup.cfg +0 -0
  25. {rclone_api-1.1.44 → rclone_api-1.1.46}/setup.py +0 -0
  26. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/__init__.py +0 -0
  27. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/assets/example.txt +0 -0
  28. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/cli.py +0 -0
  29. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/cmd/copy_large_s3.py +0 -0
  30. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/cmd/list_files.py +0 -0
  31. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/completed_process.py +0 -0
  32. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/config.py +0 -0
  33. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/convert.py +0 -0
  34. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/deprecated.py +0 -0
  35. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/diff.py +0 -0
  36. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/dir.py +0 -0
  37. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/dir_listing.py +0 -0
  38. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/exec.py +0 -0
  39. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/experimental/flags.py +0 -0
  40. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/experimental/flags_base.py +0 -0
  41. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/file.py +0 -0
  42. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/filelist.py +0 -0
  43. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/group_files.py +0 -0
  44. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/process.py +0 -0
  45. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/remote.py +0 -0
  46. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/rpath.py +0 -0
  47. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/s3/api.py +0 -0
  48. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/s3/basic_ops.py +0 -0
  49. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/s3/chunk_file.py +0 -0
  50. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/s3/chunk_types.py +0 -0
  51. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/s3/create.py +0 -0
  52. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/s3/types.py +0 -0
  53. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/s3/upload_file_multipart.py +0 -0
  54. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/scan_missing_folders.py +0 -0
  55. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/types.py +0 -0
  56. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/util.py +0 -0
  57. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api/walk.py +0 -0
  58. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api.egg-info/SOURCES.txt +0 -0
  59. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  60. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api.egg-info/entry_points.txt +0 -0
  61. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api.egg-info/requires.txt +0 -0
  62. {rclone_api-1.1.44 → rclone_api-1.1.46}/src/rclone_api.egg-info/top_level.txt +0 -0
  63. {rclone_api-1.1.44 → rclone_api-1.1.46}/test +0 -0
  64. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/archive/test_paramiko.py.disabled +0 -0
  65. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_cmd_list_files.py +0 -0
  66. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_copy.py +0 -0
  67. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_copy_bytes.py +0 -0
  68. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_copy_file_resumable_s3.py +0 -0
  69. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_copy_files.py +0 -0
  70. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_diff.py +0 -0
  71. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_group_files.py +0 -0
  72. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_is_synced.py +0 -0
  73. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_ls.py +0 -0
  74. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_mount.py +0 -0
  75. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_mount_s3.py +0 -0
  76. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_obscure.py +0 -0
  77. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_rclone_config.py +0 -0
  78. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_remote_control.py +0 -0
  79. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_remotes.py +0 -0
  80. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_s3.py +0 -0
  81. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_scan_missing_folders.py +0 -0
  82. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_size_files.py +0 -0
  83. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_size_suffix.py +0 -0
  84. {rclone_api-1.1.44 → rclone_api-1.1.46}/tests/test_walk.py +0 -0
  85. {rclone_api-1.1.44 → rclone_api-1.1.46}/tox.ini +0 -0
  86. {rclone_api-1.1.44 → rclone_api-1.1.46}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.1.44
3
+ Version: 1.1.46
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.1.44"
26
+ version = "1.1.46"
27
27
 
28
28
  [tool.setuptools]
29
29
  package-dir = {"" = "src"}
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import platform
3
+ import shutil
3
4
  import subprocess
4
5
  import time
5
6
  import warnings
@@ -19,6 +20,8 @@ class Mount:
19
20
  mount_path: Path
20
21
  process: Process
21
22
  read_only: bool
23
+ cache_dir: Path | None = None
24
+ cache_dir_delete_on_exit: bool | None = None
22
25
  _closed: bool = False
23
26
 
24
27
  def __post_init__(self):
@@ -31,7 +34,15 @@ class Mount:
31
34
  if self._closed:
32
35
  return
33
36
  self._closed = True
34
- clean_mount(self, verbose=False)
37
+ clean_mount(self, verbose=False, wait=wait)
38
+ if self.cache_dir and self.cache_dir_delete_on_exit:
39
+ _cache_dir_delete_on_exit(self.cache_dir)
40
+
41
+ def __enter__(self) -> "Mount":
42
+ return self
43
+
44
+ def __exit__(self, exc_type, exc_value, traceback) -> None:
45
+ self.close(wait=True)
35
46
 
36
47
  def __del__(self):
37
48
  self.close(wait=False)
@@ -173,3 +184,11 @@ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
173
184
  else:
174
185
  if verbose:
175
186
  print(f"{mount_path} successfully cleaned up.")
187
+
188
+
189
+ def _cache_dir_delete_on_exit(cache_dir: Path) -> None:
190
+ if cache_dir.exists():
191
+ try:
192
+ shutil.rmtree(cache_dir)
193
+ except Exception as e:
194
+ warnings.warn(f"Error removing cache directory {cache_dir}: {e}")
@@ -3,6 +3,7 @@ Unit test file.
3
3
  """
4
4
 
5
5
  import os
6
+ import shutil
6
7
  import time
7
8
  from dataclasses import dataclass
8
9
  from pathlib import Path
@@ -103,10 +104,11 @@ def _init() -> None:
103
104
  os.environ["RCLONE_API_VERBOSE"] = "1"
104
105
 
105
106
 
106
- def _run_profile(rclone: Rclone, src_file: str, transfers: int, size: int) -> None:
107
- mount_log = (
108
- Path("logs") / "mount" / f"mount_{SizeSuffix(size)}_threads_{transfers}.log"
109
- )
107
+ def _run_profile(
108
+ rclone: Rclone, src_file: str, transfers: int, size: int, log_dir: Path
109
+ ) -> None:
110
+
111
+ mount_log = log_dir / f"mount_{SizeSuffix(size)}_threads_{transfers}.log"
110
112
  print("\n\n")
111
113
  print("#" * 80)
112
114
  print(f"# Started test download of {SizeSuffix(size)} with {transfers} transfers")
@@ -177,10 +179,18 @@ def test_profile_copy_bytes() -> None:
177
179
  # sftp mount
178
180
  src_file = "src:aa_misc_data/aa_misc_data/world_lending_library_2024_11.tar.zst"
179
181
 
182
+ mount_root_path = Path("logs") / "mount"
183
+ if mount_root_path.exists():
184
+ shutil.rmtree(mount_root_path)
185
+
180
186
  for size in sizes:
181
187
  for transfers in transfer_list:
182
188
  _run_profile(
183
- rclone=rclone, src_file=src_file, transfers=transfers, size=size
189
+ rclone=rclone,
190
+ src_file=src_file,
191
+ transfers=transfers,
192
+ size=size,
193
+ log_dir=mount_root_path,
184
194
  )
185
195
  print("done")
186
196
 
@@ -852,30 +852,35 @@ class Rclone:
852
852
  if direct_io:
853
853
  other_args += ["--direct-io"]
854
854
 
855
- try:
856
- # use scoped mount to do the read, then write the bytes to the destination
857
- with self.scoped_mount(
858
- src_parent_path,
859
- tmp_mnt,
860
- use_links=True,
861
- verbose=mount_log is not None,
862
- vfs_cache_mode="minimal",
863
- other_args=other_args,
864
- log=mount_log,
865
- ):
866
- src_file_mnt = tmp_mnt / src_file
867
- with open(src_file_mnt, "rb") as f:
868
- f.seek(offset)
869
- data = f.read(length)
870
- if outfile is None:
871
- return data
872
- with open(outfile, "wb") as out:
873
- out.write(data)
874
- del data
875
- return bytes(0)
876
-
877
- except Exception as e:
878
- return e
855
+ with TemporaryDirectory() as tmpdir:
856
+ cache_dir = Path(tmpdir) / "cache"
857
+ other_args += ["--cache-dir", str(cache_dir.absolute())]
858
+ try:
859
+ # use scoped mount to do the read, then write the bytes to the destination
860
+ with self.scoped_mount(
861
+ src_parent_path,
862
+ tmp_mnt,
863
+ use_links=True,
864
+ verbose=mount_log is not None,
865
+ vfs_cache_mode="minimal",
866
+ other_args=other_args,
867
+ log=mount_log,
868
+ cache_dir=cache_dir,
869
+ cache_dir_delete_on_exit=True,
870
+ ):
871
+ src_file_mnt = tmp_mnt / src_file
872
+ with open(src_file_mnt, "rb") as f:
873
+ f.seek(offset)
874
+ data = f.read(length)
875
+ if outfile is None:
876
+ return data
877
+ with open(outfile, "wb") as out:
878
+ out.write(data)
879
+ del data
880
+ return bytes(0)
881
+
882
+ except Exception as e:
883
+ return e
879
884
 
880
885
  def copy_dir(
881
886
  self, src: str | Dir, dst: str | Dir, args: list[str] | None = None
@@ -909,6 +914,8 @@ class Rclone:
909
914
  use_links: bool | None = None,
910
915
  vfs_cache_mode: str | None = None,
911
916
  verbose: bool | None = None,
917
+ cache_dir: Path | None = None,
918
+ cache_dir_delete_on_exit: bool | None = None,
912
919
  log: Path | None = None,
913
920
  other_args: list[str] | None = None,
914
921
  ) -> Mount:
@@ -931,6 +938,7 @@ class Rclone:
931
938
  vfs_cache_mode = vfs_cache_mode or "full"
932
939
  clean_mount(outdir, verbose=verbose)
933
940
  prepare_mount(outdir, verbose=verbose)
941
+ debug_fuse = log is not None
934
942
  src_str = convert_to_str(src)
935
943
  cmd_list: list[str] = ["mount", src_str, str(outdir)]
936
944
  if not allow_writes:
@@ -940,13 +948,24 @@ class Rclone:
940
948
  if vfs_cache_mode:
941
949
  cmd_list.append("--vfs-cache-mode")
942
950
  cmd_list.append(vfs_cache_mode)
951
+ if cache_dir:
952
+ cmd_list.append("--cache-dir")
953
+ cmd_list.append(str(cache_dir.absolute()))
954
+ if debug_fuse:
955
+ cmd_list.append("--debug-fuse")
943
956
  if verbose:
944
957
  cmd_list.append("-vvvv")
945
958
  if other_args:
946
959
  cmd_list += other_args
947
960
  proc = self._launch_process(cmd_list, log=log)
948
- mount_read_only = "--read-only" in cmd_list # hint to allow fast teardown
949
- mount: Mount = Mount(mount_path=outdir, process=proc, read_only=mount_read_only)
961
+ mount_read_only = not allow_writes
962
+ mount: Mount = Mount(
963
+ mount_path=outdir,
964
+ process=proc,
965
+ read_only=mount_read_only,
966
+ cache_dir=cache_dir,
967
+ cache_dir_delete_on_exit=cache_dir_delete_on_exit,
968
+ )
950
969
  return mount
951
970
 
952
971
  @contextmanager
@@ -959,11 +978,12 @@ class Rclone:
959
978
  vfs_cache_mode: str | None = None,
960
979
  verbose: bool | None = None,
961
980
  log: Path | None = None,
981
+ cache_dir: Path | None = None,
982
+ cache_dir_delete_on_exit: bool | None = None,
962
983
  other_args: list[str] | None = None,
963
984
  ) -> Generator[Mount, None, None]:
964
985
  """Like mount, but can be used in a context manager."""
965
986
  error_happened = False
966
- verbose = get_verbose(verbose)
967
987
  mount: Mount = self.mount(
968
988
  src,
969
989
  outdir,
@@ -971,6 +991,8 @@ class Rclone:
971
991
  use_links=use_links,
972
992
  vfs_cache_mode=vfs_cache_mode,
973
993
  verbose=verbose,
994
+ cache_dir=cache_dir,
995
+ cache_dir_delete_on_exit=cache_dir_delete_on_exit,
974
996
  log=log,
975
997
  other_args=other_args,
976
998
  )
@@ -982,7 +1004,7 @@ class Rclone:
982
1004
  warnings.warn(f"Error in scoped_mount: {e}\n\nStack Trace:\n{stack_trace}")
983
1005
  raise
984
1006
  finally:
985
- if not error_happened:
1007
+ if not error_happened or (not allow_writes):
986
1008
  mount.close()
987
1009
 
988
1010
  # Settings optimized for s3.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.1.44
3
+ Version: 1.1.46
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