rclone-api 1.3.5__py2.py3-none-any.whl → 1.3.7__py2.py3-none-any.whl
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/__init__.py +2 -1
- rclone_api/cmd/copy_large_s3.py +1 -3
- rclone_api/exec.py +1 -1
- rclone_api/file.py +37 -0
- rclone_api/mount_read_chunker.py +8 -2
- rclone_api/process.py +6 -0
- rclone_api/profile/mount_copy_bytes.py +3 -1
- rclone_api/rclone.py +1343 -1276
- rclone_api/s3/upload_file_multipart.py +6 -3
- rclone_api/util.py +183 -162
- {rclone_api-1.3.5.dist-info → rclone_api-1.3.7.dist-info}/METADATA +1 -1
- {rclone_api-1.3.5.dist-info → rclone_api-1.3.7.dist-info}/RECORD +16 -16
- {rclone_api-1.3.5.dist-info → rclone_api-1.3.7.dist-info}/LICENSE +0 -0
- {rclone_api-1.3.5.dist-info → rclone_api-1.3.7.dist-info}/WHEEL +0 -0
- {rclone_api-1.3.5.dist-info → rclone_api-1.3.7.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.3.5.dist-info → rclone_api-1.3.7.dist-info}/top_level.txt +0 -0
rclone_api/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ from .config import Config, Parsed, Section
|
|
|
7
7
|
from .diff import DiffItem, DiffOption, DiffType
|
|
8
8
|
from .dir import Dir
|
|
9
9
|
from .dir_listing import DirListing
|
|
10
|
-
from .file import File
|
|
10
|
+
from .file import File, FileItem
|
|
11
11
|
from .filelist import FileList
|
|
12
12
|
|
|
13
13
|
# Import the configure_logging function to make it available at package level
|
|
@@ -28,6 +28,7 @@ __all__ = [
|
|
|
28
28
|
"RPath",
|
|
29
29
|
"DirListing",
|
|
30
30
|
"FileList",
|
|
31
|
+
"FileItem",
|
|
31
32
|
"Process",
|
|
32
33
|
"DiffItem",
|
|
33
34
|
"DiffType",
|
rclone_api/cmd/copy_large_s3.py
CHANGED
|
@@ -4,8 +4,6 @@ from pathlib import Path
|
|
|
4
4
|
|
|
5
5
|
from rclone_api import MultiUploadResult, Rclone, SizeSuffix
|
|
6
6
|
|
|
7
|
-
_1MB = 1024 * 1024
|
|
8
|
-
|
|
9
7
|
|
|
10
8
|
@dataclass
|
|
11
9
|
class Args:
|
|
@@ -39,7 +37,7 @@ def _parse_args() -> Args:
|
|
|
39
37
|
"--chunk-size",
|
|
40
38
|
help="Chunk size that will be read and uploaded in SizeSuffix form, too low or too high will cause issues",
|
|
41
39
|
type=str,
|
|
42
|
-
default="
|
|
40
|
+
default="128MB", # if this is too low or too high an s3 service
|
|
43
41
|
)
|
|
44
42
|
parser.add_argument(
|
|
45
43
|
"--read-threads",
|
rclone_api/exec.py
CHANGED
|
@@ -14,7 +14,7 @@ class RcloneExec:
|
|
|
14
14
|
rclone_exe: Path
|
|
15
15
|
|
|
16
16
|
def execute(
|
|
17
|
-
self, cmd: list[str], check: bool, capture: bool | None = None
|
|
17
|
+
self, cmd: list[str], check: bool, capture: bool | Path | None = None
|
|
18
18
|
) -> subprocess.CompletedProcess:
|
|
19
19
|
"""Execute rclone command."""
|
|
20
20
|
from rclone_api.util import rclone_execute
|
rclone_api/file.py
CHANGED
|
@@ -1,9 +1,46 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import warnings
|
|
3
|
+
from dataclasses import dataclass
|
|
2
4
|
from pathlib import Path
|
|
3
5
|
|
|
4
6
|
from rclone_api.rpath import RPath
|
|
5
7
|
|
|
6
8
|
|
|
9
|
+
# File is too complex, this is a simple dataclass that can be streamed out.
|
|
10
|
+
@dataclass
|
|
11
|
+
class FileItem:
|
|
12
|
+
"""Remote file dataclass."""
|
|
13
|
+
|
|
14
|
+
path: str
|
|
15
|
+
name: str
|
|
16
|
+
size: int
|
|
17
|
+
mime_type: str
|
|
18
|
+
mod_time: str
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def from_json(data: dict) -> "FileItem | None":
|
|
22
|
+
try:
|
|
23
|
+
return FileItem(
|
|
24
|
+
data["Path"],
|
|
25
|
+
data["Name"],
|
|
26
|
+
data["Size"],
|
|
27
|
+
data["MimeType"],
|
|
28
|
+
data["ModTime"],
|
|
29
|
+
)
|
|
30
|
+
except KeyError:
|
|
31
|
+
warnings.warn(f"Invalid data: {data}")
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def from_json_str(data: str) -> "FileItem | None":
|
|
36
|
+
try:
|
|
37
|
+
data_dict = json.loads(data)
|
|
38
|
+
return FileItem.from_json(data_dict)
|
|
39
|
+
except json.JSONDecodeError:
|
|
40
|
+
warnings.warn(f"Invalid JSON data: {data}")
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
|
|
7
44
|
class File:
|
|
8
45
|
"""Remote file dataclass."""
|
|
9
46
|
|
rclone_api/mount_read_chunker.py
CHANGED
|
@@ -6,7 +6,7 @@ from threading import Lock, Semaphore
|
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
from rclone_api.mount import Mount
|
|
9
|
-
from rclone_api.types import FilePart
|
|
9
|
+
from rclone_api.types import FilePart, SizeSuffix
|
|
10
10
|
|
|
11
11
|
# Create a logger for this module
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
@@ -86,7 +86,13 @@ class MultiMountFileChunker:
|
|
|
86
86
|
self.semaphore.release()
|
|
87
87
|
logger.debug("Mount released")
|
|
88
88
|
|
|
89
|
-
def fetch(
|
|
89
|
+
def fetch(
|
|
90
|
+
self, offset: int | SizeSuffix, size: int | SizeSuffix, extra: Any
|
|
91
|
+
) -> Future[FilePart]:
|
|
92
|
+
offset = SizeSuffix(offset).as_int()
|
|
93
|
+
size = SizeSuffix(size).as_int()
|
|
94
|
+
if isinstance(size, SizeSuffix):
|
|
95
|
+
size = size.as_int()
|
|
90
96
|
if self.verbose:
|
|
91
97
|
logger.debug(f"Fetching data range: offset={offset}, size={size}")
|
|
92
98
|
|
rclone_api/process.py
CHANGED
|
@@ -72,6 +72,12 @@ class Process:
|
|
|
72
72
|
|
|
73
73
|
atexit.register(exit_cleanup)
|
|
74
74
|
|
|
75
|
+
def __enter__(self) -> "Process":
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
79
|
+
self.cleanup()
|
|
80
|
+
|
|
75
81
|
def cleanup(self) -> None:
|
|
76
82
|
if self.tempdir and self.needs_cleanup:
|
|
77
83
|
try:
|
|
@@ -218,7 +218,7 @@ def test_profile_copy_bytes(
|
|
|
218
218
|
1024 * 1024 * 16,
|
|
219
219
|
# 1024 * 1024 * 32,
|
|
220
220
|
1024 * 1024 * 64,
|
|
221
|
-
#1024 * 1024 * 128,
|
|
221
|
+
# 1024 * 1024 * 128,
|
|
222
222
|
1024 * 1024 * 256,
|
|
223
223
|
]
|
|
224
224
|
# transfer_list = [1, 2, 4, 8, 16]
|
|
@@ -253,8 +253,10 @@ def _parse_args() -> Args:
|
|
|
253
253
|
args = parser.parse_args()
|
|
254
254
|
return Args(direct_io=args.direct_io, num=args.num, size=args.size)
|
|
255
255
|
|
|
256
|
+
|
|
256
257
|
_SHOW_CREDS = False
|
|
257
258
|
|
|
259
|
+
|
|
258
260
|
def main() -> None:
|
|
259
261
|
"""Main entry point."""
|
|
260
262
|
print("Running test_profile_copy_bytes")
|