rclone-api 1.1.42__tar.gz → 1.1.44__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.
- {rclone_api-1.1.42 → rclone_api-1.1.44}/PKG-INFO +1 -1
- {rclone_api-1.1.42 → rclone_api-1.1.44}/pyproject.toml +1 -1
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/rclone.py +9 -2
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/s3/chunk_file.py +12 -1
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/s3/upload_file_multipart.py +27 -17
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api.egg-info/PKG-INFO +1 -1
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.aiderignore +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.github/workflows/lint.yml +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.github/workflows/push_macos.yml +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.github/workflows/push_ubuntu.yml +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.github/workflows/push_win.yml +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.gitignore +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.pylintrc +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.vscode/launch.json +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.vscode/settings.json +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/.vscode/tasks.json +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/LICENSE +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/MANIFEST.in +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/README.md +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/clean +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/install +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/lint +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/requirements.testing.txt +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/setup.cfg +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/setup.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/__init__.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/assets/example.txt +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/cli.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/cmd/copy_large_s3.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/cmd/list_files.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/completed_process.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/config.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/convert.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/deprecated.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/diff.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/dir.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/dir_listing.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/exec.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/experimental/flags.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/experimental/flags_base.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/file.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/filelist.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/group_files.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/mount.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/process.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/profile/mount_copy_bytes.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/remote.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/rpath.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/s3/api.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/s3/basic_ops.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/s3/chunk_types.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/s3/create.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/s3/types.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/scan_missing_folders.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/types.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/util.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api/walk.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api.egg-info/SOURCES.txt +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api.egg-info/dependency_links.txt +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api.egg-info/entry_points.txt +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api.egg-info/requires.txt +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/src/rclone_api.egg-info/top_level.txt +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/test +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/archive/test_paramiko.py.disabled +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_cmd_list_files.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_copy.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_copy_bytes.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_copy_file_resumable_s3.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_copy_files.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_diff.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_group_files.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_is_synced.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_ls.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_mount.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_mount_s3.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_obscure.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_rclone_config.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_remote_control.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_remotes.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_s3.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_scan_missing_folders.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_size_files.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_size_suffix.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tests/test_walk.py +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/tox.ini +0 -0
- {rclone_api-1.1.42 → rclone_api-1.1.44}/upload_package.sh +0 -0
|
@@ -832,15 +832,22 @@ class Rclone:
|
|
|
832
832
|
tmp_mnt = Path("tmp_mnt") / random_str(12)
|
|
833
833
|
src_parent_path = Path(src).parent.as_posix()
|
|
834
834
|
src_file = Path(src).name
|
|
835
|
-
other_args: list[str] = [
|
|
835
|
+
other_args: list[str] = [
|
|
836
|
+
"--no-modtime",
|
|
837
|
+
# "--vfs-read-wait", "1s"
|
|
838
|
+
]
|
|
836
839
|
vfs_read_chunk_size = SizeSuffix(length // transfers)
|
|
837
840
|
vfs_read_chunk_size_limit = SizeSuffix(length)
|
|
838
841
|
vfs_read_chunk_streams = transfers
|
|
839
842
|
vfs_disk_space_total_size = SizeSuffix(length)
|
|
843
|
+
# --max-read-ahead SizeSuffix
|
|
844
|
+
max_read_ahead = SizeSuffix(vfs_read_chunk_size.as_int())
|
|
845
|
+
|
|
840
846
|
other_args += ["--vfs-read-chunk-size", str(vfs_read_chunk_size)]
|
|
841
847
|
other_args += ["--vfs-read-chunk-size-limit", str(vfs_read_chunk_size_limit)]
|
|
842
848
|
other_args += ["--vfs-read-chunk-streams", str(vfs_read_chunk_streams)]
|
|
843
849
|
other_args += ["--vfs-disk-space-total-size", str(vfs_disk_space_total_size)]
|
|
850
|
+
other_args += ["--max-read-ahead", str(max_read_ahead)]
|
|
844
851
|
other_args += ["--read-only"]
|
|
845
852
|
if direct_io:
|
|
846
853
|
other_args += ["--direct-io"]
|
|
@@ -920,7 +927,7 @@ class Rclone:
|
|
|
920
927
|
|
|
921
928
|
allow_writes = allow_writes or False
|
|
922
929
|
use_links = use_links or True
|
|
923
|
-
verbose = get_verbose(verbose)
|
|
930
|
+
verbose = get_verbose(verbose) or (log is not None)
|
|
924
931
|
vfs_cache_mode = vfs_cache_mode or "full"
|
|
925
932
|
clean_mount(outdir, verbose=verbose)
|
|
926
933
|
prepare_mount(outdir, verbose=verbose)
|
|
@@ -2,6 +2,7 @@ import time
|
|
|
2
2
|
import warnings
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from queue import Queue
|
|
5
|
+
from threading import Event
|
|
5
6
|
|
|
6
7
|
from rclone_api.s3.chunk_types import FileChunk, UploadState
|
|
7
8
|
from rclone_api.util import locked_print
|
|
@@ -25,12 +26,16 @@ def _get_file_size(file_path: Path, timeout: int = 60) -> int:
|
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def file_chunker(
|
|
28
|
-
upload_state: UploadState,
|
|
29
|
+
upload_state: UploadState,
|
|
30
|
+
max_chunks: int | None,
|
|
31
|
+
cancel_signal: Event,
|
|
32
|
+
output: Queue[FileChunk | None],
|
|
29
33
|
) -> None:
|
|
30
34
|
count = 0
|
|
31
35
|
|
|
32
36
|
def should_stop() -> bool:
|
|
33
37
|
nonlocal count
|
|
38
|
+
|
|
34
39
|
if max_chunks is None:
|
|
35
40
|
return False
|
|
36
41
|
if count >= max_chunks:
|
|
@@ -68,6 +73,12 @@ def file_chunker(
|
|
|
68
73
|
return None
|
|
69
74
|
return part_number
|
|
70
75
|
|
|
76
|
+
if cancel_signal.is_set():
|
|
77
|
+
print(
|
|
78
|
+
f"Cancel signal is set for file chunker while processing {file_path}, returning"
|
|
79
|
+
)
|
|
80
|
+
return
|
|
81
|
+
|
|
71
82
|
while not should_stop():
|
|
72
83
|
curr_parth_num = next_part_number()
|
|
73
84
|
if curr_parth_num is None:
|
|
@@ -5,7 +5,7 @@ import warnings
|
|
|
5
5
|
from concurrent.futures import ThreadPoolExecutor
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from queue import Queue
|
|
8
|
-
from threading import Thread
|
|
8
|
+
from threading import Event, Thread
|
|
9
9
|
|
|
10
10
|
from botocore.client import BaseClient
|
|
11
11
|
|
|
@@ -207,16 +207,21 @@ def upload_file_multipart(
|
|
|
207
207
|
upload_info = upload_state.upload_info
|
|
208
208
|
|
|
209
209
|
chunker_errors: Queue[Exception] = Queue()
|
|
210
|
+
cancel_chunker_event = Event()
|
|
210
211
|
|
|
211
212
|
def chunker_task(
|
|
212
213
|
upload_state=upload_state,
|
|
213
214
|
output=filechunks,
|
|
214
215
|
max_chunks=max_chunks_before_suspension,
|
|
216
|
+
cancel_signal=cancel_chunker_event,
|
|
215
217
|
queue_errors=chunker_errors,
|
|
216
218
|
) -> None:
|
|
217
219
|
try:
|
|
218
220
|
file_chunker(
|
|
219
|
-
upload_state=upload_state,
|
|
221
|
+
upload_state=upload_state,
|
|
222
|
+
output=output,
|
|
223
|
+
max_chunks=max_chunks,
|
|
224
|
+
cancel_signal=cancel_signal,
|
|
220
225
|
)
|
|
221
226
|
except Exception as e:
|
|
222
227
|
queue_errors.put(e)
|
|
@@ -228,25 +233,30 @@ def upload_file_multipart(
|
|
|
228
233
|
thread_chunker.start()
|
|
229
234
|
|
|
230
235
|
with ThreadPoolExecutor(max_workers=upload_threads) as executor:
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
try:
|
|
237
|
+
while True:
|
|
238
|
+
file_chunk: FileChunk | None = filechunks.get()
|
|
239
|
+
if file_chunk is None:
|
|
240
|
+
break
|
|
235
241
|
|
|
236
|
-
|
|
237
|
-
|
|
242
|
+
def task(upload_info=upload_info, file_chunk=file_chunk):
|
|
243
|
+
return handle_upload(upload_info, file_chunk)
|
|
238
244
|
|
|
239
|
-
|
|
245
|
+
fut = executor.submit(task)
|
|
240
246
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
def done_cb(fut=fut):
|
|
248
|
+
result = fut.result()
|
|
249
|
+
if isinstance(result, Exception):
|
|
250
|
+
warnings.warn(f"Error uploading part: {result}, skipping")
|
|
251
|
+
return
|
|
252
|
+
# upload_state.finished_parts.put(result)
|
|
253
|
+
upload_state.add_finished(result)
|
|
248
254
|
|
|
249
|
-
|
|
255
|
+
fut.add_done_callback(done_cb)
|
|
256
|
+
except Exception:
|
|
257
|
+
cancel_chunker_event.set()
|
|
258
|
+
executor.shutdown(wait=False, cancel_futures=True)
|
|
259
|
+
raise
|
|
250
260
|
# upload_state.finished_parts.put(None) # Signal the end of the queue
|
|
251
261
|
upload_state.add_finished(None)
|
|
252
262
|
thread_chunker.join()
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|