rclone-api 1.0.49__py2.py3-none-any.whl → 1.0.51__py2.py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- rclone_api/file.py +54 -47
- rclone_api/group_files.py +29 -8
- rclone_api/rclone.py +680 -677
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/METADATA +1 -1
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/RECORD +9 -9
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/LICENSE +0 -0
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/WHEEL +0 -0
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/top_level.txt +0 -0
rclone_api/file.py
CHANGED
@@ -1,47 +1,54 @@
|
|
1
|
-
import json
|
2
|
-
|
3
|
-
from rclone_api.rpath import RPath
|
4
|
-
|
5
|
-
|
6
|
-
class File:
|
7
|
-
"""Remote file dataclass."""
|
8
|
-
|
9
|
-
def __init__(
|
10
|
-
self,
|
11
|
-
path: RPath,
|
12
|
-
) -> None:
|
13
|
-
self.path = path
|
14
|
-
|
15
|
-
@property
|
16
|
-
def name(self) -> str:
|
17
|
-
return self.path.name
|
18
|
-
|
19
|
-
def read_text(self) -> str:
|
20
|
-
"""Read the file contents as bytes.
|
21
|
-
|
22
|
-
Returns:
|
23
|
-
bytes: The file contents
|
24
|
-
|
25
|
-
Raises:
|
26
|
-
RuntimeError: If no rclone instance is associated with this file
|
27
|
-
RuntimeError: If the path represents a directory
|
28
|
-
"""
|
29
|
-
if self.path.rclone is None:
|
30
|
-
raise RuntimeError("No rclone instance associated with this file")
|
31
|
-
if self.path.is_dir:
|
32
|
-
raise RuntimeError("Cannot read a directory as bytes")
|
33
|
-
|
34
|
-
result = self.path.rclone._run(["cat", self.path.path], check=True)
|
35
|
-
return result.stdout
|
36
|
-
|
37
|
-
def to_json(self) -> dict:
|
38
|
-
"""Convert the File to a JSON serializable dictionary."""
|
39
|
-
return self.path.to_json()
|
40
|
-
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
1
|
+
import json
|
2
|
+
|
3
|
+
from rclone_api.rpath import RPath
|
4
|
+
|
5
|
+
|
6
|
+
class File:
|
7
|
+
"""Remote file dataclass."""
|
8
|
+
|
9
|
+
def __init__(
|
10
|
+
self,
|
11
|
+
path: RPath,
|
12
|
+
) -> None:
|
13
|
+
self.path = path
|
14
|
+
|
15
|
+
@property
|
16
|
+
def name(self) -> str:
|
17
|
+
return self.path.name
|
18
|
+
|
19
|
+
def read_text(self) -> str:
|
20
|
+
"""Read the file contents as bytes.
|
21
|
+
|
22
|
+
Returns:
|
23
|
+
bytes: The file contents
|
24
|
+
|
25
|
+
Raises:
|
26
|
+
RuntimeError: If no rclone instance is associated with this file
|
27
|
+
RuntimeError: If the path represents a directory
|
28
|
+
"""
|
29
|
+
if self.path.rclone is None:
|
30
|
+
raise RuntimeError("No rclone instance associated with this file")
|
31
|
+
if self.path.is_dir:
|
32
|
+
raise RuntimeError("Cannot read a directory as bytes")
|
33
|
+
|
34
|
+
result = self.path.rclone._run(["cat", self.path.path], check=True)
|
35
|
+
return result.stdout
|
36
|
+
|
37
|
+
def to_json(self) -> dict:
|
38
|
+
"""Convert the File to a JSON serializable dictionary."""
|
39
|
+
return self.path.to_json()
|
40
|
+
|
41
|
+
def to_string(self, include_remote: bool = True) -> str:
|
42
|
+
"""Convert the File to a string."""
|
43
|
+
out = str(self.path)
|
44
|
+
if not include_remote:
|
45
|
+
_, out = out.split(":", 1)
|
46
|
+
return out
|
47
|
+
|
48
|
+
def __str__(self) -> str:
|
49
|
+
return str(self.path)
|
50
|
+
|
51
|
+
def __repr__(self) -> str:
|
52
|
+
data = self.path.to_json()
|
53
|
+
data_str = json.dumps(data)
|
54
|
+
return data_str
|
rclone_api/group_files.py
CHANGED
@@ -112,12 +112,19 @@ def _make_tree(files: list[str]) -> dict[str, TreeNode]:
|
|
112
112
|
parts = parse_file(file)
|
113
113
|
remote = parts.remote
|
114
114
|
node: TreeNode = tree.setdefault(remote, TreeNode(remote))
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
115
|
+
if parts.parents:
|
116
|
+
for parent in parts.parents:
|
117
|
+
is_last = parent == parts.parents[-1]
|
118
|
+
node = node.child_nodes.setdefault(
|
119
|
+
parent, TreeNode(parent, parent=node)
|
120
|
+
)
|
121
|
+
if is_last:
|
122
|
+
node.files.append(parts.name)
|
123
|
+
node.add_count_bubble_up()
|
124
|
+
else:
|
125
|
+
node.files.append(parts.name)
|
126
|
+
node.add_count_bubble_up()
|
127
|
+
|
121
128
|
return tree
|
122
129
|
|
123
130
|
|
@@ -134,13 +141,27 @@ def _fixup_rclone_paths(outpaths: dict[str, list[str]]) -> dict[str, list[str]]:
|
|
134
141
|
return out
|
135
142
|
|
136
143
|
|
137
|
-
def group_files(files: list[str]) -> dict[str, list[str]]:
|
144
|
+
def group_files(files: list[str], fully_qualified: bool = True) -> dict[str, list[str]]:
|
138
145
|
"""split between filename and parent directory path"""
|
146
|
+
if fully_qualified is False:
|
147
|
+
for i, file in enumerate(files):
|
148
|
+
file = "root:" + file
|
149
|
+
files[i] = file
|
139
150
|
tree: dict[str, TreeNode] = _make_tree(files)
|
140
151
|
outpaths: dict[str, list[str]] = {}
|
141
152
|
for _, node in tree.items():
|
142
153
|
_merge(node, "", outpaths)
|
143
|
-
|
154
|
+
tmp: dict[str, list[str]] = _fixup_rclone_paths(outpaths=outpaths)
|
155
|
+
out: dict[str, list[str]] = {}
|
156
|
+
if fully_qualified is False:
|
157
|
+
for path, files in tmp.items():
|
158
|
+
if path.startswith("root"):
|
159
|
+
path = path.replace("root", "")
|
160
|
+
if path.startswith(":"):
|
161
|
+
path = path[1:]
|
162
|
+
out[path] = [file.replace("/root/", "") for file in files]
|
163
|
+
else:
|
164
|
+
out = tmp
|
144
165
|
return out
|
145
166
|
|
146
167
|
|