rclone-api 1.1.29__py2.py3-none-any.whl → 1.1.31__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/exec.py +4 -1
- rclone_api/mount.py +5 -4
- rclone_api/process.py +5 -7
- rclone_api/profiling/mount_copy_bytes.py +145 -0
- rclone_api/rclone.py +27 -9
- {rclone_api-1.1.29.dist-info → rclone_api-1.1.31.dist-info}/METADATA +2 -1
- {rclone_api-1.1.29.dist-info → rclone_api-1.1.31.dist-info}/RECORD +11 -10
- {rclone_api-1.1.29.dist-info → rclone_api-1.1.31.dist-info}/LICENSE +0 -0
- {rclone_api-1.1.29.dist-info → rclone_api-1.1.31.dist-info}/WHEEL +0 -0
- {rclone_api-1.1.29.dist-info → rclone_api-1.1.31.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.1.29.dist-info → rclone_api-1.1.31.dist-info}/top_level.txt +0 -0
rclone_api/exec.py
CHANGED
|
@@ -23,7 +23,9 @@ class RcloneExec:
|
|
|
23
23
|
cmd, self.rclone_config, self.rclone_exe, check=check, capture=capture
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
-
def launch_process(
|
|
26
|
+
def launch_process(
|
|
27
|
+
self, cmd: list[str], capture: bool | None, log: Path | None
|
|
28
|
+
) -> Process:
|
|
27
29
|
"""Launch rclone process."""
|
|
28
30
|
|
|
29
31
|
args: ProcessArgs = ProcessArgs(
|
|
@@ -32,6 +34,7 @@ class RcloneExec:
|
|
|
32
34
|
rclone_exe=self.rclone_exe,
|
|
33
35
|
cmd_list=cmd,
|
|
34
36
|
capture_stdout=capture,
|
|
37
|
+
log=log,
|
|
35
38
|
)
|
|
36
39
|
process = Process(args)
|
|
37
40
|
return process
|
rclone_api/mount.py
CHANGED
|
@@ -105,8 +105,8 @@ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
|
|
|
105
105
|
mount_path = mount.mount_path if isinstance(mount, Mount) else mount
|
|
106
106
|
try:
|
|
107
107
|
mount_exists = mount_path.exists()
|
|
108
|
-
except OSError
|
|
109
|
-
warnings.warn(f"Error checking {mount_path}: {e}")
|
|
108
|
+
except OSError:
|
|
109
|
+
# warnings.warn(f"Error checking {mount_path}: {e}")
|
|
110
110
|
mount_exists = True
|
|
111
111
|
|
|
112
112
|
# Give the system a moment (if unmount is in progress, etc.)
|
|
@@ -139,8 +139,9 @@ def clean_mount(mount: Mount | Path, verbose: bool = False, wait=True) -> None:
|
|
|
139
139
|
mount_path.rmdir()
|
|
140
140
|
if verbose:
|
|
141
141
|
print(f"Successfully removed mount directory {mount_path}")
|
|
142
|
-
except Exception
|
|
143
|
-
warnings.warn(f"Failed to remove mount {mount_path}: {e}")
|
|
142
|
+
except Exception:
|
|
143
|
+
# warnings.warn(f"Failed to remove mount {mount_path}: {e}")
|
|
144
|
+
pass
|
|
144
145
|
else:
|
|
145
146
|
warnings.warn(f"Unsupported platform: {_SYSTEM}")
|
|
146
147
|
|
rclone_api/process.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import atexit
|
|
2
|
-
import os
|
|
3
2
|
import subprocess
|
|
4
3
|
import threading
|
|
5
4
|
import time
|
|
@@ -13,12 +12,6 @@ from rclone_api.config import Config
|
|
|
13
12
|
from rclone_api.util import get_verbose
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
def _get_verbose(verbose: bool | None) -> bool:
|
|
17
|
-
if verbose is not None:
|
|
18
|
-
return verbose
|
|
19
|
-
return bool(int(os.getenv("RCLONE_API_VERBOSE", "0")))
|
|
20
|
-
|
|
21
|
-
|
|
22
15
|
@dataclass
|
|
23
16
|
class ProcessArgs:
|
|
24
17
|
cmd: list[str]
|
|
@@ -27,12 +20,14 @@ class ProcessArgs:
|
|
|
27
20
|
cmd_list: list[str]
|
|
28
21
|
verbose: bool | None = None
|
|
29
22
|
capture_stdout: bool | None = None
|
|
23
|
+
log: Path | None = None
|
|
30
24
|
|
|
31
25
|
|
|
32
26
|
class Process:
|
|
33
27
|
def __init__(self, args: ProcessArgs) -> None:
|
|
34
28
|
assert args.rclone_exe.exists()
|
|
35
29
|
self.args = args
|
|
30
|
+
self.log = args.log
|
|
36
31
|
self.tempdir: TemporaryDirectory | None = None
|
|
37
32
|
verbose = get_verbose(args.verbose)
|
|
38
33
|
if isinstance(args.rclone_conf, Config):
|
|
@@ -52,6 +47,9 @@ class Process:
|
|
|
52
47
|
+ ["--config", str(rclone_conf.resolve())]
|
|
53
48
|
+ args.cmd
|
|
54
49
|
)
|
|
50
|
+
if self.args.log:
|
|
51
|
+
self.args.log.parent.mkdir(parents=True, exist_ok=True)
|
|
52
|
+
self.cmd += ["--log-file", str(self.args.log)]
|
|
55
53
|
if verbose:
|
|
56
54
|
cmd_str = subprocess.list2cmdline(self.cmd)
|
|
57
55
|
print(f"Running: {cmd_str}")
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit test file.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import time
|
|
7
|
+
import unittest
|
|
8
|
+
|
|
9
|
+
import psutil
|
|
10
|
+
from dotenv import load_dotenv
|
|
11
|
+
|
|
12
|
+
from rclone_api import Config, Rclone, SizeSuffix
|
|
13
|
+
|
|
14
|
+
load_dotenv()
|
|
15
|
+
|
|
16
|
+
BUCKET_NAME = os.getenv("BUCKET_NAME") # Default if not in .env
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _generate_rclone_config() -> Config:
|
|
20
|
+
|
|
21
|
+
# assert that .env exists for this test
|
|
22
|
+
assert os.path.exists(
|
|
23
|
+
".env"
|
|
24
|
+
), "this test requires that the secret .env file exists with the credentials"
|
|
25
|
+
|
|
26
|
+
# BUCKET_NAME = os.getenv("BUCKET_NAME", "TorrentBooks") # Default if not in .env
|
|
27
|
+
|
|
28
|
+
# Load additional environment variables
|
|
29
|
+
BUCKET_KEY_SECRET = os.getenv("BUCKET_KEY_SECRET")
|
|
30
|
+
BUCKET_KEY_PUBLIC = os.getenv("BUCKET_KEY_PUBLIC")
|
|
31
|
+
SRC_SFTP_HOST = os.getenv("SRC_SFTP_HOST")
|
|
32
|
+
SRC_SFTP_USER = os.getenv("SRC_SFTP_USER")
|
|
33
|
+
SRC_SFTP_PORT = os.getenv("SRC_SFTP_PORT")
|
|
34
|
+
SRC_SFTP_PASS = os.getenv("SRC_SFTP_PASS")
|
|
35
|
+
# BUCKET_URL = os.getenv("BUCKET_URL")
|
|
36
|
+
BUCKET_URL = "sfo3.digitaloceanspaces.com"
|
|
37
|
+
|
|
38
|
+
config_text = f"""
|
|
39
|
+
[dst]
|
|
40
|
+
type = s3
|
|
41
|
+
provider = DigitalOcean
|
|
42
|
+
access_key_id = {BUCKET_KEY_PUBLIC}
|
|
43
|
+
secret_access_key = {BUCKET_KEY_SECRET}
|
|
44
|
+
endpoint = {BUCKET_URL}
|
|
45
|
+
bucket = {BUCKET_NAME}
|
|
46
|
+
|
|
47
|
+
[src]
|
|
48
|
+
type = sftp
|
|
49
|
+
host = {SRC_SFTP_HOST}
|
|
50
|
+
user = {SRC_SFTP_USER}
|
|
51
|
+
port = {SRC_SFTP_PORT}
|
|
52
|
+
pass = {SRC_SFTP_PASS}
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
# _CONFIG_PATH.write_text(config_text, encoding="utf-8")
|
|
56
|
+
# print(f"Config file written to: {_CONFIG_PATH}")
|
|
57
|
+
return Config(config_text)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class RcloneProfileCopyBytes(unittest.TestCase):
|
|
61
|
+
"""Test rclone functionality."""
|
|
62
|
+
|
|
63
|
+
def setUp(self) -> None:
|
|
64
|
+
"""Check if all required environment variables are set before running tests."""
|
|
65
|
+
required_vars = [
|
|
66
|
+
"BUCKET_NAME",
|
|
67
|
+
"BUCKET_KEY_SECRET",
|
|
68
|
+
"BUCKET_KEY_PUBLIC",
|
|
69
|
+
"BUCKET_URL",
|
|
70
|
+
]
|
|
71
|
+
missing = [var for var in required_vars if not os.getenv(var)]
|
|
72
|
+
if missing:
|
|
73
|
+
self.skipTest(
|
|
74
|
+
f"Missing required environment variables: {', '.join(missing)}"
|
|
75
|
+
)
|
|
76
|
+
os.environ["RCLONE_API_VERBOSE"] = "1"
|
|
77
|
+
|
|
78
|
+
def test_profile_copy_bytes(self) -> None:
|
|
79
|
+
rclone = Rclone(_generate_rclone_config())
|
|
80
|
+
sizes = [
|
|
81
|
+
1024 * 1024 * 1,
|
|
82
|
+
1024 * 1024 * 2,
|
|
83
|
+
1024 * 1024 * 4,
|
|
84
|
+
1024 * 1024 * 8,
|
|
85
|
+
1024 * 1024 * 16,
|
|
86
|
+
1024 * 1024 * 32,
|
|
87
|
+
1024 * 1024 * 64,
|
|
88
|
+
]
|
|
89
|
+
# transfer_list = [1, 2, 4, 8, 16]
|
|
90
|
+
transfer_list = [1, 2, 4]
|
|
91
|
+
|
|
92
|
+
# src_file = "dst:rclone-api-unit-test/zachs_video/internaly_ai_alignment.mp4"
|
|
93
|
+
# sftp mount
|
|
94
|
+
src_file = "src:aa_misc_data/aa_misc_data/world_lending_library_2024_11.tar.zst"
|
|
95
|
+
|
|
96
|
+
for size in sizes:
|
|
97
|
+
for transfers in transfer_list:
|
|
98
|
+
print("\n\n")
|
|
99
|
+
print("#" * 80)
|
|
100
|
+
print(
|
|
101
|
+
f"# Started test download of {SizeSuffix(size)} with {transfers} transfers"
|
|
102
|
+
)
|
|
103
|
+
print("#" * 80)
|
|
104
|
+
net_io_start = psutil.net_io_counters()
|
|
105
|
+
start = time.time()
|
|
106
|
+
bytes_or_err: bytes | Exception = rclone.copy_bytes(
|
|
107
|
+
src=src_file,
|
|
108
|
+
offset=0,
|
|
109
|
+
length=size,
|
|
110
|
+
direct_io=True,
|
|
111
|
+
transfers=transfers,
|
|
112
|
+
)
|
|
113
|
+
diff = time.time() - start
|
|
114
|
+
net_io_end = psutil.net_io_counters()
|
|
115
|
+
if isinstance(bytes_or_err, Exception):
|
|
116
|
+
print(bytes_or_err)
|
|
117
|
+
self.fail(f"Error: {bytes_or_err}")
|
|
118
|
+
assert isinstance(bytes_or_err, bytes)
|
|
119
|
+
self.assertEqual(len(bytes_or_err), size)
|
|
120
|
+
|
|
121
|
+
# print io stats
|
|
122
|
+
bytes_sent = net_io_end.bytes_sent - net_io_start.bytes_sent
|
|
123
|
+
bytes_recv = net_io_end.bytes_recv - net_io_start.bytes_recv
|
|
124
|
+
packets_sent = net_io_end.packets_sent - net_io_start.packets_sent
|
|
125
|
+
efficiency = size / (bytes_recv)
|
|
126
|
+
efficiency_100 = efficiency * 100
|
|
127
|
+
efficiency_str = f"{efficiency_100:.2f}"
|
|
128
|
+
|
|
129
|
+
bytes_send_suffix = SizeSuffix(bytes_sent)
|
|
130
|
+
bytes_recv_suffix = SizeSuffix(bytes_recv)
|
|
131
|
+
range_size = SizeSuffix(size)
|
|
132
|
+
|
|
133
|
+
print(f"\nFinished downloading {range_size} with {transfers} transfers")
|
|
134
|
+
print("Net IO stats:")
|
|
135
|
+
print(f"Bytes sent: {bytes_send_suffix}")
|
|
136
|
+
print(f"Bytes received: {bytes_recv_suffix}")
|
|
137
|
+
print(f"Packets sent: {packets_sent}")
|
|
138
|
+
print(f"Efficiency: {efficiency_str}%")
|
|
139
|
+
print(f"Time: {diff:.1f} seconds")
|
|
140
|
+
|
|
141
|
+
print("done")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
if __name__ == "__main__":
|
|
145
|
+
unittest.main()
|
rclone_api/rclone.py
CHANGED
|
@@ -80,8 +80,10 @@ class Rclone:
|
|
|
80
80
|
) -> subprocess.CompletedProcess:
|
|
81
81
|
return self._exec.execute(cmd, check=check, capture=capture)
|
|
82
82
|
|
|
83
|
-
def _launch_process(
|
|
84
|
-
|
|
83
|
+
def _launch_process(
|
|
84
|
+
self, cmd: list[str], capture: bool | None = None, log: Path | None = None
|
|
85
|
+
) -> Process:
|
|
86
|
+
return self._exec.launch_process(cmd, capture=capture, log=log)
|
|
85
87
|
|
|
86
88
|
def webgui(self, other_args: list[str] | None = None) -> Process:
|
|
87
89
|
"""Launch the Rclone web GUI."""
|
|
@@ -684,6 +686,7 @@ class Rclone:
|
|
|
684
686
|
verbose: bool | None = None,
|
|
685
687
|
max_chunks_before_suspension: int | None = None,
|
|
686
688
|
mount_path: Path | None = None,
|
|
689
|
+
mount_log: Path | None = None,
|
|
687
690
|
) -> MultiUploadResult:
|
|
688
691
|
"""For massive files that rclone can't handle in one go, this function will copy the file in chunks to an S3 store"""
|
|
689
692
|
from rclone_api.s3.api import S3Client
|
|
@@ -724,6 +727,7 @@ class Rclone:
|
|
|
724
727
|
use_links=True,
|
|
725
728
|
vfs_cache_mode="minimal",
|
|
726
729
|
verbose=False,
|
|
730
|
+
log=mount_log,
|
|
727
731
|
other_args=other_args,
|
|
728
732
|
):
|
|
729
733
|
path_info: S3PathInfo = split_s3_path(dst)
|
|
@@ -816,7 +820,11 @@ class Rclone:
|
|
|
816
820
|
src: str,
|
|
817
821
|
offset: int,
|
|
818
822
|
length: int,
|
|
819
|
-
transfers: int =
|
|
823
|
+
transfers: int = 1, # Note, increasing transfers can result in devestating drop in performance.
|
|
824
|
+
# If outfile is supplied then bytes are written to this file and success returns bytes(0)
|
|
825
|
+
outfile: Path | None = None,
|
|
826
|
+
mount_log: Path | None = None,
|
|
827
|
+
direct_io: bool = True,
|
|
820
828
|
) -> bytes | Exception:
|
|
821
829
|
"""Copy bytes from a file to another file."""
|
|
822
830
|
from rclone_api.util import random_str
|
|
@@ -825,8 +833,7 @@ class Rclone:
|
|
|
825
833
|
src_parent_path = Path(src).parent.as_posix()
|
|
826
834
|
src_file = Path(src).name
|
|
827
835
|
other_args: list[str] = ["--no-modtime", "--vfs-read-wait", "1s"]
|
|
828
|
-
|
|
829
|
-
vfs_read_chunk_size = unit_chunk_size
|
|
836
|
+
vfs_read_chunk_size = length // transfers
|
|
830
837
|
vfs_read_chunk_size_limit = length
|
|
831
838
|
vfs_read_chunk_streams = transfers
|
|
832
839
|
vfs_disk_space_total_size = length
|
|
@@ -835,7 +842,8 @@ class Rclone:
|
|
|
835
842
|
other_args += ["--vfs-read-chunk-streams", str(vfs_read_chunk_streams)]
|
|
836
843
|
other_args += ["--vfs-disk-space-total-size", str(vfs_disk_space_total_size)]
|
|
837
844
|
other_args += ["--read-only"]
|
|
838
|
-
|
|
845
|
+
if direct_io:
|
|
846
|
+
other_args += ["--direct-io"]
|
|
839
847
|
|
|
840
848
|
try:
|
|
841
849
|
# use scoped mount to do the read, then write the bytes to the destination
|
|
@@ -843,15 +851,22 @@ class Rclone:
|
|
|
843
851
|
src_parent_path,
|
|
844
852
|
tmp_mnt,
|
|
845
853
|
use_links=True,
|
|
846
|
-
verbose=
|
|
854
|
+
verbose=mount_log is not None,
|
|
847
855
|
vfs_cache_mode="minimal",
|
|
848
856
|
other_args=other_args,
|
|
857
|
+
log=mount_log,
|
|
849
858
|
):
|
|
850
859
|
src_file_mnt = tmp_mnt / src_file
|
|
851
860
|
with open(src_file_mnt, "rb") as f:
|
|
852
861
|
f.seek(offset)
|
|
853
862
|
data = f.read(length)
|
|
854
|
-
|
|
863
|
+
if outfile is None:
|
|
864
|
+
return data
|
|
865
|
+
with open(outfile, "wb") as out:
|
|
866
|
+
out.write(data)
|
|
867
|
+
del data
|
|
868
|
+
return bytes(0)
|
|
869
|
+
|
|
855
870
|
except Exception as e:
|
|
856
871
|
return e
|
|
857
872
|
|
|
@@ -887,6 +902,7 @@ class Rclone:
|
|
|
887
902
|
use_links: bool | None = None,
|
|
888
903
|
vfs_cache_mode: str | None = None,
|
|
889
904
|
verbose: bool | None = None,
|
|
905
|
+
log: Path | None = None,
|
|
890
906
|
other_args: list[str] | None = None,
|
|
891
907
|
) -> Mount:
|
|
892
908
|
"""Mount a remote or directory to a local path.
|
|
@@ -921,7 +937,7 @@ class Rclone:
|
|
|
921
937
|
cmd_list.append("-vvvv")
|
|
922
938
|
if other_args:
|
|
923
939
|
cmd_list += other_args
|
|
924
|
-
proc = self._launch_process(cmd_list)
|
|
940
|
+
proc = self._launch_process(cmd_list, log=log)
|
|
925
941
|
mount_read_only = "--read-only" in cmd_list # hint to allow fast teardown
|
|
926
942
|
mount: Mount = Mount(mount_path=outdir, process=proc, read_only=mount_read_only)
|
|
927
943
|
return mount
|
|
@@ -935,6 +951,7 @@ class Rclone:
|
|
|
935
951
|
use_links: bool | None = None,
|
|
936
952
|
vfs_cache_mode: str | None = None,
|
|
937
953
|
verbose: bool | None = None,
|
|
954
|
+
log: Path | None = None,
|
|
938
955
|
other_args: list[str] | None = None,
|
|
939
956
|
) -> Generator[Mount, None, None]:
|
|
940
957
|
"""Like mount, but can be used in a context manager."""
|
|
@@ -947,6 +964,7 @@ class Rclone:
|
|
|
947
964
|
use_links=use_links,
|
|
948
965
|
vfs_cache_mode=vfs_cache_mode,
|
|
949
966
|
verbose=verbose,
|
|
967
|
+
log=log,
|
|
950
968
|
other_args=other_args,
|
|
951
969
|
)
|
|
952
970
|
try:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: rclone_api
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.31
|
|
4
4
|
Summary: rclone api in python
|
|
5
5
|
Home-page: https://github.com/zackees/rclone-api
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -12,6 +12,7 @@ License-File: LICENSE
|
|
|
12
12
|
Requires-Dist: pyright>=1.1.393
|
|
13
13
|
Requires-Dist: python-dotenv>=1.0.0
|
|
14
14
|
Requires-Dist: certifi>=2025.1.31
|
|
15
|
+
Requires-Dist: psutil
|
|
15
16
|
Requires-Dist: boto3<=1.35.99,>=1.20.1
|
|
16
17
|
Dynamic: home-page
|
|
17
18
|
|
|
@@ -7,13 +7,13 @@ rclone_api/deprecated.py,sha256=qWKpnZdYcBK7YQZKuVoWWXDwi-uqiAtbjgPcci_efow,590
|
|
|
7
7
|
rclone_api/diff.py,sha256=tMoJMAGmLSE6Q_7QhPf6PnCzb840djxMZtDmhc2GlGQ,5227
|
|
8
8
|
rclone_api/dir.py,sha256=i4h7LX5hB_WmVixxDRWL_l1nifvscrdWct_8Wx7wHZc,3540
|
|
9
9
|
rclone_api/dir_listing.py,sha256=GoziW8Sne6FY90MLNcb2aO3aaa3jphB6H8ExYrV0Ryo,1882
|
|
10
|
-
rclone_api/exec.py,sha256=
|
|
10
|
+
rclone_api/exec.py,sha256=Pd7pUBd8ib5MzqvMybG2DQISPRbDRu20VjVRL2mLAVY,1076
|
|
11
11
|
rclone_api/file.py,sha256=EP5yT2dZ0H2p7CY5n0y5k5pHhIliV25pm8KOwBklUTk,1863
|
|
12
12
|
rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
|
13
13
|
rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
|
|
14
|
-
rclone_api/mount.py,sha256=
|
|
15
|
-
rclone_api/process.py,sha256=
|
|
16
|
-
rclone_api/rclone.py,sha256=
|
|
14
|
+
rclone_api/mount.py,sha256=ryAjkX4_kFeFZWLiBVpcGy2VilpvVhFbWeWfEX4jMKs,6104
|
|
15
|
+
rclone_api/process.py,sha256=rBj_S86jC6nqCYop-jq8r9eMSteKeObxUrJMgH8LZvI,5084
|
|
16
|
+
rclone_api/rclone.py,sha256=meZkXmIM1M_L0Xu2hf0fcm-tG1cF5t6AHSIM6TOXUQM,42624
|
|
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
|
|
@@ -25,6 +25,7 @@ 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/profiling/mount_copy_bytes.py,sha256=SgorSAG9lOlqMxzLt5N2UX_fepANpFWKM5NaQiBrsFE,4745
|
|
28
29
|
rclone_api/s3/api.py,sha256=qxtRDUpHYqJ7StJRtP8U_PbF_BvYRg705568SyvF-R0,3770
|
|
29
30
|
rclone_api/s3/basic_ops.py,sha256=hK3366xhVEzEcjz9Gk_8lFx6MRceAk72cax6mUrr6ko,2104
|
|
30
31
|
rclone_api/s3/chunk_file.py,sha256=YELR-EzR7RHpzCDGpYdzlwu21NZW5wttIDvLoONI4aU,3477
|
|
@@ -32,9 +33,9 @@ rclone_api/s3/chunk_types.py,sha256=LbXayXY1KgVU1LkdbASD_BQ7TpVpwVnzMjtz--8LBaE,
|
|
|
32
33
|
rclone_api/s3/create.py,sha256=wgfkapv_j904CfKuWyiBIWJVxfAx_ftemFSUV14aT68,3149
|
|
33
34
|
rclone_api/s3/types.py,sha256=yBnJ38Tjk6RlydJ-sqZ7DSfyFloy8KDYJ0mv3vlOzLE,1388
|
|
34
35
|
rclone_api/s3/upload_file_multipart.py,sha256=1jQAdk35Fa9Tcq36bS65262cs7AcNG2DAFQ-NdYlWSw,9961
|
|
35
|
-
rclone_api-1.1.
|
|
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.
|
|
36
|
+
rclone_api-1.1.31.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
|
37
|
+
rclone_api-1.1.31.dist-info/METADATA,sha256=5gEXYe7terl_H8vFbUZkWyD2wy2c05W-6EKuNgQya6Y,4537
|
|
38
|
+
rclone_api-1.1.31.dist-info/WHEEL,sha256=rF4EZyR2XVS6irmOHQIJx2SUqXLZKRMUrjsg8UwN-XQ,109
|
|
39
|
+
rclone_api-1.1.31.dist-info/entry_points.txt,sha256=6eNqTRXKhVf8CpWNjXiOa_0Du9tHiW_HD2iQSXRsUg8,132
|
|
40
|
+
rclone_api-1.1.31.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
|
41
|
+
rclone_api-1.1.31.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|