rclone-api 1.1.26__py2.py3-none-any.whl → 1.1.29__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/rclone.py +45 -3
- rclone_api/s3/api.py +1 -1
- rclone_api/types.py +52 -25
- {rclone_api-1.1.26.dist-info → rclone_api-1.1.29.dist-info}/METADATA +1 -1
- {rclone_api-1.1.26.dist-info → rclone_api-1.1.29.dist-info}/RECORD +10 -10
- /rclone_api/s3/{chunk_uploader.py → upload_file_multipart.py} +0 -0
- {rclone_api-1.1.26.dist-info → rclone_api-1.1.29.dist-info}/LICENSE +0 -0
- {rclone_api-1.1.26.dist-info → rclone_api-1.1.29.dist-info}/WHEEL +0 -0
- {rclone_api-1.1.26.dist-info → rclone_api-1.1.29.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.1.26.dist-info → rclone_api-1.1.29.dist-info}/top_level.txt +0 -0
rclone_api/rclone.py
CHANGED
|
@@ -691,7 +691,7 @@ class Rclone:
|
|
|
691
691
|
from rclone_api.util import S3PathInfo, random_str, split_s3_path
|
|
692
692
|
|
|
693
693
|
other_args: list[str] = ["--no-modtime", "--vfs-read-wait", "1s"]
|
|
694
|
-
chunk_size = chunk_size or SizeSuffix("
|
|
694
|
+
chunk_size = chunk_size or SizeSuffix("64M")
|
|
695
695
|
unit_chunk_size = chunk_size / read_threads
|
|
696
696
|
vfs_read_chunk_size = unit_chunk_size
|
|
697
697
|
vfs_read_chunk_size_limit = chunk_size
|
|
@@ -726,8 +726,6 @@ class Rclone:
|
|
|
726
726
|
verbose=False,
|
|
727
727
|
other_args=other_args,
|
|
728
728
|
):
|
|
729
|
-
# raise NotImplementedError("Not implemented yet")
|
|
730
|
-
|
|
731
729
|
path_info: S3PathInfo = split_s3_path(dst)
|
|
732
730
|
remote = path_info.remote
|
|
733
731
|
bucket_name = path_info.bucket
|
|
@@ -813,6 +811,50 @@ class Rclone:
|
|
|
813
811
|
)
|
|
814
812
|
return out
|
|
815
813
|
|
|
814
|
+
def copy_bytes(
|
|
815
|
+
self,
|
|
816
|
+
src: str,
|
|
817
|
+
offset: int,
|
|
818
|
+
length: int,
|
|
819
|
+
transfers: int = 16,
|
|
820
|
+
) -> bytes | Exception:
|
|
821
|
+
"""Copy bytes from a file to another file."""
|
|
822
|
+
from rclone_api.util import random_str
|
|
823
|
+
|
|
824
|
+
tmp_mnt = Path("tmp_mnt") / random_str(12)
|
|
825
|
+
src_parent_path = Path(src).parent.as_posix()
|
|
826
|
+
src_file = Path(src).name
|
|
827
|
+
other_args: list[str] = ["--no-modtime", "--vfs-read-wait", "1s"]
|
|
828
|
+
unit_chunk_size = length
|
|
829
|
+
vfs_read_chunk_size = unit_chunk_size
|
|
830
|
+
vfs_read_chunk_size_limit = length
|
|
831
|
+
vfs_read_chunk_streams = transfers
|
|
832
|
+
vfs_disk_space_total_size = length
|
|
833
|
+
other_args += ["--vfs-read-chunk-size", str(vfs_read_chunk_size)]
|
|
834
|
+
other_args += ["--vfs-read-chunk-size-limit", str(vfs_read_chunk_size_limit)]
|
|
835
|
+
other_args += ["--vfs-read-chunk-streams", str(vfs_read_chunk_streams)]
|
|
836
|
+
other_args += ["--vfs-disk-space-total-size", str(vfs_disk_space_total_size)]
|
|
837
|
+
other_args += ["--read-only"]
|
|
838
|
+
other_args += ["--direct-io"]
|
|
839
|
+
|
|
840
|
+
try:
|
|
841
|
+
# use scoped mount to do the read, then write the bytes to the destination
|
|
842
|
+
with self.scoped_mount(
|
|
843
|
+
src_parent_path,
|
|
844
|
+
tmp_mnt,
|
|
845
|
+
use_links=True,
|
|
846
|
+
verbose=False,
|
|
847
|
+
vfs_cache_mode="minimal",
|
|
848
|
+
other_args=other_args,
|
|
849
|
+
):
|
|
850
|
+
src_file_mnt = tmp_mnt / src_file
|
|
851
|
+
with open(src_file_mnt, "rb") as f:
|
|
852
|
+
f.seek(offset)
|
|
853
|
+
data = f.read(length)
|
|
854
|
+
return data
|
|
855
|
+
except Exception as e:
|
|
856
|
+
return e
|
|
857
|
+
|
|
816
858
|
def copy_dir(
|
|
817
859
|
self, src: str | Dir, dst: str | Dir, args: list[str] | None = None
|
|
818
860
|
) -> CompletedProcess:
|
rclone_api/s3/api.py
CHANGED
|
@@ -9,9 +9,9 @@ from rclone_api.s3.basic_ops import (
|
|
|
9
9
|
list_bucket_contents,
|
|
10
10
|
upload_file,
|
|
11
11
|
)
|
|
12
|
-
from rclone_api.s3.chunk_uploader import MultiUploadResult, upload_file_multipart
|
|
13
12
|
from rclone_api.s3.create import create_s3_client
|
|
14
13
|
from rclone_api.s3.types import S3Credentials, S3MutliPartUploadConfig, S3UploadTarget
|
|
14
|
+
from rclone_api.s3.upload_file_multipart import MultiUploadResult, upload_file_multipart
|
|
15
15
|
|
|
16
16
|
_MIN_THRESHOLD_FOR_CHUNKING = 5 * 1024 * 1024
|
|
17
17
|
|
rclone_api/types.py
CHANGED
|
@@ -37,41 +37,68 @@ class SizeResult:
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def _to_size_suffix(size: int) -> str:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
40
|
+
def _convert(size: int) -> tuple[float, str]:
|
|
41
|
+
val: float
|
|
42
|
+
unit: str
|
|
43
|
+
if size < 1024:
|
|
44
|
+
val = size
|
|
45
|
+
unit = "B"
|
|
46
|
+
elif size < 1024**2:
|
|
47
|
+
val = size / 1024
|
|
48
|
+
unit = "K"
|
|
49
|
+
elif size < 1024**3:
|
|
50
|
+
val = size / (1024**2)
|
|
51
|
+
unit = "M"
|
|
52
|
+
elif size < 1024**4:
|
|
53
|
+
val = size / (1024**3)
|
|
54
|
+
unit = "G"
|
|
55
|
+
elif size < 1024**5:
|
|
56
|
+
val = size / (1024**4)
|
|
57
|
+
unit = "T"
|
|
58
|
+
elif size < 1024**6:
|
|
59
|
+
val = size / (1024**5)
|
|
60
|
+
unit = "P"
|
|
61
|
+
else:
|
|
62
|
+
raise ValueError(f"Invalid size: {size}")
|
|
63
|
+
|
|
64
|
+
return val, unit
|
|
65
|
+
|
|
66
|
+
def _fmt(_val: float | int, _unit: str) -> str:
|
|
67
|
+
# If the float is an integer, drop the decimal, otherwise format with one decimal.
|
|
68
|
+
val_str: str = str(_val)
|
|
69
|
+
if not val_str.endswith(".0"):
|
|
70
|
+
first_str: str = f"{_val:.1f}"
|
|
71
|
+
else:
|
|
72
|
+
first_str = str(int(_val))
|
|
73
|
+
return first_str + _unit
|
|
74
|
+
|
|
75
|
+
val, unit = _convert(size)
|
|
76
|
+
out = _fmt(val, unit)
|
|
77
|
+
# Now round trip the value to fix floating point issues via rounding.
|
|
78
|
+
int_val = _from_size_suffix(out)
|
|
79
|
+
val, unit = _convert(int_val)
|
|
80
|
+
out = _fmt(val, unit)
|
|
81
|
+
return out
|
|
62
82
|
|
|
63
83
|
|
|
64
84
|
# Update regex to allow decimals (e.g., 16.5MB)
|
|
65
85
|
_PATTERN_SIZE_SUFFIX = re.compile(r"^(\d+(?:\.\d+)?)([A-Za-z]+)$")
|
|
66
86
|
|
|
67
87
|
|
|
88
|
+
def _parse_elements(value: str) -> tuple[str, str] | None:
|
|
89
|
+
match = _PATTERN_SIZE_SUFFIX.match(value)
|
|
90
|
+
if match is None:
|
|
91
|
+
return None
|
|
92
|
+
return match.group(1), match.group(2)
|
|
93
|
+
|
|
94
|
+
|
|
68
95
|
def _from_size_suffix(size: str) -> int:
|
|
69
96
|
if size == "0":
|
|
70
97
|
return 0
|
|
71
|
-
|
|
72
|
-
if
|
|
98
|
+
pair = _parse_elements(size)
|
|
99
|
+
if pair is None:
|
|
73
100
|
raise ValueError(f"Invalid size suffix: {size}")
|
|
74
|
-
num_str, suffix =
|
|
101
|
+
num_str, suffix = pair
|
|
75
102
|
n = float(num_str)
|
|
76
103
|
# Determine the unit from the first letter (e.g., "M" from "MB")
|
|
77
104
|
unit = suffix[0].upper()
|
|
@@ -13,11 +13,11 @@ rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
|
|
13
13
|
rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
|
|
14
14
|
rclone_api/mount.py,sha256=g9YkKCGJbWvGF7gzSKtWa8pEgphuW0-e0SySxtOirH4,6093
|
|
15
15
|
rclone_api/process.py,sha256=Hgn8MGEPkBt8C6C4oIuh-n1t1GkFF2miPlIE1lh_Zbc,5045
|
|
16
|
-
rclone_api/rclone.py,sha256=
|
|
16
|
+
rclone_api/rclone.py,sha256=bdAhJAW5KuxmTCZsSp5LfVUgD5WWfaKtuWyZTM-AGtI,41881
|
|
17
17
|
rclone_api/remote.py,sha256=O9WDUFQy9f6oT1HdUbTixK2eg0xtBBm8k4Xl6aa6K00,431
|
|
18
18
|
rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
|
|
19
19
|
rclone_api/scan_missing_folders.py,sha256=Kulca2Q6WZodt00ATFHkmqqInuoPvBkhTcS9703y6po,4740
|
|
20
|
-
rclone_api/types.py,sha256
|
|
20
|
+
rclone_api/types.py,sha256=AWVIoCaRkUBCXOQffxdkFCOeUhPwolQh9d2albyAGHc,4730
|
|
21
21
|
rclone_api/util.py,sha256=_Z-GUMVXnHYOGdo2dy2ie2P5fGgyg8KdGjHKicx68Ko,4573
|
|
22
22
|
rclone_api/walk.py,sha256=-54NVE8EJcCstwDoaC_UtHm73R2HrZwVwQmsnv55xNU,3369
|
|
23
23
|
rclone_api/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
|
@@ -25,16 +25,16 @@ rclone_api/cmd/copy_large_s3.py,sha256=-rfedi-ZzPUdCSP8ai9LRL0y1xVkvN-viQQlk8HVU
|
|
|
25
25
|
rclone_api/cmd/list_files.py,sha256=x8FHODEilwKqwdiU1jdkeJbLwOqUkUQuDWPo2u_zpf0,741
|
|
26
26
|
rclone_api/experimental/flags.py,sha256=qCVD--fSTmzlk9hloRLr0q9elzAOFzPsvVpKM3aB1Mk,2739
|
|
27
27
|
rclone_api/experimental/flags_base.py,sha256=ajU_czkTcAxXYU-SlmiCfHY7aCQGHvpCLqJ-Z8uZLk0,2102
|
|
28
|
-
rclone_api/s3/api.py,sha256=
|
|
28
|
+
rclone_api/s3/api.py,sha256=qxtRDUpHYqJ7StJRtP8U_PbF_BvYRg705568SyvF-R0,3770
|
|
29
29
|
rclone_api/s3/basic_ops.py,sha256=hK3366xhVEzEcjz9Gk_8lFx6MRceAk72cax6mUrr6ko,2104
|
|
30
30
|
rclone_api/s3/chunk_file.py,sha256=YELR-EzR7RHpzCDGpYdzlwu21NZW5wttIDvLoONI4aU,3477
|
|
31
31
|
rclone_api/s3/chunk_types.py,sha256=LbXayXY1KgVU1LkdbASD_BQ7TpVpwVnzMjtz--8LBaE,10316
|
|
32
|
-
rclone_api/s3/chunk_uploader.py,sha256=1jQAdk35Fa9Tcq36bS65262cs7AcNG2DAFQ-NdYlWSw,9961
|
|
33
32
|
rclone_api/s3/create.py,sha256=wgfkapv_j904CfKuWyiBIWJVxfAx_ftemFSUV14aT68,3149
|
|
34
33
|
rclone_api/s3/types.py,sha256=yBnJ38Tjk6RlydJ-sqZ7DSfyFloy8KDYJ0mv3vlOzLE,1388
|
|
35
|
-
rclone_api
|
|
36
|
-
rclone_api-1.1.
|
|
37
|
-
rclone_api-1.1.
|
|
38
|
-
rclone_api-1.1.
|
|
39
|
-
rclone_api-1.1.
|
|
40
|
-
rclone_api-1.1.
|
|
34
|
+
rclone_api/s3/upload_file_multipart.py,sha256=1jQAdk35Fa9Tcq36bS65262cs7AcNG2DAFQ-NdYlWSw,9961
|
|
35
|
+
rclone_api-1.1.29.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
|
36
|
+
rclone_api-1.1.29.dist-info/METADATA,sha256=BmYo65cIJ7V2miFqEfW5Kk1Y2-tpcMz1cbTUQNTZlNo,4514
|
|
37
|
+
rclone_api-1.1.29.dist-info/WHEEL,sha256=rF4EZyR2XVS6irmOHQIJx2SUqXLZKRMUrjsg8UwN-XQ,109
|
|
38
|
+
rclone_api-1.1.29.dist-info/entry_points.txt,sha256=6eNqTRXKhVf8CpWNjXiOa_0Du9tHiW_HD2iQSXRsUg8,132
|
|
39
|
+
rclone_api-1.1.29.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
|
40
|
+
rclone_api-1.1.29.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|