rclone-api 1.0.49__py2.py3-none-any.whl → 1.0.50__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/file.py +54 -47
- rclone_api/group_files.py +29 -8
- rclone_api/rclone.py +670 -677
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.50.dist-info}/METADATA +1 -1
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.50.dist-info}/RECORD +9 -9
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.50.dist-info}/LICENSE +0 -0
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.50.dist-info}/WHEEL +0 -0
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.50.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.0.49.dist-info → rclone_api-1.0.50.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
|
|