rclone-api 1.5.6__tar.gz → 1.5.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 (112) hide show
  1. {rclone_api-1.5.6 → rclone_api-1.5.7}/PKG-INFO +1 -1
  2. {rclone_api-1.5.6 → rclone_api-1.5.7}/pyproject.toml +1 -1
  3. rclone_api-1.5.7/src/rclone_api/mount.py +55 -0
  4. rclone_api-1.5.6/src/rclone_api/mount.py → rclone_api-1.5.7/src/rclone_api/mount_util.py +57 -97
  5. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/rclone_impl.py +2 -1
  6. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api.egg-info/PKG-INFO +1 -1
  7. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api.egg-info/SOURCES.txt +1 -0
  8. {rclone_api-1.5.6 → rclone_api-1.5.7}/.aiderignore +0 -0
  9. {rclone_api-1.5.6 → rclone_api-1.5.7}/.github/workflows/lint.yml +0 -0
  10. {rclone_api-1.5.6 → rclone_api-1.5.7}/.github/workflows/push_macos.yml +0 -0
  11. {rclone_api-1.5.6 → rclone_api-1.5.7}/.github/workflows/push_ubuntu.yml +0 -0
  12. {rclone_api-1.5.6 → rclone_api-1.5.7}/.github/workflows/push_win.yml +0 -0
  13. {rclone_api-1.5.6 → rclone_api-1.5.7}/.gitignore +0 -0
  14. {rclone_api-1.5.6 → rclone_api-1.5.7}/.pylintrc +0 -0
  15. {rclone_api-1.5.6 → rclone_api-1.5.7}/.vscode/launch.json +0 -0
  16. {rclone_api-1.5.6 → rclone_api-1.5.7}/.vscode/settings.json +0 -0
  17. {rclone_api-1.5.6 → rclone_api-1.5.7}/.vscode/tasks.json +0 -0
  18. {rclone_api-1.5.6 → rclone_api-1.5.7}/LICENSE +0 -0
  19. {rclone_api-1.5.6 → rclone_api-1.5.7}/MANIFEST.in +0 -0
  20. {rclone_api-1.5.6 → rclone_api-1.5.7}/README.md +0 -0
  21. {rclone_api-1.5.6 → rclone_api-1.5.7}/clean +0 -0
  22. {rclone_api-1.5.6 → rclone_api-1.5.7}/install +0 -0
  23. {rclone_api-1.5.6 → rclone_api-1.5.7}/lint +0 -0
  24. {rclone_api-1.5.6 → rclone_api-1.5.7}/requirements.testing.txt +0 -0
  25. {rclone_api-1.5.6 → rclone_api-1.5.7}/setup.cfg +0 -0
  26. {rclone_api-1.5.6 → rclone_api-1.5.7}/setup.py +0 -0
  27. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/__init__.py +0 -0
  28. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/assets/example.txt +0 -0
  29. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/cli.py +0 -0
  30. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/cmd/analyze.py +0 -0
  31. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/cmd/copy_large_s3.py +0 -0
  32. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/cmd/copy_large_s3_finish.py +0 -0
  33. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/cmd/list_files.py +0 -0
  34. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/cmd/save_to_db.py +0 -0
  35. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/completed_process.py +0 -0
  36. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/config.py +0 -0
  37. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/convert.py +0 -0
  38. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/db/__init__.py +0 -0
  39. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/db/db.py +0 -0
  40. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/db/models.py +0 -0
  41. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/deprecated.py +0 -0
  42. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/detail/copy_file_parts_resumable.py +0 -0
  43. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/detail/walk.py +0 -0
  44. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/diff.py +0 -0
  45. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/dir.py +0 -0
  46. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/dir_listing.py +0 -0
  47. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/exec.py +0 -0
  48. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/experimental/flags.py +0 -0
  49. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/experimental/flags_base.py +0 -0
  50. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/file.py +0 -0
  51. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/file_item.py +0 -0
  52. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/file_part.py +0 -0
  53. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/file_stream.py +0 -0
  54. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/filelist.py +0 -0
  55. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/group_files.py +0 -0
  56. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/http_server.py +0 -0
  57. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/install.py +0 -0
  58. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/log.py +0 -0
  59. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/process.py +0 -0
  60. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/remote.py +0 -0
  61. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/rpath.py +0 -0
  62. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/api.py +0 -0
  63. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/basic_ops.py +0 -0
  64. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/chunk_task.py +0 -0
  65. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/create.py +0 -0
  66. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/file_info.py +0 -0
  67. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/finished_piece.py +0 -0
  68. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/info_json.py +0 -0
  69. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/merge_state.py +0 -0
  70. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/upload_info.py +0 -0
  71. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/upload_parts_inline.py +0 -0
  72. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/upload_parts_resumable.py +0 -0
  73. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/upload_parts_server_side_merge.py +0 -0
  74. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/multipart/upload_state.py +0 -0
  75. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/s3/types.py +0 -0
  76. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/scan_missing_folders.py +0 -0
  77. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/types.py +0 -0
  78. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api/util.py +0 -0
  79. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  80. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api.egg-info/entry_points.txt +0 -0
  81. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api.egg-info/requires.txt +0 -0
  82. {rclone_api-1.5.6 → rclone_api-1.5.7}/src/rclone_api.egg-info/top_level.txt +0 -0
  83. {rclone_api-1.5.6 → rclone_api-1.5.7}/test +0 -0
  84. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/archive/test_paramiko.py.disabled +0 -0
  85. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_cmd_list_files.py +0 -0
  86. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_copy.py +0 -0
  87. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_copy_bytes.py +0 -0
  88. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_copy_file_resumable_s3.py +0 -0
  89. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_copy_files.py +0 -0
  90. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_db.py +0 -0
  91. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_diff.py +0 -0
  92. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_file_item.py +0 -0
  93. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_group_files.py +0 -0
  94. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_install.py +0 -0
  95. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_is_synced.py +0 -0
  96. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_ls.py +0 -0
  97. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_ls_stream_files.py +0 -0
  98. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_mount.py +0 -0
  99. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_mount_s3.py +0 -0
  100. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_obscure.py +0 -0
  101. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_rclone_config.py +0 -0
  102. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_read_write_text.py +0 -0
  103. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_remote_control.py +0 -0
  104. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_remotes.py +0 -0
  105. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_s3.py +0 -0
  106. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_scan_missing_folders.py +0 -0
  107. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_serve_http.py +0 -0
  108. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_size_files.py +0 -0
  109. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_size_suffix.py +0 -0
  110. {rclone_api-1.5.6 → rclone_api-1.5.7}/tests/test_walk.py +0 -0
  111. {rclone_api-1.5.6 → rclone_api-1.5.7}/tox.ini +0 -0
  112. {rclone_api-1.5.6 → rclone_api-1.5.7}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.5.6
