rclone-api 1.0.45__py2.py3-none-any.whl → 1.0.47__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/completed_process.py +28 -0
- rclone_api/exec.py +6 -2
- rclone_api/rclone.py +58 -4
- rclone_api/util.py +3 -1
- {rclone_api-1.0.45.dist-info → rclone_api-1.0.47.dist-info}/METADATA +1 -1
- {rclone_api-1.0.45.dist-info → rclone_api-1.0.47.dist-info}/RECORD +10 -10
- {rclone_api-1.0.45.dist-info → rclone_api-1.0.47.dist-info}/LICENSE +0 -0
- {rclone_api-1.0.45.dist-info → rclone_api-1.0.47.dist-info}/WHEEL +0 -0
- {rclone_api-1.0.45.dist-info → rclone_api-1.0.47.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.0.45.dist-info → rclone_api-1.0.47.dist-info}/top_level.txt +0 -0
rclone_api/completed_process.py
CHANGED
@@ -19,3 +19,31 @@ class CompletedProcess:
|
|
19
19
|
|
20
20
|
def successes(self) -> list[subprocess.CompletedProcess]:
|
21
21
|
return [p for p in self.completed if p.returncode == 0]
|
22
|
+
|
23
|
+
@property
|
24
|
+
def stdout(self) -> str:
|
25
|
+
tmp: list[str] = []
|
26
|
+
for cp in self.completed:
|
27
|
+
stdout = cp.stdout
|
28
|
+
if stdout is not None:
|
29
|
+
tmp.append(stdout)
|
30
|
+
return "\n".join(tmp)
|
31
|
+
|
32
|
+
@property
|
33
|
+
def stderr(self) -> str:
|
34
|
+
tmp: list[str] = []
|
35
|
+
for cp in self.completed:
|
36
|
+
stderr = cp.stderr
|
37
|
+
if stderr is not None:
|
38
|
+
tmp.append(stderr)
|
39
|
+
return "\n".join(tmp)
|
40
|
+
|
41
|
+
@property
|
42
|
+
def returncode(self) -> int | None:
|
43
|
+
for cp in self.completed:
|
44
|
+
rtn = cp.returncode
|
45
|
+
if rtn is None:
|
46
|
+
return None
|
47
|
+
if rtn != 0:
|
48
|
+
return rtn
|
49
|
+
return 0
|
rclone_api/exec.py
CHANGED
@@ -13,11 +13,15 @@ class RcloneExec:
|
|
13
13
|
rclone_config: Path | Config
|
14
14
|
rclone_exe: Path
|
15
15
|
|
16
|
-
def execute(
|
16
|
+
def execute(
|
17
|
+
self, cmd: list[str], check: bool, capture: bool | None = None
|
18
|
+
) -> subprocess.CompletedProcess:
|
17
19
|
"""Execute rclone command."""
|
18
20
|
from rclone_api.util import rclone_execute
|
19
21
|
|
20
|
-
return rclone_execute(
|
22
|
+
return rclone_execute(
|
23
|
+
cmd, self.rclone_config, self.rclone_exe, check=check, capture=capture
|
24
|
+
)
|
21
25
|
|
22
26
|
def launch_process(self, cmd: list[str], capture: bool | None) -> Process:
|
23
27
|
"""Launch rclone process."""
|
rclone_api/rclone.py
CHANGED
@@ -57,12 +57,62 @@ class Rclone:
|
|
57
57
|
raise ValueError(f"Rclone config file not found: {rclone_conf}")
|
58
58
|
self._exec = RcloneExec(rclone_conf, get_rclone_exe(rclone_exe))
|
59
59
|
|
60
|
-
def _run(
|
61
|
-
|
60
|
+
def _run(
|
61
|
+
self, cmd: list[str], check: bool = True, capture: bool | None = None
|
62
|
+
) -> subprocess.CompletedProcess:
|
63
|
+
return self._exec.execute(cmd, check=check, capture=capture)
|
62
64
|
|
63
65
|
def _launch_process(self, cmd: list[str], capture: bool | None = None) -> Process:
|
64
66
|
return self._exec.launch_process(cmd, capture=capture)
|
65
67
|
|
68
|
+
def webgui(self, other_args: list[str] | None = None) -> Process:
|
69
|
+
"""Launch the Rclone web GUI."""
|
70
|
+
cmd = ["rcd", "--rc-web-gui"]
|
71
|
+
if other_args:
|
72
|
+
cmd += other_args
|
73
|
+
return self._launch_process(cmd, capture=False)
|
74
|
+
|
75
|
+
def launch_server(
|
76
|
+
self,
|
77
|
+
addr: str | None = None,
|
78
|
+
user: str | None = None,
|
79
|
+
password: str | None = None,
|
80
|
+
other_args: list[str] | None = None,
|
81
|
+
) -> Process:
|
82
|
+
"""Launch the Rclone server so it can receive commands"""
|
83
|
+
cmd = ["rcd"]
|
84
|
+
if addr is not None:
|
85
|
+
cmd += ["--rc-addr", addr]
|
86
|
+
if user is not None:
|
87
|
+
cmd += ["--rc-user", user]
|
88
|
+
if password is not None:
|
89
|
+
cmd += ["--rc-pass", password]
|
90
|
+
if other_args:
|
91
|
+
cmd += other_args
|
92
|
+
out = self._launch_process(cmd, capture=False)
|
93
|
+
time.sleep(1) # Give it some time to launch
|
94
|
+
return out
|
95
|
+
|
96
|
+
def remote_control(
|
97
|
+
self,
|
98
|
+
addr: str,
|
99
|
+
user: str | None = None,
|
100
|
+
password: str | None = None,
|
101
|
+
capture: bool | None = None,
|
102
|
+
other_args: list[str] | None = None,
|
103
|
+
) -> CompletedProcess:
|
104
|
+
cmd = ["rc"]
|
105
|
+
if addr:
|
106
|
+
cmd += ["--rc-addr", addr]
|
107
|
+
if user is not None:
|
108
|
+
cmd += ["--rc-user", user]
|
109
|
+
if password is not None:
|
110
|
+
cmd += ["--rc-pass", password]
|
111
|
+
if other_args:
|
112
|
+
cmd += other_args
|
113
|
+
cp = self._run(cmd, capture=capture)
|
114
|
+
return CompletedProcess.from_subprocess(cp)
|
115
|
+
|
66
116
|
def obscure(self, password: str) -> str:
|
67
117
|
"""Obscure a password for use in rclone config files."""
|
68
118
|
cmd_list: list[str] = ["obscure", password]
|
@@ -185,10 +235,14 @@ class Rclone:
|
|
185
235
|
|
186
236
|
yield from walk(dir_obj, max_depth=max_depth, breadth_first=breadth_first)
|
187
237
|
|
188
|
-
def cleanup(
|
238
|
+
def cleanup(
|
239
|
+
self, path: str, other_args: list[str] | None = None
|
240
|
+
) -> CompletedProcess:
|
189
241
|
"""Cleanup any resources used by the Rclone instance."""
|
190
242
|
# rclone cleanup remote:path [flags]
|
191
243
|
cmd = ["cleanup", path]
|
244
|
+
if other_args:
|
245
|
+
cmd += other_args
|
192
246
|
out = self._run(cmd)
|
193
247
|
return CompletedProcess.from_subprocess(out)
|
194
248
|
|
@@ -246,7 +300,7 @@ class Rclone:
|
|
246
300
|
|
247
301
|
# print(include_files_txt)
|
248
302
|
cmd_list: list[str] = [
|
249
|
-
"
|
303
|
+
"copy",
|
250
304
|
remote,
|
251
305
|
"--files-from",
|
252
306
|
str(include_files_txt),
|
rclone_api/util.py
CHANGED
@@ -78,10 +78,12 @@ def rclone_execute(
|
|
78
78
|
rclone_conf: Path | Config,
|
79
79
|
rclone_exe: Path,
|
80
80
|
check: bool,
|
81
|
+
capture: bool | None = None,
|
81
82
|
verbose: bool | None = None,
|
82
83
|
) -> subprocess.CompletedProcess:
|
83
84
|
tempdir: TemporaryDirectory | None = None
|
84
85
|
verbose = get_verbose(verbose)
|
86
|
+
capture = capture if isinstance(capture, bool) else True
|
85
87
|
assert verbose is not None
|
86
88
|
|
87
89
|
try:
|
@@ -97,7 +99,7 @@ def rclone_execute(
|
|
97
99
|
cmd_str = subprocess.list2cmdline(cmd)
|
98
100
|
print(f"Running: {cmd_str}")
|
99
101
|
cp = subprocess.run(
|
100
|
-
cmd, capture_output=
|
102
|
+
cmd, capture_output=capture, encoding="utf-8", check=False, shell=False
|
101
103
|
)
|
102
104
|
if cp.returncode != 0:
|
103
105
|
cmd_str = subprocess.list2cmdline(cmd)
|
@@ -1,27 +1,27 @@
|
|
1
1
|
rclone_api/__init__.py,sha256=fvWhio7i71rS5JtIr3l-36F6LRHo0ddpq0VX-6P5ldY,495
|
2
2
|
rclone_api/cli.py,sha256=dibfAZIh0kXWsBbfp3onKLjyZXo54mTzDjUdzJlDlWo,231
|
3
|
-
rclone_api/completed_process.py,sha256=
|
3
|
+
rclone_api/completed_process.py,sha256=Pp-hXnLgej0IGO5ee9Fmx64dGzIofbQFEUyXdFCvO54,1371
|
4
4
|
rclone_api/config.py,sha256=tP6cU9DnCCEIRc_KP9HPur1jFLLg2QGFSxNwFm6_MVw,118
|
5
5
|
rclone_api/convert.py,sha256=Mx9Qo7zhkOedJd8LdhPvNGHp8znJzOk4f_2KWnoGc78,1012
|
6
6
|
rclone_api/deprecated.py,sha256=qWKpnZdYcBK7YQZKuVoWWXDwi-uqiAtbjgPcci_efow,590
|
7
7
|
rclone_api/diff.py,sha256=ELUQD1Mv8qaoAav13sEE-iKynFph70rQHj7-a4Z1pyo,4137
|
8
8
|
rclone_api/dir.py,sha256=vV-bcI2ESijmwF5rPID5WO2K7soAfZa35wv4KRh_GIo,2154
|
9
9
|
rclone_api/dir_listing.py,sha256=9Qqf2SUswrOEkyqmaH23V51I18X6ePiXb9B1vUwRF5o,1571
|
10
|
-
rclone_api/exec.py,sha256=
|
10
|
+
rclone_api/exec.py,sha256=1ovvaMXDEfLiT7BrYZyE85u_yFhEUwUNW3jPOzqknR8,1023
|
11
11
|
rclone_api/file.py,sha256=D02iHJW1LhfOiM_R_yPHP8_ApnDiYrkuraVcrV8-qkw,1246
|
12
12
|
rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
13
13
|
rclone_api/group_files.py,sha256=HxrRUi_kFlMblrCMFyv6rO56tVMEzgU4-vVeB_2-lbc,4606
|
14
14
|
rclone_api/process.py,sha256=RrMfTe0bndmJ6gBK67ioqNvCstJ8aTC8RlGX1XBLlcw,4191
|
15
|
-
rclone_api/rclone.py,sha256
|
15
|
+
rclone_api/rclone.py,sha256=-F7tFWIOcBovdiaMgYpuTExjaY6rmI_Xo1rORXfP-h8,23280
|
16
16
|
rclone_api/remote.py,sha256=c9hlRKBCg1BFB9MCINaQIoCg10qyAkeqiS4brl8ce-8,343
|
17
17
|
rclone_api/rpath.py,sha256=8ZA_1wxWtskwcy0I8V2VbjKDmzPkiWd8Q2JQSvh-sYE,2586
|
18
|
-
rclone_api/util.py,sha256=
|
18
|
+
rclone_api/util.py,sha256=IWNOOcPE0xdKvehzXQ9okIppGDBYWJPIfdbUME8BFVM,4015
|
19
19
|
rclone_api/walk.py,sha256=kca0t1GAnF6FLclN01G8NG__Qe-ggodLtAbQSHyVPng,2968
|
20
20
|
rclone_api/assets/example.txt,sha256=lTBovRjiz0_TgtAtbA1C5hNi2ffbqnNPqkKg6UiKCT8,54
|
21
21
|
rclone_api/cmd/list_files.py,sha256=x8FHODEilwKqwdiU1jdkeJbLwOqUkUQuDWPo2u_zpf0,741
|
22
|
-
rclone_api-1.0.
|
23
|
-
rclone_api-1.0.
|
24
|
-
rclone_api-1.0.
|
25
|
-
rclone_api-1.0.
|
26
|
-
rclone_api-1.0.
|
27
|
-
rclone_api-1.0.
|
22
|
+
rclone_api-1.0.47.dist-info/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
23
|
+
rclone_api-1.0.47.dist-info/METADATA,sha256=tEWwiE6PzwzCM50jJIAegd5dWbca2QFVhDUoDSRpxwc,4489
|
24
|
+
rclone_api-1.0.47.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
|
25
|
+
rclone_api-1.0.47.dist-info/entry_points.txt,sha256=XUoTX3m7CWxdj2VAKhEuO0NMOfX2qf-OcEDFwdyk9ZE,72
|
26
|
+
rclone_api-1.0.47.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
27
|
+
rclone_api-1.0.47.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|