rclone-api 1.5.52__py3-none-any.whl → 1.5.54__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/fs/filesystem.py +330 -318
- rclone_api/fs/walk.py +24 -0
- {rclone_api-1.5.52.dist-info → rclone_api-1.5.54.dist-info}/METADATA +1 -1
- {rclone_api-1.5.52.dist-info → rclone_api-1.5.54.dist-info}/RECORD +8 -7
- {rclone_api-1.5.52.dist-info → rclone_api-1.5.54.dist-info}/WHEEL +0 -0
- {rclone_api-1.5.52.dist-info → rclone_api-1.5.54.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.5.52.dist-info → rclone_api-1.5.54.dist-info}/licenses/LICENSE +0 -0
- {rclone_api-1.5.52.dist-info → rclone_api-1.5.54.dist-info}/top_level.txt +0 -0
rclone_api/fs/filesystem.py
CHANGED
@@ -1,318 +1,330 @@
|
|
1
|
-
import abc
|
2
|
-
import logging
|
3
|
-
import shutil
|
4
|
-
import warnings
|
5
|
-
from pathlib import Path
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
self.
|
113
|
-
self.
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
self.
|
122
|
-
self.
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
self.
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
self.
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
self.
|
234
|
-
self.
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
self.fs_holder
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
def
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
def
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
1
|
+
import abc
|
2
|
+
import logging
|
3
|
+
import shutil
|
4
|
+
import warnings
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Generator
|
7
|
+
|
8
|
+
from rclone_api.config import Config
|
9
|
+
|
10
|
+
logger = logging.getLogger(__name__)
|
11
|
+
|
12
|
+
|
13
|
+
class FS(abc.ABC):
|
14
|
+
def __init__(self) -> None:
|
15
|
+
pass
|
16
|
+
|
17
|
+
@abc.abstractmethod
|
18
|
+
def copy(self, src: Path | str, dst: Path | str) -> None:
|
19
|
+
pass
|
20
|
+
|
21
|
+
@abc.abstractmethod
|
22
|
+
def read_bytes(self, path: Path | str) -> bytes:
|
23
|
+
pass
|
24
|
+
|
25
|
+
@abc.abstractmethod
|
26
|
+
def exists(self, path: Path | str) -> bool:
|
27
|
+
pass
|
28
|
+
|
29
|
+
@abc.abstractmethod
|
30
|
+
def write_binary(self, path: Path | str, data: bytes) -> None:
|
31
|
+
pass
|
32
|
+
|
33
|
+
@abc.abstractmethod
|
34
|
+
def mkdir(self, path: str, parents=True, exist_ok=True) -> None:
|
35
|
+
pass
|
36
|
+
|
37
|
+
@abc.abstractmethod
|
38
|
+
def ls(self, path: Path | str) -> tuple[list[str], list[str]]:
|
39
|
+
"""First is files and second is directories."""
|
40
|
+
pass
|
41
|
+
|
42
|
+
@abc.abstractmethod
|
43
|
+
def cwd(self) -> "FSPath":
|
44
|
+
pass
|
45
|
+
|
46
|
+
@abc.abstractmethod
|
47
|
+
def get_path(self, path: str) -> "FSPath":
|
48
|
+
pass
|
49
|
+
|
50
|
+
@abc.abstractmethod
|
51
|
+
def dispose(self) -> None:
|
52
|
+
pass
|
53
|
+
|
54
|
+
|
55
|
+
class RealFS(FS):
|
56
|
+
|
57
|
+
@staticmethod
|
58
|
+
def from_path(path: Path | str) -> "FSPath":
|
59
|
+
path_str = Path(path).as_posix()
|
60
|
+
return FSPath(RealFS(), path_str)
|
61
|
+
|
62
|
+
def __init__(self) -> None:
|
63
|
+
super().__init__()
|
64
|
+
|
65
|
+
def ls(self, path: Path | str) -> tuple[list[str], list[str]]:
|
66
|
+
files_and_dirs = [str(p) for p in Path(path).iterdir()]
|
67
|
+
files = [f for f in files_and_dirs if Path(f).is_file()]
|
68
|
+
dirs = [d for d in files_and_dirs if Path(d).is_dir()]
|
69
|
+
return files, dirs
|
70
|
+
|
71
|
+
def cwd(self) -> "FSPath":
|
72
|
+
return RealFS.from_path(Path.cwd())
|
73
|
+
|
74
|
+
def copy(self, src: Path | str, dst: Path | str) -> None:
|
75
|
+
shutil.copy(str(src), str(dst))
|
76
|
+
|
77
|
+
def read_bytes(self, path: Path | str) -> bytes:
|
78
|
+
with open(path, "rb") as f:
|
79
|
+
return f.read()
|
80
|
+
|
81
|
+
def write_binary(self, path: Path | str, data: bytes) -> None:
|
82
|
+
with open(path, "wb") as f:
|
83
|
+
f.write(data)
|
84
|
+
|
85
|
+
def exists(self, path: Path | str) -> bool:
|
86
|
+
return Path(path).exists()
|
87
|
+
|
88
|
+
def mkdir(self, path: str, parents=True, exist_ok=True) -> None:
|
89
|
+
Path(path).mkdir(parents=parents, exist_ok=exist_ok)
|
90
|
+
|
91
|
+
def get_path(self, path: str) -> "FSPath":
|
92
|
+
return FSPath(self, path)
|
93
|
+
|
94
|
+
def dispose(self) -> None:
|
95
|
+
pass
|
96
|
+
|
97
|
+
|
98
|
+
class RemoteFS(FS):
|
99
|
+
|
100
|
+
@staticmethod
|
101
|
+
def from_rclone_config(
|
102
|
+
src: str, rclone_conf: Path | Config | str | dict | None
|
103
|
+
) -> "RemoteFS":
|
104
|
+
if isinstance(rclone_conf, str) or isinstance(rclone_conf, dict):
|
105
|
+
rclone_conf = Config(text=rclone_conf)
|
106
|
+
return RemoteFS(rclone_conf, src)
|
107
|
+
|
108
|
+
def __init__(self, rclone_conf: Path | Config | None, src: str) -> None:
|
109
|
+
from rclone_api import HttpServer, Rclone
|
110
|
+
|
111
|
+
super().__init__()
|
112
|
+
self.src = src
|
113
|
+
self.shutdown = False
|
114
|
+
self.server: HttpServer | None = None
|
115
|
+
if rclone_conf is None:
|
116
|
+
from rclone_api.config import find_conf_file
|
117
|
+
|
118
|
+
rclone_conf = find_conf_file()
|
119
|
+
if rclone_conf is None:
|
120
|
+
raise FileNotFoundError("rclone.conf not found")
|
121
|
+
self.rclone_conf = rclone_conf
|
122
|
+
self.rclone: Rclone = Rclone(rclone_conf)
|
123
|
+
self.server = self.rclone.serve_http(src=src)
|
124
|
+
|
125
|
+
def root(self) -> "FSPath":
|
126
|
+
return FSPath(self, self.src)
|
127
|
+
|
128
|
+
def cwd(self) -> "FSPath":
|
129
|
+
return self.root()
|
130
|
+
|
131
|
+
def _to_str(self, path: Path | str) -> str:
|
132
|
+
if isinstance(path, Path):
|
133
|
+
return path.as_posix()
|
134
|
+
return path
|
135
|
+
|
136
|
+
def _to_remote_path(self, path: str | Path) -> str:
|
137
|
+
return Path(path).relative_to(self.src).as_posix()
|
138
|
+
|
139
|
+
def copy(self, src: Path | str, dst: Path | str) -> None:
|
140
|
+
from rclone_api.completed_process import CompletedProcess
|
141
|
+
|
142
|
+
src = src if isinstance(src, Path) else Path(src)
|
143
|
+
if not src.is_file():
|
144
|
+
raise FileNotFoundError(f"File not found: {src}")
|
145
|
+
dst = self._to_remote_path(dst)
|
146
|
+
|
147
|
+
is_s3 = self.rclone.is_s3(dst)
|
148
|
+
if is_s3:
|
149
|
+
filesize = src.stat().st_size
|
150
|
+
if filesize < 1024 * 1024 * 1024: # 1GB
|
151
|
+
logger.info(f"S3 OPTIMIZED: Copying {src} -> {dst}")
|
152
|
+
err = self.rclone.copy_file_s3(src, dst)
|
153
|
+
if isinstance(err, Exception):
|
154
|
+
raise FileNotFoundError(
|
155
|
+
f"File not found: {src}, specified by {err}"
|
156
|
+
)
|
157
|
+
return
|
158
|
+
# Fallback.
|
159
|
+
logging.info(f"Copying {src} -> {dst}")
|
160
|
+
src_path = src.as_posix()
|
161
|
+
cp: CompletedProcess = self.rclone.copy(src_path, dst)
|
162
|
+
if cp.returncode != 0:
|
163
|
+
raise FileNotFoundError(f"File not found: {src}, specified by {cp.stderr}")
|
164
|
+
|
165
|
+
def read_bytes(self, path: Path | str) -> bytes:
|
166
|
+
path = self._to_str(path)
|
167
|
+
err = self.rclone.read_bytes(path)
|
168
|
+
if isinstance(err, Exception):
|
169
|
+
raise FileNotFoundError(f"File not found: {path}")
|
170
|
+
return err
|
171
|
+
|
172
|
+
def write_binary(self, path: Path | str, data: bytes) -> None:
|
173
|
+
path = self._to_str(path)
|
174
|
+
self.rclone.write_bytes(data, path) # Already optimized for s3.
|
175
|
+
|
176
|
+
def exists(self, path: Path | str) -> bool:
|
177
|
+
from rclone_api.http_server import HttpServer
|
178
|
+
|
179
|
+
assert isinstance(self.server, HttpServer)
|
180
|
+
path = self._to_str(path)
|
181
|
+
dst_rel = self._to_remote_path(path)
|
182
|
+
return self.server.exists(dst_rel)
|
183
|
+
|
184
|
+
def mkdir(self, path: str, parents=True, exist_ok=True) -> None:
|
185
|
+
# Ignore mkdir for remote backend, it will be made when file is written.
|
186
|
+
import warnings
|
187
|
+
|
188
|
+
warnings.warn("mkdir is not supported for remote backend", stacklevel=2)
|
189
|
+
return None
|
190
|
+
|
191
|
+
def is_dir(self, path: Path | str) -> bool:
|
192
|
+
from rclone_api.http_server import HttpServer
|
193
|
+
|
194
|
+
assert isinstance(self.server, HttpServer)
|
195
|
+
path = self._to_remote_path(path)
|
196
|
+
err = self.server.list(path)
|
197
|
+
return isinstance(err, list)
|
198
|
+
|
199
|
+
def is_file(self, path: Path | str) -> bool:
|
200
|
+
from rclone_api.http_server import HttpServer
|
201
|
+
|
202
|
+
assert isinstance(self.server, HttpServer)
|
203
|
+
path = self._to_remote_path(path)
|
204
|
+
err = self.server.list(path)
|
205
|
+
# Make faster.
|
206
|
+
return isinstance(err, Exception) and self.exists(path)
|
207
|
+
|
208
|
+
def ls(self, path: Path | str) -> tuple[list[str], list[str]]:
|
209
|
+
from rclone_api.http_server import HttpServer
|
210
|
+
|
211
|
+
assert isinstance(self.server, HttpServer)
|
212
|
+
path = self._to_remote_path(path)
|
213
|
+
err = self.server.list(path)
|
214
|
+
if isinstance(err, Exception):
|
215
|
+
raise FileNotFoundError(f"File not found: {path}, because of {err}")
|
216
|
+
return err
|
217
|
+
|
218
|
+
def get_path(self, path: str) -> "FSPath":
|
219
|
+
return FSPath(self, path)
|
220
|
+
|
221
|
+
def dispose(self) -> None:
|
222
|
+
if self.shutdown or not self.server:
|
223
|
+
return
|
224
|
+
self.shutdown = True
|
225
|
+
self.server.shutdown()
|
226
|
+
|
227
|
+
def __del__(self) -> None:
|
228
|
+
self.dispose()
|
229
|
+
|
230
|
+
|
231
|
+
class FSPath:
|
232
|
+
def __init__(self, fs: FS, path: str) -> None:
|
233
|
+
self.fs: FS = fs
|
234
|
+
self.path: str = path
|
235
|
+
self.fs_holder: FS | None = None
|
236
|
+
|
237
|
+
def set_owner(self) -> None:
|
238
|
+
self.fs_holder = self.fs
|
239
|
+
|
240
|
+
def is_real_fs(self) -> bool:
|
241
|
+
return isinstance(self.fs, RealFS)
|
242
|
+
|
243
|
+
def read_text(self) -> str:
|
244
|
+
data = self.read_bytes()
|
245
|
+
return data.decode("utf-8")
|
246
|
+
|
247
|
+
def read_bytes(self) -> bytes:
|
248
|
+
data: bytes | None = None
|
249
|
+
try:
|
250
|
+
data = self.fs.read_bytes(self.path)
|
251
|
+
return data
|
252
|
+
except Exception as e:
|
253
|
+
raise FileNotFoundError(f"File not found: {self.path}, because of {e}")
|
254
|
+
|
255
|
+
def exists(self) -> bool:
|
256
|
+
return self.fs.exists(self.path)
|
257
|
+
|
258
|
+
def __str__(self) -> str:
|
259
|
+
return self.path
|
260
|
+
|
261
|
+
def __repr__(self) -> str:
|
262
|
+
return f"FSPath({self.path})"
|
263
|
+
|
264
|
+
def __enter__(self) -> "FSPath":
|
265
|
+
if self.fs_holder is not None:
|
266
|
+
warnings.warn("This operation is reserved for the cwd returned by FS")
|
267
|
+
return self
|
268
|
+
|
269
|
+
def __exit__(self, exc_type, exc_value, traceback) -> None:
|
270
|
+
if self.fs_holder is not None:
|
271
|
+
self.fs_holder.dispose()
|
272
|
+
self.fs_holder = None
|
273
|
+
|
274
|
+
def mkdir(self, parents=True, exist_ok=True) -> None:
|
275
|
+
self.fs.mkdir(self.path, parents=parents, exist_ok=exist_ok)
|
276
|
+
|
277
|
+
def walk(
|
278
|
+
self,
|
279
|
+
) -> "Generator[tuple[FSPath, list[str], list[str]], None, None]":
|
280
|
+
from rclone_api.fs.walk import os_walk
|
281
|
+
|
282
|
+
return os_walk(self)
|
283
|
+
|
284
|
+
def relative_to(self, other: "FSPath") -> "FSPath":
|
285
|
+
p = Path(self.path).relative_to(other.path)
|
286
|
+
return FSPath(self.fs, p.as_posix())
|
287
|
+
|
288
|
+
def write_text(self, data: str, encoding: str | None = None) -> None:
|
289
|
+
if encoding is None:
|
290
|
+
encoding = "utf-8"
|
291
|
+
self.write_bytes(data.encode(encoding))
|
292
|
+
|
293
|
+
def write_bytes(self, data: bytes) -> None:
|
294
|
+
self.fs.write_binary(self.path, data)
|
295
|
+
|
296
|
+
def rmtree(self, ignore_errors=False) -> None:
|
297
|
+
assert self.exists(), f"Path does not exist: {self.path}"
|
298
|
+
# check fs is RealFS
|
299
|
+
assert isinstance(self.fs, RealFS)
|
300
|
+
shutil.rmtree(self.path, ignore_errors=ignore_errors)
|
301
|
+
|
302
|
+
def lspaths(self) -> "tuple[list[FSPath], list[FSPath]]":
|
303
|
+
filenames, dirnames = self.ls()
|
304
|
+
fpaths: list[FSPath] = [self / name for name in filenames]
|
305
|
+
dpaths: list[FSPath] = [self / name for name in dirnames]
|
306
|
+
return fpaths, dpaths
|
307
|
+
|
308
|
+
def ls(self) -> tuple[list[str], list[str]]:
|
309
|
+
filenames: list[str]
|
310
|
+
dirnames: list[str]
|
311
|
+
filenames, dirnames = self.fs.ls(self.path)
|
312
|
+
return filenames, dirnames
|
313
|
+
|
314
|
+
@property
|
315
|
+
def name(self) -> str:
|
316
|
+
return Path(self.path).name
|
317
|
+
|
318
|
+
@property
|
319
|
+
def parent(self) -> "FSPath":
|
320
|
+
parent_path = Path(self.path).parent
|
321
|
+
parent_str = parent_path.as_posix()
|
322
|
+
return FSPath(self.fs, parent_str)
|
323
|
+
|
324
|
+
def __truediv__(self, other: str) -> "FSPath":
|
325
|
+
new_path = Path(self.path) / other
|
326
|
+
return FSPath(self.fs, new_path.as_posix())
|
327
|
+
|
328
|
+
# hashable
|
329
|
+
def __hash__(self) -> int:
|
330
|
+
return hash(f"{repr(self.fs)}:{self.path}")
|
rclone_api/fs/walk.py
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
from typing import Generator
|
2
|
+
|
3
|
+
from rclone_api.fs.filesystem import FSPath, logger
|
4
|
+
|
5
|
+
|
6
|
+
def os_walk(
|
7
|
+
self: FSPath,
|
8
|
+
) -> Generator[tuple[FSPath, list[str], list[str]], None, None]:
|
9
|
+
root_path = self
|
10
|
+
stack: list[str] = [self.path]
|
11
|
+
|
12
|
+
while stack:
|
13
|
+
current_dir = root_path / stack.pop()
|
14
|
+
try:
|
15
|
+
filenames, dirnames = current_dir.ls()
|
16
|
+
except Exception as e:
|
17
|
+
logger.warning(f"Unable to list directory {current_dir}: {e}")
|
18
|
+
continue
|
19
|
+
|
20
|
+
yield current_dir, dirnames, filenames
|
21
|
+
|
22
|
+
# Add subdirectories to stack for further traversal
|
23
|
+
for dirname in reversed(dirnames):
|
24
|
+
stack.append((current_dir / dirname).path)
|
@@ -40,7 +40,8 @@ rclone_api/detail/copy_file_parts_resumable.py,sha256=RoUWV2eBWEvuuTfsvrz5BhtvX3
|
|
40
40
|
rclone_api/detail/walk.py,sha256=-54NVE8EJcCstwDoaC_UtHm73R2HrZwVwQmsnv55xNU,3369
|
41
41
|
rclone_api/experimental/flags.py,sha256=qCVD--fSTmzlk9hloRLr0q9elzAOFzPsvVpKM3aB1Mk,2739
|
42
42
|
rclone_api/experimental/flags_base.py,sha256=ajU_czkTcAxXYU-SlmiCfHY7aCQGHvpCLqJ-Z8uZLk0,2102
|
43
|
-
rclone_api/fs/filesystem.py,sha256=
|
43
|
+
rclone_api/fs/filesystem.py,sha256=NjAe5T79YOUpE8cwKmFVQTjwdu-2iIJTXotV4iEwjlo,10617
|
44
|
+
rclone_api/fs/walk.py,sha256=usNCSGCXiP50Ijx9uTxGb8MuZPqFazzQ-746R7KsbP4,722
|
44
45
|
rclone_api/s3/api.py,sha256=HpheMOGHcCc0CyNdv0zvB0S92g312urjRdssRrkdpb8,4162
|
45
46
|
rclone_api/s3/basic_ops.py,sha256=hK3366xhVEzEcjz9Gk_8lFx6MRceAk72cax6mUrr6ko,2104
|
46
47
|
rclone_api/s3/chunk_task.py,sha256=waEYe-iYQ1_BR3NCS4BrzVrK9UANvH1EcbXx2I6Z_NM,6839
|
@@ -55,9 +56,9 @@ rclone_api/s3/multipart/upload_parts_inline.py,sha256=V7syKjFyVIe4U9Ahl5XgqVTzt9
|
|
55
56
|
rclone_api/s3/multipart/upload_parts_resumable.py,sha256=6-nlMclS8jyVvMvFbQDcZOX9MY1WbCcKA_s9bwuYxnk,9793
|
56
57
|
rclone_api/s3/multipart/upload_parts_server_side_merge.py,sha256=Fp2pdrs5dONQI9LkfNolgAGj1-Z2V1SsRd0r0sreuXI,18040
|
57
58
|
rclone_api/s3/multipart/upload_state.py,sha256=f-Aq2NqtAaMUMhYitlICSNIxCKurWAl2gDEUVizLIqw,6019
|
58
|
-
rclone_api-1.5.
|
59
|
-
rclone_api-1.5.
|
60
|
-
rclone_api-1.5.
|
61
|
-
rclone_api-1.5.
|
62
|
-
rclone_api-1.5.
|
63
|
-
rclone_api-1.5.
|
59
|
+
rclone_api-1.5.54.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
60
|
+
rclone_api-1.5.54.dist-info/METADATA,sha256=FTf3dzDB3CbF3TsUKdqg-q7M5SVxQX7fExEcXmwb2go,37305
|
61
|
+
rclone_api-1.5.54.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
62
|
+
rclone_api-1.5.54.dist-info/entry_points.txt,sha256=ognh2e11HTjn73_KL5MWI67pBKS2jekBi-QTiRXySXA,316
|
63
|
+
rclone_api-1.5.54.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
64
|
+
rclone_api-1.5.54.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|