rclone-api 1.0.44__tar.gz → 1.0.46__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {rclone_api-1.0.44 → rclone_api-1.0.46}/PKG-INFO +1 -1
- {rclone_api-1.0.44 → rclone_api-1.0.46}/pyproject.toml +1 -1
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/__init__.py +2 -1
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/group_files.py +18 -18
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/rclone.py +25 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api.egg-info/PKG-INFO +1 -1
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.aiderignore +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.github/workflows/lint.yml +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.github/workflows/push_macos.yml +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.github/workflows/push_ubuntu.yml +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.github/workflows/push_win.yml +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.gitignore +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.pylintrc +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.vscode/launch.json +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.vscode/settings.json +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/.vscode/tasks.json +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/LICENSE +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/MANIFEST.in +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/README.md +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/clean +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/install +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/lint +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/requirements.testing.txt +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/setup.cfg +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/setup.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/assets/example.txt +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/cli.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/cmd/list_files.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/completed_process.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/config.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/convert.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/deprecated.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/diff.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/dir.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/dir_listing.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/exec.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/file.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/filelist.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/process.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/remote.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/rpath.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/util.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api/walk.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api.egg-info/SOURCES.txt +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api.egg-info/dependency_links.txt +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api.egg-info/entry_points.txt +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api.egg-info/requires.txt +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/src/rclone_api.egg-info/top_level.txt +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/test +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_cmd_list_files.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_copy.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_diff.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_group_files.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_is_synced.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_ls.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_mount.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_mount_s3.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_mount_webdav.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_obscure.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_remotes.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_serve_webdav.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tests/test_walk.py +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/tox.ini +0 -0
- {rclone_api-1.0.44 → rclone_api-1.0.46}/upload_package.sh +0 -0
@@ -5,7 +5,7 @@ from .dir_listing import DirListing
|
|
5
5
|
from .file import File
|
6
6
|
from .filelist import FileList
|
7
7
|
from .process import Process
|
8
|
-
from .rclone import Rclone
|
8
|
+
from .rclone import Rclone, rclone_verbose
|
9
9
|
from .remote import Remote
|
10
10
|
from .rpath import RPath
|
11
11
|
|
@@ -21,4 +21,5 @@ __all__ = [
|
|
21
21
|
"Process",
|
22
22
|
"DiffItem",
|
23
23
|
"DiffType",
|
24
|
+
"rclone_verbose",
|
24
25
|
]
|
@@ -39,10 +39,10 @@ class TreeNode:
|
|
39
39
|
self.count = 0
|
40
40
|
self.parent = parent
|
41
41
|
|
42
|
-
def
|
42
|
+
def add_count_bubble_up(self):
|
43
43
|
self.count += 1
|
44
44
|
if self.parent:
|
45
|
-
self.parent.
|
45
|
+
self.parent.add_count_bubble_up()
|
46
46
|
|
47
47
|
def get_path(self) -> str:
|
48
48
|
paths_reversed: list[str] = [self.name]
|
@@ -85,9 +85,6 @@ def _merge(node: TreeNode, parent_path: str, out: dict[str, list[str]]) -> None:
|
|
85
85
|
if node.files:
|
86
86
|
# we saw files, to don't try to go any deeper.
|
87
87
|
filelist = out.setdefault(parent_path, [])
|
88
|
-
# for file in node.files:
|
89
|
-
# filelist.append(file)
|
90
|
-
# out[parent_path] = filelist
|
91
88
|
paths = node.get_child_subpaths()
|
92
89
|
for path in paths:
|
93
90
|
filelist.append(path)
|
@@ -97,17 +94,11 @@ def _merge(node: TreeNode, parent_path: str, out: dict[str, list[str]]) -> None:
|
|
97
94
|
n_child_nodes = len(node.child_nodes)
|
98
95
|
|
99
96
|
if n_child_nodes <= 2:
|
100
|
-
# child = list(node.child_nodes.values())[0]
|
101
|
-
# _merge(child, parent_path, out)
|
102
|
-
# return
|
103
97
|
for child in node.child_nodes.values():
|
104
98
|
_merge(child, parent_path, out)
|
105
99
|
return
|
106
100
|
|
107
101
|
filelist = out.setdefault(parent_path, [])
|
108
|
-
# for file in node.files:
|
109
|
-
# filelist.append(file)
|
110
|
-
# out[parent_path] = filelist
|
111
102
|
paths = node.get_child_subpaths()
|
112
103
|
for path in paths:
|
113
104
|
filelist.append(path)
|
@@ -126,16 +117,12 @@ def _make_tree(files: list[str]) -> dict[str, TreeNode]:
|
|
126
117
|
node = node.child_nodes.setdefault(parent, TreeNode(parent, parent=node))
|
127
118
|
if is_last:
|
128
119
|
node.files.append(parts.name)
|
129
|
-
node.
|
120
|
+
node.add_count_bubble_up()
|
130
121
|
return tree
|
131
122
|
|
132
123
|
|
133
|
-
|
134
|
-
|
135
|
-
tree: dict[str, TreeNode] = _make_tree(files)
|
136
|
-
outpaths: dict[str, list[str]] = {}
|
137
|
-
for _, node in tree.items():
|
138
|
-
_merge(node, "", outpaths)
|
124
|
+
#
|
125
|
+
def _fixup_rclone_paths(outpaths: dict[str, list[str]]) -> dict[str, list[str]]:
|
139
126
|
out: dict[str, list[str]] = {}
|
140
127
|
for path, files in outpaths.items():
|
141
128
|
# fixup path
|
@@ -145,3 +132,16 @@ def group_files(files: list[str]) -> dict[str, list[str]]:
|
|
145
132
|
path = path.replace("/", ":", 1)
|
146
133
|
out[path] = files
|
147
134
|
return out
|
135
|
+
|
136
|
+
|
137
|
+
def group_files(files: list[str]) -> dict[str, list[str]]:
|
138
|
+
"""split between filename and parent directory path"""
|
139
|
+
tree: dict[str, TreeNode] = _make_tree(files)
|
140
|
+
outpaths: dict[str, list[str]] = {}
|
141
|
+
for _, node in tree.items():
|
142
|
+
_merge(node, "", outpaths)
|
143
|
+
out: dict[str, list[str]] = _fixup_rclone_paths(outpaths=outpaths)
|
144
|
+
return out
|
145
|
+
|
146
|
+
|
147
|
+
__all__ = ["group_files"]
|
@@ -2,6 +2,7 @@
|
|
2
2
|
Unit test file.
|
3
3
|
"""
|
4
4
|
|
5
|
+
import os
|
5
6
|
import subprocess
|
6
7
|
import time
|
7
8
|
import warnings
|
@@ -36,6 +37,12 @@ from rclone_api.walk import walk
|
|
36
37
|
EXECUTOR = ThreadPoolExecutor(16)
|
37
38
|
|
38
39
|
|
40
|
+
def rclone_verbose(verbose: bool | None) -> bool:
|
41
|
+
if verbose is not None:
|
42
|
+
os.environ["RCLONE_API_VERBOSE"] = "1" if verbose else "0"
|
43
|
+
return bool(int(os.getenv("RCLONE_API_VERBOSE", "0")))
|
44
|
+
|
45
|
+
|
39
46
|
class ModTimeStrategy(Enum):
|
40
47
|
USE_SERVER_MODTIME = "use-server-modtime"
|
41
48
|
NO_MODTIME = "no-modtime"
|
@@ -56,6 +63,13 @@ class Rclone:
|
|
56
63
|
def _launch_process(self, cmd: list[str], capture: bool | None = None) -> Process:
|
57
64
|
return self._exec.launch_process(cmd, capture=capture)
|
58
65
|
|
66
|
+
def webgui(self, other_args: list[str] | None = None) -> Process:
|
67
|
+
"""Launch the Rclone web GUI."""
|
68
|
+
cmd = ["rcd", "--rc-web-gui"]
|
69
|
+
if other_args:
|
70
|
+
cmd += other_args
|
71
|
+
return self._launch_process(cmd, capture=False)
|
72
|
+
|
59
73
|
def obscure(self, password: str) -> str:
|
60
74
|
"""Obscure a password for use in rclone config files."""
|
61
75
|
cmd_list: list[str] = ["obscure", password]
|
@@ -178,6 +192,17 @@ class Rclone:
|
|
178
192
|
|
179
193
|
yield from walk(dir_obj, max_depth=max_depth, breadth_first=breadth_first)
|
180
194
|
|
195
|
+
def cleanup(
|
196
|
+
self, path: str, other_args: list[str] | None = None
|
197
|
+
) -> CompletedProcess:
|
198
|
+
"""Cleanup any resources used by the Rclone instance."""
|
199
|
+
# rclone cleanup remote:path [flags]
|
200
|
+
cmd = ["cleanup", path]
|
201
|
+
if other_args:
|
202
|
+
cmd += other_args
|
203
|
+
out = self._run(cmd)
|
204
|
+
return CompletedProcess.from_subprocess(out)
|
205
|
+
|
181
206
|
def copyfile(self, src: File | str, dst: File | str) -> None:
|
182
207
|
"""Copy a single file from source to destination.
|
183
208
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|