rclone-api 1.5.13__py3-none-any.whl → 1.5.14__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 +1 -1
- rclone_api/filesystem.py +170 -0
- {rclone_api-1.5.13.dist-info → rclone_api-1.5.14.dist-info}/METADATA +1 -1
- {rclone_api-1.5.13.dist-info → rclone_api-1.5.14.dist-info}/RECORD +8 -7
- {rclone_api-1.5.13.dist-info → rclone_api-1.5.14.dist-info}/WHEEL +0 -0
- {rclone_api-1.5.13.dist-info → rclone_api-1.5.14.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.5.13.dist-info → rclone_api-1.5.14.dist-info}/licenses/LICENSE +0 -0
- {rclone_api-1.5.13.dist-info → rclone_api-1.5.14.dist-info}/top_level.txt +0 -0
rclone_api/__init__.py
CHANGED
rclone_api/filesystem.py
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
import abc
|
2
|
+
import shutil
|
3
|
+
from pathlib import Path
|
4
|
+
|
5
|
+
|
6
|
+
class FileSystem(abc.ABC):
|
7
|
+
def __init__(self) -> None:
|
8
|
+
pass
|
9
|
+
|
10
|
+
@abc.abstractmethod
|
11
|
+
def copy(self, src: Path | str, dest: Path | str) -> None:
|
12
|
+
pass
|
13
|
+
|
14
|
+
@abc.abstractmethod
|
15
|
+
def read_binary(self, path: Path | str) -> bytes:
|
16
|
+
pass
|
17
|
+
|
18
|
+
@abc.abstractmethod
|
19
|
+
def exists(self, path: Path | str) -> bool:
|
20
|
+
pass
|
21
|
+
|
22
|
+
@abc.abstractmethod
|
23
|
+
def write_binary(self, path: Path | str, data: bytes) -> None:
|
24
|
+
pass
|
25
|
+
|
26
|
+
@abc.abstractmethod
|
27
|
+
def mkdir(self, path: str, parents=True, exist_ok=True) -> None:
|
28
|
+
pass
|
29
|
+
|
30
|
+
@abc.abstractmethod
|
31
|
+
def get_path(self, path: str) -> "FSPath":
|
32
|
+
pass
|
33
|
+
|
34
|
+
def read_text(self, path: Path | str) -> str:
|
35
|
+
utf = self.read_binary(path)
|
36
|
+
return utf.decode("utf-8")
|
37
|
+
|
38
|
+
def write_text(self, path: Path | str, data: str, encoding: str | None) -> None:
|
39
|
+
encoding = encoding or "utf-8"
|
40
|
+
utf = data.encode(encoding)
|
41
|
+
self.write_binary(path, utf)
|
42
|
+
|
43
|
+
|
44
|
+
class RealFileSystem(FileSystem):
|
45
|
+
|
46
|
+
@staticmethod
|
47
|
+
def get_real_path(path: Path | str) -> "FSPath":
|
48
|
+
path_str = Path(path).as_posix()
|
49
|
+
return FSPath(RealFileSystem(), path_str)
|
50
|
+
|
51
|
+
def __init__(self) -> None:
|
52
|
+
super().__init__()
|
53
|
+
|
54
|
+
def copy(self, src: Path | str, dest: Path | str) -> None:
|
55
|
+
shutil.copy(str(src), str(dest))
|
56
|
+
|
57
|
+
def read_binary(self, path: Path | str) -> bytes:
|
58
|
+
with open(path, "rb") as f:
|
59
|
+
return f.read()
|
60
|
+
|
61
|
+
def write_binary(self, path: Path | str, data: bytes) -> None:
|
62
|
+
with open(path, "wb") as f:
|
63
|
+
f.write(data)
|
64
|
+
|
65
|
+
def exists(self, path: Path | str) -> bool:
|
66
|
+
return Path(path).exists()
|
67
|
+
|
68
|
+
def mkdir(self, path: str, parents=True, exist_ok=True) -> None:
|
69
|
+
Path(path).mkdir(parents=parents, exist_ok=exist_ok)
|
70
|
+
|
71
|
+
def get_path(self, path: str) -> "FSPath":
|
72
|
+
return FSPath(self, path)
|
73
|
+
|
74
|
+
|
75
|
+
class RemoteFileSystem(FileSystem):
|
76
|
+
def __init__(self, rclone_conf: Path, src: str) -> None:
|
77
|
+
from rclone_api import HttpServer, Rclone
|
78
|
+
|
79
|
+
super().__init__()
|
80
|
+
self.rclone_conf = rclone_conf
|
81
|
+
self.rclone: Rclone = Rclone(rclone_conf)
|
82
|
+
self.server: HttpServer = self.rclone.serve_http(src=src)
|
83
|
+
self.shutdown = False
|
84
|
+
|
85
|
+
def _to_str(self, path: Path | str) -> str:
|
86
|
+
if isinstance(path, Path):
|
87
|
+
return path.as_posix()
|
88
|
+
return path
|
89
|
+
|
90
|
+
def copy(self, src: Path | str, dest: Path | str) -> None:
|
91
|
+
src = self._to_str(src)
|
92
|
+
dest = self._to_str(dest)
|
93
|
+
self.rclone.copy(src, dest)
|
94
|
+
|
95
|
+
def read_binary(self, path: Path | str) -> bytes:
|
96
|
+
path = self._to_str(path)
|
97
|
+
err = self.rclone.read_bytes(path)
|
98
|
+
if isinstance(err, Exception):
|
99
|
+
raise FileNotFoundError(f"File not found: {path}")
|
100
|
+
return err
|
101
|
+
|
102
|
+
def write_binary(self, path: Path | str, data: bytes) -> None:
|
103
|
+
path = self._to_str(path)
|
104
|
+
self.rclone.write_bytes(data, path)
|
105
|
+
|
106
|
+
def exists(self, path: Path | str) -> bool:
|
107
|
+
path = self._to_str(path)
|
108
|
+
return self.server.exists(path)
|
109
|
+
|
110
|
+
def mkdir(self, path: str, parents=True, exist_ok=True) -> None:
|
111
|
+
raise NotImplementedError("RemoteFileSystem does not support mkdir")
|
112
|
+
|
113
|
+
def get_path(self, path: str) -> "FSPath":
|
114
|
+
return FSPath(self, path)
|
115
|
+
|
116
|
+
def dispose(self) -> None:
|
117
|
+
if self.shutdown:
|
118
|
+
return
|
119
|
+
self.shutdown = True
|
120
|
+
self.server.shutdown()
|
121
|
+
|
122
|
+
def __del__(self) -> None:
|
123
|
+
self.dispose()
|
124
|
+
|
125
|
+
|
126
|
+
class FSPath:
|
127
|
+
def __init__(self, fs: FileSystem, path: str) -> None:
|
128
|
+
self.path = path
|
129
|
+
self.fs = fs
|
130
|
+
|
131
|
+
def read_text(self) -> str:
|
132
|
+
return self.fs.read_text(self.path)
|
133
|
+
|
134
|
+
def read_binary(self) -> bytes:
|
135
|
+
return self.fs.read_binary(self.path)
|
136
|
+
|
137
|
+
def exists(self) -> bool:
|
138
|
+
return self.fs.exists(self.path)
|
139
|
+
|
140
|
+
def __str__(self) -> str:
|
141
|
+
return self.path
|
142
|
+
|
143
|
+
def __repr__(self) -> str:
|
144
|
+
return f"FSPath({self.path})"
|
145
|
+
|
146
|
+
def mkdir(self, parents=True, exist_ok=True) -> None:
|
147
|
+
self.fs.mkdir(self.path, parents=parents, exist_ok=exist_ok)
|
148
|
+
|
149
|
+
def write_text(self, data: str, encoding: str | None = None) -> None:
|
150
|
+
self.fs.write_text(self.path, data, encoding=encoding)
|
151
|
+
|
152
|
+
def rmtree(self, ignore_errors=False) -> None:
|
153
|
+
assert self.exists(), f"Path does not exist: {self.path}"
|
154
|
+
# check fs is RealFileSystem
|
155
|
+
assert isinstance(self.fs, RealFileSystem)
|
156
|
+
shutil.rmtree(self.path, ignore_errors=ignore_errors)
|
157
|
+
|
158
|
+
@property
|
159
|
+
def name(self) -> str:
|
160
|
+
return Path(self.path).name
|
161
|
+
|
162
|
+
@property
|
163
|
+
def parent(self) -> "FSPath":
|
164
|
+
parent_path = Path(self.path).parent
|
165
|
+
parent_str = parent_path.as_posix()
|
166
|
+
return FSPath(self.fs, parent_str)
|
167
|
+
|
168
|
+
def __truediv__(self, other: str) -> "FSPath":
|
169
|
+
new_path = Path(self.path) / other
|
170
|
+
return FSPath(self.fs, new_path.as_posix())
|
@@ -1,4 +1,4 @@
|
|
1
|
-
rclone_api/__init__.py,sha256=
|
1
|
+
rclone_api/__init__.py,sha256=tzjjY0b-VfJ8BFYs15S3OApVwd7S1JEYbv0gUz-13aE,32421
|
2
2
|
rclone_api/cli.py,sha256=dibfAZIh0kXWsBbfp3onKLjyZXo54mTzDjUdzJlDlWo,231
|
3
3
|
rclone_api/completed_process.py,sha256=_IZ8IWK7DM1_tsbDEkH6wPZ-bbcrgf7A7smls854pmg,1775
|
4
4
|
rclone_api/config.py,sha256=f6jEAxVorGFr31oHfcsu5AJTtOJj2wR5tTSsbGGZuIw,2558
|
@@ -13,6 +13,7 @@ rclone_api/file_item.py,sha256=cH-AQYsxedhNPp4c8NHY1ad4Z7St4yf_VGbmiGD59no,1770
|
|
13
13
|
rclone_api/file_part.py,sha256=i6ByS5_sae8Eba-4imBVTxd-xKC8ExWy7NR8QGr0ors,6155
|
14
14
|
rclone_api/file_stream.py,sha256=_W3qnwCuigqA0hzXl2q5pAxSZDRaUSwet4BkT0lpnzs,1431
|
15
15
|
rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
16
|
+
rclone_api/filesystem.py,sha256=NlDlKWjX_WtaqjkwinMpqhaaU5QPkIrnTNKi7_k3tG0,4960
|
16
17
|
rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
|
17
18
|
rclone_api/http_server.py,sha256=p1_S9VAViVvGif6NA_rxrDgMqnOmPTxJaHQ7B43FK70,10431
|
18
19
|
rclone_api/install.py,sha256=Xb1BRn8rQcSpSd4dzmvIOELP2zM2DytUeIZ6jzv738A,2893
|
@@ -53,9 +54,9 @@ rclone_api/s3/multipart/upload_parts_inline.py,sha256=V7syKjFyVIe4U9Ahl5XgqVTzt9
|
|
53
54
|
rclone_api/s3/multipart/upload_parts_resumable.py,sha256=6-nlMclS8jyVvMvFbQDcZOX9MY1WbCcKA_s9bwuYxnk,9793
|
54
55
|
rclone_api/s3/multipart/upload_parts_server_side_merge.py,sha256=Fp2pdrs5dONQI9LkfNolgAGj1-Z2V1SsRd0r0sreuXI,18040
|
55
56
|
rclone_api/s3/multipart/upload_state.py,sha256=f-Aq2NqtAaMUMhYitlICSNIxCKurWAl2gDEUVizLIqw,6019
|
56
|
-
rclone_api-1.5.
|
57
|
-
rclone_api-1.5.
|
58
|
-
rclone_api-1.5.
|
59
|
-
rclone_api-1.5.
|
60
|
-
rclone_api-1.5.
|
61
|
-
rclone_api-1.5.
|
57
|
+
rclone_api-1.5.14.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
58
|
+
rclone_api-1.5.14.dist-info/METADATA,sha256=NEyfLjNiEDEL1_rdIVPkqPPr1fksSmZFpxgDFmkCFJQ,32657
|
59
|
+
rclone_api-1.5.14.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
60
|
+
rclone_api-1.5.14.dist-info/entry_points.txt,sha256=fJteOlYVwgX3UbNuL9jJ0zUTuX2O79JFAeNgK7Sw7EQ,255
|
61
|
+
rclone_api-1.5.14.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
62
|
+
rclone_api-1.5.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|