3
+ Version: 1.5.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
@@ -27,7 +27,7 @@ dependencies = [
27
27
  ]
28
28
 
29
29
  # Change this with the version number bump.
30
- version = "1.5.6"
30
+ version = "1.5.7"
31
31
 
32
32
  [tool.setuptools]
33
33
  package-dir = {"" = "src"}
@@ -0,0 +1,55 @@
1
+ from dataclasses import dataclass
2
+ from pathlib import Path
3
+
4
+ from rclone_api.process import Process
5
+
6
+
7
+ @dataclass
8
+ class Mount:
9
+ """Mount information."""
10
+
11
+ src: str
12
+ mount_path: Path
13
+ process: Process
14
+ read_only: bool
15
+ cache_dir: Path | None = None
16
+ cache_dir_delete_on_exit: bool | None = None
17
+ _closed: bool = False
18
+
19
+ def __post_init__(self):
20
+ from rclone_api.mount_util import add_mount_for_gc, wait_for_mount
21
+
22
+ assert isinstance(self.mount_path, Path)
23
+ assert self.process is not None
24
+ wait_for_mount(self)
25
+ add_mount_for_gc(self)
26
+
27
+ def close(self, wait=True) -> None:
28
+ """Clean up the mount."""
29
+ from rclone_api.mount_util import (
30
+ cache_dir_delete_on_exit,
31
+ clean_mount,
32
+ remove_mount_for_gc,
33
+ )
34
+
35
+ if self._closed:
36
+ return
37
+ self._closed = True
38
+ self.process.terminate()
39
+ clean_mount(self, verbose=False, wait=wait)
40
+ if self.cache_dir and self.cache_dir_delete_on_exit:
41
+ cache_dir_delete_on_exit(self.cache_dir)
42
+ remove_mount_for_gc(self)
43
+
44
+ def __enter__(self) -> "Mount":
45
+ return self
46
+
47
+ def __exit__(self, exc_type, exc_value, traceback) -> None:
48
+ self.close(wait=True)
49
+
50
+ def __del__(self):
51
+ self.close(wait=False)
52
+
53
+ # make this a hashable object
54
+ def __hash__(self):
55
+ return hash(self.mount_path)
@@ -7,10 +7,9 @@ import time
7
7
  import warnings
