rclone-api 1.4.3__tar.gz → 1.4.4__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.4.3 → rclone_api-1.4.4}/PKG-INFO +1 -1
- {rclone_api-1.4.3 → rclone_api-1.4.4}/pyproject.toml +1 -1
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/detail/copy_file_parts.py +56 -48
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api.egg-info/PKG-INFO +1 -1
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.aiderignore +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.github/workflows/lint.yml +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.github/workflows/push_macos.yml +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.github/workflows/push_ubuntu.yml +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.github/workflows/push_win.yml +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.gitignore +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.pylintrc +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.vscode/launch.json +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.vscode/settings.json +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/.vscode/tasks.json +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/LICENSE +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/MANIFEST.in +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/README.md +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/clean +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/install +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/lint +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/requirements.testing.txt +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/setup.cfg +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/setup.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/__init__.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/assets/example.txt +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/cli.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/cmd/analyze.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/cmd/copy_large_s3.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/cmd/list_files.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/cmd/save_to_db.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/completed_process.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/config.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/convert.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/db/__init__.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/db/db.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/db/models.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/deprecated.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/detail/walk.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/diff.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/dir.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/dir_listing.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/exec.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/experimental/flags.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/experimental/flags_base.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/file.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/file_item.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/file_part.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/file_stream.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/filelist.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/group_files.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/http_server.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/log.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/mount.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/process.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/rclone_impl.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/remote.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/rpath.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/api.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/basic_ops.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/chunk_task.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/create.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/multipart/file_info.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/multipart/finished_piece.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/multipart/upload_info.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/multipart/upload_state.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/s3_multipart_uploader.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/types.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/s3/upload_file_multipart.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/scan_missing_folders.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/types.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api/util.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api.egg-info/SOURCES.txt +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api.egg-info/dependency_links.txt +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api.egg-info/entry_points.txt +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api.egg-info/requires.txt +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/src/rclone_api.egg-info/top_level.txt +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/test +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/archive/test_paramiko.py.disabled +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_cmd_list_files.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_copy.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_copy_bytes.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_copy_file_resumable_s3.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_copy_files.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_db.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_diff.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_file_item.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_group_files.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_is_synced.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_ls.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_ls_stream_files.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_mount.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_mount_s3.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_obscure.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_rclone_config.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_read_write_text.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_remote_control.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_remotes.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_s3.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_scan_missing_folders.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_serve_http.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_size_files.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_size_suffix.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tests/test_walk.py +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/tox.ini +0 -0
- {rclone_api-1.4.3 → rclone_api-1.4.4}/upload_package.sh +0 -0
@@ -8,7 +8,6 @@ from concurrent.futures import Future, ThreadPoolExecutor
|
|
8
8
|
from dataclasses import dataclass
|
9
9
|
from datetime import datetime
|
10
10
|
from pathlib import Path
|
11
|
-
from tempfile import TemporaryDirectory
|
12
11
|
|
13
12
|
from rclone_api.dir_listing import DirListing
|
14
13
|
from rclone_api.http_server import HttpServer
|
@@ -249,6 +248,8 @@ def copy_file_parts(
|
|
249
248
|
threads: int = 1,
|
250
249
|
) -> Exception | None:
|
251
250
|
"""Copy parts of a file from source to destination."""
|
251
|
+
from rclone_api.util import random_str
|
252
|
+
|
252
253
|
if dst_dir.endswith("/"):
|
253
254
|
dst_dir = dst_dir[:-1]
|
254
255
|
src_size = self.size_file(src)
|
@@ -311,65 +312,72 @@ def copy_file_parts(
|
|
311
312
|
print(info_json)
|
312
313
|
|
313
314
|
finished_tasks: list[UploadPart] = []
|
315
|
+
tmp_dir = str(Path("chunks") / random_str(12))
|
316
|
+
import atexit
|
317
|
+
import shutil
|
318
|
+
|
319
|
+
atexit.register(lambda: shutil.rmtree(tmp_dir, ignore_errors=True))
|
314
320
|
|
315
321
|
with self.serve_http(src_dir) as http_server:
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
with ThreadPoolExecutor(max_workers=threads) as
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
322
|
+
tmpdir: Path = Path(tmp_dir)
|
323
|
+
write_semaphore = threading.Semaphore(threads)
|
324
|
+
with ThreadPoolExecutor(max_workers=threads) as upload_executor:
|
325
|
+
with ThreadPoolExecutor(max_workers=threads) as read_executor:
|
326
|
+
for part_info in part_infos:
|
327
|
+
part_number: int = part_info.part_number
|
328
|
+
range: Range = part_info.range
|
329
|
+
offset: SizeSuffix = SizeSuffix(range.start)
|
330
|
+
length: SizeSuffix = SizeSuffix(range.end - range.start)
|
331
|
+
end = offset + length
|
332
|
+
suffix = _gen_name(part_number, offset, end)
|
333
|
+
part_dst = f"{dst_dir}/{suffix}"
|
334
|
+
|
335
|
+
def _read_task(
|
336
|
+
src_name=src_name,
|
337
|
+
http_server=http_server,
|
338
|
+
tmpdir=tmpdir,
|
339
|
+
offset=offset,
|
340
|
+
length=length,
|
341
|
+
part_dst=part_dst,
|
342
|
+
) -> UploadPart:
|
343
|
+
return read_task(
|
331
344
|
src_name=src_name,
|
332
345
|
http_server=http_server,
|
333
346
|
tmpdir=tmpdir,
|
334
347
|
offset=offset,
|
335
348
|
length=length,
|
336
349
|
part_dst=part_dst,
|
337
|
-
)
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
#
|
350
|
-
|
351
|
-
|
352
|
-
)
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
upload_fut.add_done_callback(
|
362
|
-
lambda fut: finished_tasks.append(fut.result())
|
363
|
-
)
|
364
|
-
|
365
|
-
read_fut.add_done_callback(queue_upload_task)
|
366
|
-
# SEMAPHORE ACQUIRE!!!
|
367
|
-
# If we are back filled on the writers, then we stall.
|
368
|
-
write_semaphore.acquire()
|
350
|
+
)
|
351
|
+
|
352
|
+
read_fut: Future[UploadPart] = read_executor.submit(_read_task)
|
353
|
+
|
354
|
+
# Releases the semaphore when the write task is done
|
355
|
+
def queue_upload_task(
|
356
|
+
read_fut=read_fut,
|
357
|
+
) -> None:
|
358
|
+
upload_part = read_fut.result()
|
359
|
+
upload_fut: Future[UploadPart] = upload_executor.submit(
|
360
|
+
upload_task, self, upload_part
|
361
|
+
)
|
362
|
+
# SEMAPHORE RELEASE!!!
|
363
|
+
upload_fut.add_done_callback(
|
364
|
+
lambda _: write_semaphore.release()
|
365
|
+
)
|
366
|
+
upload_fut.add_done_callback(
|
367
|
+
lambda fut: finished_tasks.append(fut.result())
|
368
|
+
)
|
369
|
+
|
370
|
+
read_fut.add_done_callback(queue_upload_task)
|
371
|
+
# SEMAPHORE ACQUIRE!!!
|
372
|
+
# If we are back filled on the writers, then we stall.
|
373
|
+
write_semaphore.acquire()
|
369
374
|
|
370
375
|
exceptions: list[Exception] = [
|
371
376
|
t.exception for t in finished_tasks if t.exception is not None
|
372
377
|
]
|
378
|
+
|
379
|
+
shutil.rmtree(tmp_dir, ignore_errors=True)
|
380
|
+
|
373
381
|
if len(exceptions) > 0:
|
374
382
|
return Exception(f"Failed to copy parts: {exceptions}", exceptions)
|
375
383
|
|
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
|
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
|