megfile 4.2.4__py3-none-any.whl → 4.2.5__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.
- megfile/__init__.py +5 -0
- megfile/fs.py +14 -1
- megfile/fs_path.py +46 -9
- megfile/interfaces.py +33 -0
- megfile/lib/joinpath.py +13 -0
- megfile/lib/s3_buffered_writer.py +13 -0
- megfile/lib/s3_limited_seekable_writer.py +2 -0
- megfile/s3_path.py +4 -1
- megfile/sftp2_path.py +9 -3
- megfile/sftp_path.py +1 -1
- megfile/version.py +1 -1
- megfile/webdav.py +552 -0
- megfile/webdav_path.py +958 -0
- {megfile-4.2.4.dist-info → megfile-4.2.5.dist-info}/METADATA +4 -1
- {megfile-4.2.4.dist-info → megfile-4.2.5.dist-info}/RECORD +20 -18
- {megfile-4.2.4.dist-info → megfile-4.2.5.dist-info}/WHEEL +0 -0
- {megfile-4.2.4.dist-info → megfile-4.2.5.dist-info}/entry_points.txt +0 -0
- {megfile-4.2.4.dist-info → megfile-4.2.5.dist-info}/licenses/LICENSE +0 -0
- {megfile-4.2.4.dist-info → megfile-4.2.5.dist-info}/licenses/LICENSE.pyre +0 -0
- {megfile-4.2.4.dist-info → megfile-4.2.5.dist-info}/top_level.txt +0 -0
megfile/webdav.py
ADDED
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
from logging import getLogger as get_logger
|
|
2
|
+
from typing import IO, BinaryIO, Callable, Iterator, List, Optional, Tuple
|
|
3
|
+
|
|
4
|
+
from megfile.interfaces import FileEntry, PathLike, StatResult
|
|
5
|
+
from megfile.lib.compat import fspath
|
|
6
|
+
from megfile.lib.joinpath import uri_join
|
|
7
|
+
from megfile.webdav_path import (
|
|
8
|
+
WebdavPath,
|
|
9
|
+
is_webdav,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
_logger = get_logger(__name__)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"is_webdav",
|
|
16
|
+
"webdav_glob",
|
|
17
|
+
"webdav_iglob",
|
|
18
|
+
"webdav_glob_stat",
|
|
19
|
+
"webdav_resolve",
|
|
20
|
+
"webdav_download",
|
|
21
|
+
"webdav_upload",
|
|
22
|
+
"webdav_path_join",
|
|
23
|
+
"webdav_exists",
|
|
24
|
+
"webdav_getmtime",
|
|
25
|
+
"webdav_getsize",
|
|
26
|
+
"webdav_isdir",
|
|
27
|
+
"webdav_isfile",
|
|
28
|
+
"webdav_listdir",
|
|
29
|
+
"webdav_load_from",
|
|
30
|
+
"webdav_makedirs",
|
|
31
|
+
"webdav_realpath",
|
|
32
|
+
"webdav_rename",
|
|
33
|
+
"webdav_move",
|
|
34
|
+
"webdav_remove",
|
|
35
|
+
"webdav_scan",
|
|
36
|
+
"webdav_scan_stat",
|
|
37
|
+
"webdav_scandir",
|
|
38
|
+
"webdav_stat",
|
|
39
|
+
"webdav_unlink",
|
|
40
|
+
"webdav_walk",
|
|
41
|
+
"webdav_getmd5",
|
|
42
|
+
"webdav_save_as",
|
|
43
|
+
"webdav_open",
|
|
44
|
+
"webdav_absolute",
|
|
45
|
+
"webdav_rmdir",
|
|
46
|
+
"webdav_copy",
|
|
47
|
+
"webdav_sync",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def webdav_glob(
|
|
52
|
+
path: PathLike, recursive: bool = True, missing_ok: bool = True
|
|
53
|
+
) -> List[str]:
|
|
54
|
+
"""Return path list in ascending alphabetical order,
|
|
55
|
+
in which path matches glob pattern
|
|
56
|
+
|
|
57
|
+
:param path: Given path
|
|
58
|
+
:param recursive: If False, `**` will not search directory recursively
|
|
59
|
+
:param missing_ok: If False and target path doesn't match any file,
|
|
60
|
+
raise FileNotFoundError
|
|
61
|
+
:returns: A list contains paths match `pathname`
|
|
62
|
+
"""
|
|
63
|
+
return list(
|
|
64
|
+
sorted(webdav_iglob(path=path, recursive=recursive, missing_ok=missing_ok))
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def webdav_glob_stat(
|
|
69
|
+
path: PathLike, recursive: bool = True, missing_ok: bool = True
|
|
70
|
+
) -> Iterator[FileEntry]:
|
|
71
|
+
"""Return a list contains tuples of path and file stat, in ascending alphabetical
|
|
72
|
+
order, in which path matches glob pattern
|
|
73
|
+
|
|
74
|
+
:param path: Given path
|
|
75
|
+
:param recursive: If False, `**` will not search directory recursively
|
|
76
|
+
:param missing_ok: If False and target path doesn't match any file,
|
|
77
|
+
raise FileNotFoundError
|
|
78
|
+
:returns: A list contains tuples of path and file stat,
|
|
79
|
+
in which paths match `pathname`
|
|
80
|
+
"""
|
|
81
|
+
for entry in WebdavPath(path).glob_stat(
|
|
82
|
+
pattern="", recursive=recursive, missing_ok=missing_ok
|
|
83
|
+
):
|
|
84
|
+
yield entry
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def webdav_iglob(
|
|
88
|
+
path: PathLike, recursive: bool = True, missing_ok: bool = True
|
|
89
|
+
) -> Iterator[str]:
|
|
90
|
+
"""Return path iterator in ascending alphabetical order,
|
|
91
|
+
in which path matches glob pattern
|
|
92
|
+
|
|
93
|
+
:param path: Given path
|
|
94
|
+
:param recursive: If False, `**` will not search directory recursively
|
|
95
|
+
:param missing_ok: If False and target path doesn't match any file,
|
|
96
|
+
raise FileNotFoundError
|
|
97
|
+
:returns: An iterator contains paths match `pathname`
|
|
98
|
+
"""
|
|
99
|
+
for path in WebdavPath(path).iglob(
|
|
100
|
+
pattern="", recursive=recursive, missing_ok=missing_ok
|
|
101
|
+
):
|
|
102
|
+
yield path.path_with_protocol
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def webdav_resolve(path: PathLike, strict=False) -> "str":
|
|
106
|
+
"""Return the absolute path
|
|
107
|
+
|
|
108
|
+
:param path: Given path
|
|
109
|
+
:param strict: Ignored for WebDAV
|
|
110
|
+
:return: Absolute path
|
|
111
|
+
"""
|
|
112
|
+
return WebdavPath(path).resolve(strict).path_with_protocol
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def webdav_download(
|
|
116
|
+
src_url: PathLike,
|
|
117
|
+
dst_url: PathLike,
|
|
118
|
+
callback: Optional[Callable[[int], None]] = None,
|
|
119
|
+
followlinks: bool = False,
|
|
120
|
+
overwrite: bool = True,
|
|
121
|
+
):
|
|
122
|
+
"""
|
|
123
|
+
Downloads a file from WebDAV to local filesystem.
|
|
124
|
+
|
|
125
|
+
:param src_url: source WebDAV path
|
|
126
|
+
:param dst_url: target fs path
|
|
127
|
+
:param callback: Called periodically during copy
|
|
128
|
+
:param followlinks: Ignored for WebDAV
|
|
129
|
+
:param overwrite: whether or not overwrite file when exists, default is True
|
|
130
|
+
"""
|
|
131
|
+
from megfile.fs import is_fs
|
|
132
|
+
from megfile.fs_path import FSPath
|
|
133
|
+
|
|
134
|
+
if not is_fs(dst_url):
|
|
135
|
+
raise OSError(f"dst_url is not fs path: {dst_url}")
|
|
136
|
+
if not is_webdav(src_url) and not isinstance(src_url, WebdavPath):
|
|
137
|
+
raise OSError(f"src_url is not webdav path: {src_url}")
|
|
138
|
+
|
|
139
|
+
dst_path = FSPath(dst_url)
|
|
140
|
+
if not overwrite and dst_path.exists():
|
|
141
|
+
return
|
|
142
|
+
|
|
143
|
+
if isinstance(src_url, WebdavPath):
|
|
144
|
+
src_path: WebdavPath = src_url
|
|
145
|
+
else:
|
|
146
|
+
src_path: WebdavPath = WebdavPath(src_url)
|
|
147
|
+
|
|
148
|
+
if src_path.is_dir():
|
|
149
|
+
raise IsADirectoryError("Is a directory: %r" % src_url)
|
|
150
|
+
if str(dst_url).endswith("/"):
|
|
151
|
+
raise IsADirectoryError("Is a directory: %r" % dst_url)
|
|
152
|
+
|
|
153
|
+
dst_path.parent.makedirs(exist_ok=True)
|
|
154
|
+
|
|
155
|
+
# Download file
|
|
156
|
+
with src_path.open("rb") as fsrc:
|
|
157
|
+
with dst_path.open("wb") as fdst:
|
|
158
|
+
if callback:
|
|
159
|
+
bytes_written = 0
|
|
160
|
+
while True:
|
|
161
|
+
chunk = fsrc.read(8192)
|
|
162
|
+
if not chunk:
|
|
163
|
+
break
|
|
164
|
+
fdst.write(chunk)
|
|
165
|
+
callback(len(chunk))
|
|
166
|
+
bytes_written += len(chunk)
|
|
167
|
+
else:
|
|
168
|
+
fdst.write(fsrc.read())
|
|
169
|
+
|
|
170
|
+
# Preserve modification time
|
|
171
|
+
src_stat = src_path.stat()
|
|
172
|
+
dst_path.utime(src_stat.st_atime, src_stat.st_mtime)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def webdav_upload(
|
|
176
|
+
src_url: PathLike,
|
|
177
|
+
dst_url: PathLike,
|
|
178
|
+
callback: Optional[Callable[[int], None]] = None,
|
|
179
|
+
followlinks: bool = False,
|
|
180
|
+
overwrite: bool = True,
|
|
181
|
+
):
|
|
182
|
+
"""
|
|
183
|
+
Uploads a file from local filesystem to WebDAV server.
|
|
184
|
+
|
|
185
|
+
:param src_url: source fs path
|
|
186
|
+
:param dst_url: target WebDAV path
|
|
187
|
+
:param callback: Called periodically during copy
|
|
188
|
+
:param followlinks: Follow symlinks for local files
|
|
189
|
+
:param overwrite: whether or not overwrite file when exists, default is True
|
|
190
|
+
"""
|
|
191
|
+
import os
|
|
192
|
+
|
|
193
|
+
from megfile.fs import is_fs
|
|
194
|
+
from megfile.fs_path import FSPath
|
|
195
|
+
|
|
196
|
+
if not is_fs(src_url):
|
|
197
|
+
raise OSError(f"src_url is not fs path: {src_url}")
|
|
198
|
+
if not is_webdav(dst_url) and not isinstance(dst_url, WebdavPath):
|
|
199
|
+
raise OSError(f"dst_url is not webdav path: {dst_url}")
|
|
200
|
+
|
|
201
|
+
if followlinks and os.path.islink(src_url):
|
|
202
|
+
src_url = os.readlink(src_url)
|
|
203
|
+
if os.path.isdir(src_url):
|
|
204
|
+
raise IsADirectoryError("Is a directory: %r" % src_url)
|
|
205
|
+
if str(dst_url).endswith("/"):
|
|
206
|
+
raise IsADirectoryError("Is a directory: %r" % dst_url)
|
|
207
|
+
|
|
208
|
+
src_path = FSPath(src_url)
|
|
209
|
+
if isinstance(dst_url, WebdavPath):
|
|
210
|
+
dst_path: WebdavPath = dst_url
|
|
211
|
+
else:
|
|
212
|
+
dst_path: WebdavPath = WebdavPath(dst_url)
|
|
213
|
+
|
|
214
|
+
if not overwrite and dst_path.exists():
|
|
215
|
+
return
|
|
216
|
+
|
|
217
|
+
dst_path.parent.makedirs(exist_ok=True)
|
|
218
|
+
|
|
219
|
+
# Upload file
|
|
220
|
+
with src_path.open("rb") as fsrc:
|
|
221
|
+
with dst_path.open("wb") as fdst:
|
|
222
|
+
if callback:
|
|
223
|
+
while True:
|
|
224
|
+
chunk = fsrc.read(8192)
|
|
225
|
+
if not chunk:
|
|
226
|
+
break
|
|
227
|
+
fdst.write(chunk)
|
|
228
|
+
callback(len(chunk))
|
|
229
|
+
else:
|
|
230
|
+
fdst.write(fsrc.read())
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def webdav_path_join(path: PathLike, *other_paths: PathLike) -> str:
|
|
234
|
+
"""
|
|
235
|
+
Concat 2 or more path to a complete path
|
|
236
|
+
|
|
237
|
+
:param path: Given path
|
|
238
|
+
:param other_paths: Paths to be concatenated
|
|
239
|
+
:returns: Concatenated complete path
|
|
240
|
+
"""
|
|
241
|
+
return uri_join(fspath(path), *map(fspath, other_paths))
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def webdav_exists(path: PathLike, followlinks: bool = False) -> bool:
|
|
245
|
+
"""
|
|
246
|
+
Test if the path exists
|
|
247
|
+
|
|
248
|
+
:param path: Given path
|
|
249
|
+
:param followlinks: Ignored for WebDAV
|
|
250
|
+
:returns: True if the path exists, else False
|
|
251
|
+
"""
|
|
252
|
+
return WebdavPath(path).exists(followlinks)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def webdav_getmtime(path: PathLike, follow_symlinks: bool = False) -> float:
|
|
256
|
+
"""
|
|
257
|
+
Get last-modified time of the file on the given path (in Unix timestamp format).
|
|
258
|
+
|
|
259
|
+
:param path: Given path
|
|
260
|
+
:param follow_symlinks: Ignored for WebDAV
|
|
261
|
+
:returns: last-modified time
|
|
262
|
+
"""
|
|
263
|
+
return WebdavPath(path).getmtime(follow_symlinks)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def webdav_getsize(path: PathLike, follow_symlinks: bool = False) -> int:
|
|
267
|
+
"""
|
|
268
|
+
Get file size on the given file path (in bytes).
|
|
269
|
+
|
|
270
|
+
:param path: Given path
|
|
271
|
+
:param follow_symlinks: Ignored for WebDAV
|
|
272
|
+
:returns: File size
|
|
273
|
+
"""
|
|
274
|
+
return WebdavPath(path).getsize(follow_symlinks)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def webdav_isdir(path: PathLike, followlinks: bool = False) -> bool:
|
|
278
|
+
"""
|
|
279
|
+
Test if a path is directory
|
|
280
|
+
|
|
281
|
+
:param path: Given path
|
|
282
|
+
:param followlinks: Ignored for WebDAV
|
|
283
|
+
:returns: True if the path is a directory, else False
|
|
284
|
+
"""
|
|
285
|
+
return WebdavPath(path).is_dir(followlinks)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def webdav_isfile(path: PathLike, followlinks: bool = False) -> bool:
|
|
289
|
+
"""
|
|
290
|
+
Test if a path is file
|
|
291
|
+
|
|
292
|
+
:param path: Given path
|
|
293
|
+
:param followlinks: Ignored for WebDAV
|
|
294
|
+
:returns: True if the path is a file, else False
|
|
295
|
+
"""
|
|
296
|
+
return WebdavPath(path).is_file(followlinks)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def webdav_listdir(path: PathLike) -> List[str]:
|
|
300
|
+
"""
|
|
301
|
+
Get all contents of given WebDAV path.
|
|
302
|
+
The result is in ascending alphabetical order.
|
|
303
|
+
|
|
304
|
+
:param path: Given path
|
|
305
|
+
:returns: All contents in ascending alphabetical order
|
|
306
|
+
"""
|
|
307
|
+
return WebdavPath(path).listdir()
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def webdav_load_from(path: PathLike) -> BinaryIO:
|
|
311
|
+
"""Read all content on specified path and write into memory
|
|
312
|
+
|
|
313
|
+
User should close the BinaryIO manually
|
|
314
|
+
|
|
315
|
+
:param path: Given path
|
|
316
|
+
:returns: Binary stream
|
|
317
|
+
"""
|
|
318
|
+
return WebdavPath(path).load()
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def webdav_makedirs(
|
|
322
|
+
path: PathLike, mode=0o777, parents: bool = False, exist_ok: bool = False
|
|
323
|
+
):
|
|
324
|
+
"""
|
|
325
|
+
Make a directory on WebDAV, including parent directory.
|
|
326
|
+
|
|
327
|
+
:param path: Given path
|
|
328
|
+
:param mode: Ignored for WebDAV
|
|
329
|
+
:param parents: If parents is true, any missing parents are created
|
|
330
|
+
:param exist_ok: If False and target directory exists, raise FileExistsError
|
|
331
|
+
"""
|
|
332
|
+
return WebdavPath(path).mkdir(mode, parents, exist_ok)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def webdav_realpath(path: PathLike) -> str:
|
|
336
|
+
"""Return the real path of given path
|
|
337
|
+
|
|
338
|
+
:param path: Given path
|
|
339
|
+
:returns: Real path of given path
|
|
340
|
+
"""
|
|
341
|
+
return WebdavPath(path).realpath()
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def webdav_rename(
|
|
345
|
+
src_path: PathLike, dst_path: PathLike, overwrite: bool = True
|
|
346
|
+
) -> "WebdavPath":
|
|
347
|
+
"""
|
|
348
|
+
Rename file on WebDAV
|
|
349
|
+
|
|
350
|
+
:param src_path: Given path
|
|
351
|
+
:param dst_path: Given destination path
|
|
352
|
+
:param overwrite: whether or not overwrite file when exists
|
|
353
|
+
"""
|
|
354
|
+
return WebdavPath(src_path).rename(dst_path, overwrite)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def webdav_move(
|
|
358
|
+
src_path: PathLike, dst_path: PathLike, overwrite: bool = True
|
|
359
|
+
) -> "WebdavPath":
|
|
360
|
+
"""
|
|
361
|
+
Move file on WebDAV
|
|
362
|
+
|
|
363
|
+
:param src_path: Given path
|
|
364
|
+
:param dst_path: Given destination path
|
|
365
|
+
:param overwrite: whether or not overwrite file when exists
|
|
366
|
+
"""
|
|
367
|
+
return WebdavPath(src_path).replace(dst_path, overwrite)
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def webdav_remove(path: PathLike, missing_ok: bool = False) -> None:
|
|
371
|
+
"""
|
|
372
|
+
Remove the file or directory on WebDAV
|
|
373
|
+
|
|
374
|
+
:param path: Given path
|
|
375
|
+
:param missing_ok: if False and target file/directory not exists,
|
|
376
|
+
raise FileNotFoundError
|
|
377
|
+
"""
|
|
378
|
+
return WebdavPath(path).remove(missing_ok)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def webdav_scan(
|
|
382
|
+
path: PathLike, missing_ok: bool = True, followlinks: bool = False
|
|
383
|
+
) -> Iterator[str]:
|
|
384
|
+
"""
|
|
385
|
+
Iteratively traverse only files in given directory, in alphabetical order.
|
|
386
|
+
|
|
387
|
+
:param path: Given path
|
|
388
|
+
:param missing_ok: If False and there's no file in the directory,
|
|
389
|
+
raise FileNotFoundError
|
|
390
|
+
:param followlinks: Ignored for WebDAV
|
|
391
|
+
:returns: A file path generator
|
|
392
|
+
"""
|
|
393
|
+
return WebdavPath(path).scan(missing_ok, followlinks)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def webdav_scan_stat(
|
|
397
|
+
path: PathLike, missing_ok: bool = True, followlinks: bool = False
|
|
398
|
+
) -> Iterator[FileEntry]:
|
|
399
|
+
"""
|
|
400
|
+
Iteratively traverse only files in given directory, in alphabetical order.
|
|
401
|
+
|
|
402
|
+
:param path: Given path
|
|
403
|
+
:param missing_ok: If False and there's no file in the directory,
|
|
404
|
+
raise FileNotFoundError
|
|
405
|
+
:param followlinks: Ignored for WebDAV
|
|
406
|
+
:returns: A file path generator yielding FileEntry objects
|
|
407
|
+
"""
|
|
408
|
+
return WebdavPath(path).scan_stat(missing_ok, followlinks)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def webdav_scandir(path: PathLike) -> Iterator[FileEntry]:
|
|
412
|
+
"""
|
|
413
|
+
Get all content of given file path.
|
|
414
|
+
|
|
415
|
+
:param path: Given path
|
|
416
|
+
:returns: An iterator contains all contents
|
|
417
|
+
"""
|
|
418
|
+
return WebdavPath(path).scandir()
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def webdav_stat(path: PathLike, follow_symlinks=True) -> StatResult:
|
|
422
|
+
"""
|
|
423
|
+
Get StatResult of file on WebDAV
|
|
424
|
+
|
|
425
|
+
:param path: Given path
|
|
426
|
+
:param follow_symlinks: Ignored for WebDAV
|
|
427
|
+
:returns: StatResult
|
|
428
|
+
"""
|
|
429
|
+
return WebdavPath(path).stat(follow_symlinks)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
def webdav_unlink(path: PathLike, missing_ok: bool = False) -> None:
|
|
433
|
+
"""
|
|
434
|
+
Remove the file on WebDAV
|
|
435
|
+
|
|
436
|
+
:param path: Given path
|
|
437
|
+
:param missing_ok: if False and target file not exists, raise FileNotFoundError
|
|
438
|
+
"""
|
|
439
|
+
return WebdavPath(path).unlink(missing_ok)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def webdav_walk(
|
|
443
|
+
path: PathLike, followlinks: bool = False
|
|
444
|
+
) -> Iterator[Tuple[str, List[str], List[str]]]:
|
|
445
|
+
"""
|
|
446
|
+
Generate the file names in a directory tree by walking the tree top-down.
|
|
447
|
+
|
|
448
|
+
:param path: Given path
|
|
449
|
+
:param followlinks: Ignored for WebDAV
|
|
450
|
+
:returns: A 3-tuple generator (root, dirs, files)
|
|
451
|
+
"""
|
|
452
|
+
return WebdavPath(path).walk(followlinks)
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def webdav_getmd5(path: PathLike, recalculate: bool = False, followlinks: bool = False):
|
|
456
|
+
"""
|
|
457
|
+
Calculate the md5 value of the file
|
|
458
|
+
|
|
459
|
+
:param path: Given path
|
|
460
|
+
:param recalculate: Ignored for WebDAV
|
|
461
|
+
:param followlinks: Ignored for WebDAV
|
|
462
|
+
:returns: md5 of file
|
|
463
|
+
"""
|
|
464
|
+
return WebdavPath(path).md5(recalculate, followlinks)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def webdav_save_as(file_object: BinaryIO, path: PathLike):
|
|
468
|
+
"""Write the opened binary stream to path
|
|
469
|
+
|
|
470
|
+
:param file_object: stream to be read
|
|
471
|
+
:param path: Given path
|
|
472
|
+
"""
|
|
473
|
+
return WebdavPath(path).save(file_object)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def webdav_open(
|
|
477
|
+
path: PathLike,
|
|
478
|
+
mode: str = "r",
|
|
479
|
+
*,
|
|
480
|
+
buffering=-1,
|
|
481
|
+
encoding: Optional[str] = None,
|
|
482
|
+
errors: Optional[str] = None,
|
|
483
|
+
**kwargs,
|
|
484
|
+
) -> IO:
|
|
485
|
+
"""Open a file on the path.
|
|
486
|
+
|
|
487
|
+
:param path: Given path
|
|
488
|
+
:param mode: Mode to open file
|
|
489
|
+
:param buffering: buffering policy
|
|
490
|
+
:param encoding: encoding for text mode
|
|
491
|
+
:param errors: error handling for text mode
|
|
492
|
+
:returns: File-Like object
|
|
493
|
+
"""
|
|
494
|
+
return WebdavPath(path).open(
|
|
495
|
+
mode, buffering=buffering, encoding=encoding, errors=errors
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def webdav_absolute(path: PathLike) -> "WebdavPath":
|
|
500
|
+
"""
|
|
501
|
+
Make the path absolute
|
|
502
|
+
|
|
503
|
+
:param path: Given path
|
|
504
|
+
:returns: Absolute path
|
|
505
|
+
"""
|
|
506
|
+
return WebdavPath(path).absolute()
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
def webdav_rmdir(path: PathLike):
|
|
510
|
+
"""
|
|
511
|
+
Remove this directory. The directory must be empty.
|
|
512
|
+
|
|
513
|
+
:param path: Given path
|
|
514
|
+
"""
|
|
515
|
+
return WebdavPath(path).rmdir()
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
def webdav_copy(
|
|
519
|
+
src_path: PathLike,
|
|
520
|
+
dst_path: PathLike,
|
|
521
|
+
callback: Optional[Callable[[int], None]] = None,
|
|
522
|
+
followlinks: bool = False,
|
|
523
|
+
overwrite: bool = True,
|
|
524
|
+
):
|
|
525
|
+
"""
|
|
526
|
+
Copy the file to the given destination path.
|
|
527
|
+
|
|
528
|
+
:param src_path: Given path
|
|
529
|
+
:param dst_path: The destination path to copy the file to.
|
|
530
|
+
:param callback: An optional callback function
|
|
531
|
+
:param followlinks: Ignored for WebDAV
|
|
532
|
+
:param overwrite: whether to overwrite existing file
|
|
533
|
+
"""
|
|
534
|
+
return WebdavPath(src_path).copy(dst_path, callback, followlinks, overwrite)
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
def webdav_sync(
|
|
538
|
+
src_path: PathLike,
|
|
539
|
+
dst_path: PathLike,
|
|
540
|
+
followlinks: bool = False,
|
|
541
|
+
force: bool = False,
|
|
542
|
+
overwrite: bool = True,
|
|
543
|
+
):
|
|
544
|
+
"""Copy file/directory on src_path to dst_path
|
|
545
|
+
|
|
546
|
+
:param src_path: Given path
|
|
547
|
+
:param dst_path: Given destination path
|
|
548
|
+
:param followlinks: Ignored for WebDAV
|
|
549
|
+
:param force: Sync file forcibly
|
|
550
|
+
:param overwrite: whether or not overwrite file when exists, default is True
|
|
551
|
+
"""
|
|
552
|
+
return WebdavPath(src_path).sync(dst_path, followlinks, force, overwrite)
|