8
8
  import weakref
9
9
  from concurrent.futures import ThreadPoolExecutor
10
- from dataclasses import dataclass
11
10
  from pathlib import Path
12
- from typing import Any
13
11
 
12
+ from rclone_api.mount import Mount
14
13
  from rclone_api.process import Process
15
14
 
16
15
  _SYSTEM = platform.system() # "Linux", "Darwin", "Windows", etc.
@@ -18,15 +17,6 @@ _SYSTEM = platform.system() # "Linux", "Darwin", "Windows", etc.
18
17
  _MOUNTS_FOR_GC: weakref.WeakSet = weakref.WeakSet()
19
18
 
20
19
 
21
- def _add_mount_for_gc(mount: "Mount") -> None:
22
- # weak reference to avoid circular references
23
- _MOUNTS_FOR_GC.add(mount)
24
-
25
-
26
- def _remove_mount_for_gc(mount: "Mount") -> None:
27
- _MOUNTS_FOR_GC.discard(mount)
28
-
29
-
30
20
  def _cleanup_mounts() -> None:
31
21
  with ThreadPoolExecutor() as executor:
32
22
  mount: Mount
@@ -34,61 +24,7 @@ def _cleanup_mounts() -> None:
34
24
  executor.submit(mount.close)
35
25
 
36
26
 
37
- def _cache_dir_delete_on_exit(cache_dir: Path) -> None:
38
- if cache_dir.exists():
39
- try:
40
- shutil.rmtree(cache_dir)
41
- except Exception as e:
42
- warnings.warn(f"Error removing cache directory {cache_dir}: {e}")
43
-
44
-
45
- atexit.register(_cleanup_mounts)
46
-
47
-
48
- @dataclass
49
- class Mount:
50
- """Mount information."""
51
-
52
- src: str
53
- mount_path: Path
54
- process: Process
55
- read_only: bool
56
- cache_dir: Path | None = None
57
- cache_dir_delete_on_exit: bool | None = None
58
- _closed: bool = False
59
-
60
- def __post_init__(self):
61
- assert isinstance(self.mount_path, Path)
62
- assert self.process is not None
63
- wait_for_mount(self.mount_path, self.process)
64
- _add_mount_for_gc(self)
65
-
66
- def close(self, wait=True) -> None:
67
- """Clean up the mount."""
68
- if self._closed:
69
- return
70
- self._closed = True
71
- self.process.terminate()
72
- clean_mount(self, verbose=False, wait=wait)
73
- if self.cache_dir and self.cache_dir_delete_on_exit:
74
- _cache_dir_delete_on_exit(self.cache_dir)
75
- _remove_mount_for_gc(self)
76
-
77
- def __enter__(self) -> "Mount":
78
- return self
79
-
80
- def __exit__(self, exc_type, exc_value, traceback) -> None:
81
- self.close(wait=True)
82
-
83
- def __del__(self):
84
- self.close(wait=False)
85
-
86
- # make this a hashable object
87
- def __hash__(self):
88
- return hash(self.mount_path)
89
-
90
-
91
- def run_command(cmd: str, verbose: bool) -> int:
27
+ def _run_command(cmd: str, verbose: bool) -> int:
92
28
  """Run a shell command and print its output if verbose is True."""
93
29
  if verbose:
94
30
  print(f"Executing: {cmd}")
@@ -104,6 +40,26 @@ def run_command(cmd: str, verbose: bool) -> int:
104
40
  return -1
105
41
 
106
42
 
43
+ atexit.register(_cleanup_mounts)
44
+
45
+
46
+ def cache_dir_delete_on_exit(cache_dir: Path) -> None:
47
+ if cache_dir.exists():
48
+ try:
49
+ shutil.rmtree(cache_dir)
50
+ except Exception as e:
51
+ warnings.warn(f"Error removing cache directory {cache_dir}: {e}")
52
+
53
+
54
+ def add_mount_for_gc(mount: Mount) -> None:
55
+ # weak reference to avoid circular references
56
+ _MOUNTS_FOR_GC.add(mount)
57
+
58
+
59
+ def remove_mount_for_gc(mount: Mount) -> None:
60
+ _MOUNTS_FOR_GC.discard(mount)
61
+
62
+
107
63
  def prepare_mount(outdir: Path, verbose: bool) -> None:
108
64
  if _SYSTEM == "Windows":
109
65
  # Windows -> Must create parent directories only if they don't exist
@@ -118,8 +74,7 @@ def prepare_mount(outdir: Path, verbose: bool) -> None:
118
74
 
119
75
 
120
76
  def wait_for_mount(
121
- path: Path,
122
- mount_process: Any,
77
+ mount: Mount,
123
78
  timeout: int = 20,
124
79
  post_mount_delay: int = 5,
125
80
  poll_interval: float = 1.0,
@@ -132,7 +87,7 @@ def wait_for_mount(
132
87
  is still running, and applies an extra delay after detecting content for stabilization.
133
88
 
134
89
  Args:
135
- path (Path): The mount point directory to check.
90
+ src (Path): The mount point directory to check.
136
91
  mount_process (Any): A Process instance handling the mount (must be an instance of Process).
137
92
  timeout (int): Maximum time in seconds to wait for the mount to become available.
138
93
  post_mount_delay (int): Additional seconds to wait after detecting files.
@@ -145,6 +100,9 @@ def wait_for_mount(
145
100
  TypeError: If mount_process is not an instance of Process.
146
101
  """
147
102
 
103
+ mount_process = mount.process
104
+ src = mount.mount_path
105
+
148
106
  if not isinstance(mount_process, Process):
149
107
  raise TypeError("mount_process must be an instance of Process")
150
108
 
@@ -160,40 +118,42 @@ def wait_for_mount(
160
118
  raise subprocess.CalledProcessError(rtn, cmd_str)
161
119
 
162
120
  # Check if the mount path exists.
163
- if path.exists():
121
+ if src.exists():
164
122
  # Optionally check if path is a mount point.
165
123
  if check_mount_flag:
166
124
  try:
167
- if not os.path.ismount(str(path)):
125
+ if not os.path.ismount(str(src)):
168
126
  print(
169
- f"{path} exists but is not recognized as a mount point yet."
127
+ f"{src} exists but is not recognized as a mount point yet."
170
128
  )
171
129
  time.sleep(poll_interval)
172
130
  continue
173
131
  except Exception as e:
174
- print(f"Could not verify mount point status for {path}: {e}")
132
+ print(f"Could not verify mount point status for {src}: {e}")
175
133
 
176
134
  try:
177
135
  # Check for at least one entry in the directory.
178
- if any(path.iterdir()):
136
+ if any(src.iterdir()):
179
137
  print(
180
- f"Mount point {path} appears available with files. Waiting {post_mount_delay} seconds for stabilization."
138
+ f"Mount point {src} appears available with files. Waiting {post_mount_delay} seconds for stabilization."
181
139
  )
182
140
  time.sleep(post_mount_delay)
183
141
  return
184
142
  else:
185
- print(f"Mount point {path} is empty. Waiting for files to appear.")
143
+ print(f"Mount point {src} is empty. Waiting for files to appear.")
186
144
  except Exception as e:
187
145
  last_error = e
188
- print(f"Error accessing {path}: {e}")
146
+ print(f"Error accessing {src}: {e}")
189
147
  else:
190
- print(f"Mount point {path} does not exist yet.")
148
+ print(f"Mount point {src} does not exist yet.")
191
149
 
192
150
  time.sleep(poll_interval)
193
151
 
194
- raise TimeoutError(
195
- f"Mount point {path} did not become available within {timeout} seconds. Last error: {last_error}"
196
- )
152
+ # raise TimeoutError(
153
+ # f"Mount point {src} did not become available within {timeout} seconds. Last error: {last_error}"
154
+ # )
155
+ if last_error is not None:
156
+ raise last_error
197
157
 
198
158
 
199
159
  def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
@@ -205,10 +165,14 @@ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
205
165
  and 'umount'. On macOS it uses 'umount' (and optionally 'diskutil unmount'),
206
166
  while on Windows it attempts to remove the mount point via 'mountvol /D'.
207
167
  """
168
+
169
+ def verbose_print(msg: str):
170
+ if verbose:
171
+ print(msg)
172
+
208
173
  proc = mount.process if isinstance(mount, Mount) else None
209
174
  if proc is not None and proc.poll() is None:
210
- if verbose:
211
- print(f"Terminating mount process {proc.pid}")
175
+ verbose_print(f"Terminating mount process {proc.pid}")
212
176
  proc.kill()
213
177
 
214
178
  # Check if the mount path exists; if an OSError occurs, assume it exists.
@@ -224,26 +188,24 @@ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
224
188
  time.sleep(2)
225
189
 
226
190
  if not mount_exists:
227
- if verbose:
228
- print(f"{mount_path} does not exist; nothing to clean up.")
191
+ verbose_print(f"{mount_path} does not exist; nothing to clean up.")
229
192
  return
230
193
 
231
- if verbose:
232
- print(f"{mount_path} still exists, attempting to unmount and remove.")
194
+ verbose_print(f"{mount_path} still exists, attempting to unmount and remove.")
233
195
 
234
196
  # Platform-specific unmount procedures
235
197
  if _SYSTEM == "Linux":
236
198
  # Try FUSE unmount first (if applicable), then the regular umount.
237
- run_command(f"fusermount -u {mount_path}", verbose)
238
- run_command(f"umount {mount_path}", verbose)
199
+ _run_command(f"fusermount -u {mount_path}", verbose)
200
+ _run_command(f"umount {mount_path}", verbose)
239
201
  elif _SYSTEM == "Darwin":
240
202
  # On macOS, use umount; optionally try diskutil for stubborn mounts.
241
- run_command(f"umount {mount_path}", verbose)
203
+ _run_command(f"umount {mount_path}", verbose)
242
204
  # Optionally: uncomment the next line if diskutil unmount is preferred.
243
- # run_command(f"diskutil unmount {mount_path}", verbose)
205
+ # _run_command(f"diskutil unmount {mount_path}", verbose)
244
206
  elif _SYSTEM == "Windows":
245
207
  # On Windows, remove the mount point using mountvol.
246
- run_command(f"mountvol {mount_path} /D", verbose)
208
+ _run_command(f"mountvol {mount_path} /D", verbose)
247
209
  # If that does not work, try to remove the directory directly.
248
210
  try:
249
211
  mount_path.rmdir()
@@ -267,19 +229,17 @@ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
267
229
  still_exists = True
268
230
 
269
231
  if still_exists:
270
- if verbose:
271
- print(f"{mount_path} still exists after unmount attempt.")
232
+ verbose_print(f"{mount_path} still exists after unmount attempt.")
272
233
  # Attempt to remove the directory if it is empty.
273
234
  try:
274
235
  # Only remove if the directory is empty.
275
236
  if not any(mount_path.iterdir()):
276
237
  mount_path.rmdir()
277
238
  if verbose:
278
- print(f"Removed empty mount directory {mount_path}")
239
+ verbose_print(f"Removed empty mount directory {mount_path}")
279
240
  else:
280
241
  warnings.warn(f"{mount_path} is not empty; cannot remove.")
281
242
  except Exception as e:
282
243
  warnings.warn(f"Failed during cleanup of {mount_path}: {e}")
283
244
  else:
284
- if verbose:
285
- print(f"{mount_path} successfully cleaned up.")
245
+ verbose_print(f"{mount_path} successfully cleaned up.")
@@ -27,7 +27,7 @@ from rclone_api.file import File
27
27
  from rclone_api.file_stream import FilesStream
28
28
  from rclone_api.group_files import group_files
29
29
  from rclone_api.http_server import HttpServer
30
- from rclone_api.mount import Mount, clean_mount, prepare_mount
30
+ from rclone_api.mount import Mount
31
31
  from rclone_api.process import Process
32
32
  from rclone_api.remote import Remote
33
33
  from rclone_api.rpath import RPath
@@ -1017,6 +1017,7 @@ class RcloneImpl:
1017
1017
  Raises:
1018
1018
  subprocess.CalledProcessError: If the mount operation fails
1019
1019
  """
1020
+ from rclone_api.mount_util import clean_mount, prepare_mount
1020
1021
 
1021
1022
  allow_writes = allow_writes or False
1022
1023
  use_links = use_links or True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.5.6
3
+ Version: 1.5.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
@@ -40,6 +40,7 @@ src/rclone_api/http_server.py
40
40
  src/rclone_api/install.py
41
41
  src/rclone_api/log.py
42
42
  src/rclone_api/mount.py
43
+ src/rclone_api/mount_util.py
43
44
  src/rclone_api/process.py
44
45
  src/rclone_api/rclone_impl.py
45
46
  src/rclone_api/remote.py
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
File without changes