rclone-api 1.5.11__py3-none-any.whl → 1.5.13__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 +3 -1
- rclone_api/http_server.py +45 -5
- rclone_api/process.py +8 -1
- rclone_api/rclone_impl.py +11 -2
- rclone_api/s3/multipart/upload_parts_resumable.py +1 -1
- {rclone_api-1.5.11.dist-info → rclone_api-1.5.13.dist-info}/METADATA +1 -1
- {rclone_api-1.5.11.dist-info → rclone_api-1.5.13.dist-info}/RECORD +11 -11
- {rclone_api-1.5.11.dist-info → rclone_api-1.5.13.dist-info}/WHEEL +1 -1
- {rclone_api-1.5.11.dist-info → rclone_api-1.5.13.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.5.11.dist-info → rclone_api-1.5.13.dist-info}/licenses/LICENSE +0 -0
- {rclone_api-1.5.11.dist-info → rclone_api-1.5.13.dist-info}/top_level.txt +0 -0
rclone_api/__init__.py
CHANGED
@@ -862,7 +862,9 @@ class Rclone:
|
|
862
862
|
Returns:
|
863
863
|
HttpServer object with methods for accessing the served content
|
864
864
|
"""
|
865
|
-
return self.impl.serve_http(
|
865
|
+
return self.impl.serve_http(
|
866
|
+
src=src, cache_mode="minimal", addr=addr, other_args=other_args
|
867
|
+
)
|
866
868
|
|
867
869
|
def size_files(
|
868
870
|
self,
|
rclone_api/http_server.py
CHANGED
@@ -17,6 +17,7 @@ from rclone_api.process import Process
|
|
17
17
|
from rclone_api.types import Range, SizeSuffix, get_chunk_tmpdir
|
18
18
|
|
19
19
|
_TIMEOUT = 10 * 60 # 10 minutes
|
20
|
+
_PUT_WARNED = False
|
20
21
|
|
21
22
|
|
22
23
|
_range = range
|
@@ -46,6 +47,18 @@ class HttpServer:
|
|
46
47
|
file.seek(0)
|
47
48
|
return file.read()
|
48
49
|
|
50
|
+
def exists(self, path: str) -> bool:
|
51
|
+
"""Check if the file exists on the server."""
|
52
|
+
try:
|
53
|
+
assert self.process is not None
|
54
|
+
# response = httpx.head(f"{self.url}/{path}")
|
55
|
+
url = self._get_file_url(path)
|
56
|
+
response = httpx.head(url)
|
57
|
+
return response.status_code == 200
|
58
|
+
except Exception as e:
|
59
|
+
warnings.warn(f"Failed to check if {self.url}/{path} exists: {e}")
|
60
|
+
return False
|
61
|
+
|
49
62
|
def size(self, path: str) -> int | Exception:
|
50
63
|
"""Get size of the file from the server."""
|
51
64
|
try:
|
@@ -60,6 +73,36 @@ class HttpServer:
|
|
60
73
|
warnings.warn(f"Failed to get size of {self.url}/{path}: {e}")
|
61
74
|
return e
|
62
75
|
|
76
|
+
def put(self, path: str, data: bytes) -> Exception | None:
|
77
|
+
"""Put bytes to the server."""
|
78
|
+
global _PUT_WARNED
|
79
|
+
if not _PUT_WARNED:
|
80
|
+
_PUT_WARNED = True
|
81
|
+
warnings.warn("PUT method not implemented on the rclone binary as of 1.69")
|
82
|
+
try:
|
83
|
+
assert self.process is not None
|
84
|
+
url = self._get_file_url(path)
|
85
|
+
headers = {"Content-Type": "application/octet-stream"}
|
86
|
+
response = httpx.post(url, content=data, timeout=_TIMEOUT, headers=headers)
|
87
|
+
print("Allowed methods:", response.headers.get("Allow"))
|
88
|
+
response.raise_for_status()
|
89
|
+
return None
|
90
|
+
except Exception as e:
|
91
|
+
warnings.warn(f"Failed to put {path} to {self.url}: {e}")
|
92
|
+
return e
|
93
|
+
|
94
|
+
def delete(self, path: str) -> Exception | None:
|
95
|
+
"""Remove file from the server."""
|
96
|
+
try:
|
97
|
+
assert self.process is not None
|
98
|
+
url = self._get_file_url(path)
|
99
|
+
response = httpx.delete(url)
|
100
|
+
response.raise_for_status()
|
101
|
+
return None
|
102
|
+
except Exception as e:
|
103
|
+
warnings.warn(f"Failed to remove {path} from {self.url}: {e}")
|
104
|
+
return e
|
105
|
+
|
63
106
|
def download(
|
64
107
|
self, path: str, dst: Path, range: Range | None = None
|
65
108
|
) -> Path | Exception:
|
@@ -199,11 +242,8 @@ class HttpServer:
|
|
199
242
|
def shutdown(self) -> None:
|
200
243
|
"""Shutdown the server."""
|
201
244
|
if self.process:
|
202
|
-
self.process.
|
203
|
-
|
204
|
-
self.process.stdout.close()
|
205
|
-
if self.process.stderr:
|
206
|
-
self.process.stderr.close()
|
245
|
+
self.process.dispose()
|
246
|
+
self.process = None
|
207
247
|
|
208
248
|
|
209
249
|
class HttpFetcher:
|
rclone_api/process.py
CHANGED
@@ -30,6 +30,7 @@ class Process:
|
|
30
30
|
), f"rclone executable not found: {args.rclone_exe}"
|
31
31
|
self.args = args
|
32
32
|
self.log = args.log
|
33
|
+
self.cleaned_up = False
|
33
34
|
self.tempfile: Path | None = None
|
34
35
|
|
35
36
|
verbose = get_verbose(args.verbose)
|
@@ -75,11 +76,17 @@ class Process:
|
|
75
76
|
def __enter__(self) -> "Process":
|
76
77
|
return self
|
77
78
|
|
78
|
-
def
|
79
|
+
def dispose(self) -> None:
|
80
|
+
if self.cleaned_up:
|
81
|
+
return
|
82
|
+
self.cleaned_up = True
|
79
83
|
self.terminate()
|
80
84
|
self.wait()
|
81
85
|
self.cleanup()
|
82
86
|
|
87
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
88
|
+
self.dispose()
|
89
|
+
|
83
90
|
def cleanup(self) -> None:
|
84
91
|
if self.tempfile:
|
85
92
|
clear_temp_config_file(self.tempfile)
|
rclone_api/rclone_impl.py
CHANGED
@@ -6,6 +6,7 @@ import os
|
|
6
6
|
import random
|
7
7
|
import subprocess
|
8
8
|
import time
|
9
|
+
import tracemalloc
|
9
10
|
import warnings
|
10
11
|
from concurrent.futures import Future, ThreadPoolExecutor
|
11
12
|
from datetime import datetime
|
@@ -51,6 +52,9 @@ from rclone_api.util import (
|
|
51
52
|
to_path,
|
52
53
|
)
|
53
54
|
|
55
|
+
# Enable tracing memory usage always
|
56
|
+
tracemalloc.start()
|
57
|
+
|
54
58
|
|
55
59
|
def rclone_verbose(verbose: bool | None) -> bool:
|
56
60
|
if verbose is not None:
|
@@ -1164,6 +1168,7 @@ class RcloneImpl:
|
|
1164
1168
|
def serve_http(
|
1165
1169
|
self,
|
1166
1170
|
src: str,
|
1171
|
+
cache_mode: str | None,
|
1167
1172
|
addr: str | None = None,
|
1168
1173
|
serve_http_log: Path | None = None,
|
1169
1174
|
other_args: list[str] | None = None,
|
@@ -1186,9 +1191,13 @@ class RcloneImpl:
|
|
1186
1191
|
"0",
|
1187
1192
|
"--vfs-read-chunk-size-limit",
|
1188
1193
|
"512M",
|
1189
|
-
"--vfs-cache-mode",
|
1190
|
-
"off",
|
1191
1194
|
]
|
1195
|
+
|
1196
|
+
if cache_mode:
|
1197
|
+
cmd_list += [
|
1198
|
+
"--vfs-cache-mode",
|
1199
|
+
cache_mode,
|
1200
|
+
]
|
1192
1201
|
if serve_http_log:
|
1193
1202
|
cmd_list += ["--log-file", str(serve_http_log)]
|
1194
1203
|
cmd_list += ["-vvvv"]
|
@@ -232,7 +232,7 @@ def upload_parts_resumable(
|
|
232
232
|
|
233
233
|
atexit.register(lambda: shutil.rmtree(tmp_dir, ignore_errors=True))
|
234
234
|
|
235
|
-
with self.serve_http(src_dir) as http_server:
|
235
|
+
with self.serve_http(src_dir, cache_mode="minimal") as http_server:
|
236
236
|
tmpdir: Path = Path(tmp_dir)
|
237
237
|
write_semaphore = threading.Semaphore(threads)
|
238
238
|
with ThreadPoolExecutor(max_workers=threads) as upload_executor:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
rclone_api/__init__.py,sha256=
|
1
|
+
rclone_api/__init__.py,sha256=nUDuo5YZQZybVsd0fiExyDPOOwxwZGSrD8Sx6Asb57U,32426
|
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
|
@@ -14,13 +14,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
16
|
rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
|
17
|
-
rclone_api/http_server.py,sha256=
|
17
|
+
rclone_api/http_server.py,sha256=p1_S9VAViVvGif6NA_rxrDgMqnOmPTxJaHQ7B43FK70,10431
|
18
18
|
rclone_api/install.py,sha256=Xb1BRn8rQcSpSd4dzmvIOELP2zM2DytUeIZ6jzv738A,2893
|
19
19
|
rclone_api/log.py,sha256=VZHM7pNSXip2ZLBKMP7M1u-rp_F7zoafFDuR8CPUoKI,1271
|
20
20
|
rclone_api/mount.py,sha256=LZqEhuKZunbWVqmsOIqkkCotaxWJpdFRS1InXveoU5E,1428
|
21
21
|
rclone_api/mount_util.py,sha256=jqhJEVTHV6c6lOOzUYb4FLMbqDMHdz7-QRcdH-IobFc,10154
|
22
|
-
rclone_api/process.py,sha256=
|
23
|
-
rclone_api/rclone_impl.py,sha256=
|
22
|
+
rclone_api/process.py,sha256=MeWiN-TrrN0HmtWexBPxGwf84z6f-_E5yaXE-YtLYpY,5879
|
23
|
+
rclone_api/rclone_impl.py,sha256=STHQ_hT0chyp2yj3Cp-Vd0xXc1Pdpo3p9J3bTQEm0XE,46531
|
24
24
|
rclone_api/remote.py,sha256=mTgMTQTwxUmbLjTpr-AGTId2ycXKI9mLX5L7PPpDIoc,520
|
25
25
|
rclone_api/rpath.py,sha256=Y1JjQWcie39EgQrq-UtbfDz5yDLCwwfu27W7AQXllSE,2860
|
26
26
|
rclone_api/scan_missing_folders.py,sha256=-8NCwpCaHeHrX-IepCoAEsX1rl8S-GOCxcIhTr_w3gA,4747
|
@@ -50,12 +50,12 @@ rclone_api/s3/multipart/info_json.py,sha256=-e8UCwrqjAP64U8PmH-o2ciJ6TN48DwHktJf
|
|
50
50
|
rclone_api/s3/multipart/merge_state.py,sha256=ziTB9CYV-OWaky5C1fOT9hifSY2zgUrk5HmX1Xeu2UA,4978
|
51
51
|
rclone_api/s3/multipart/upload_info.py,sha256=d6_OfzFR_vtDzCEegFfzCfWi2kUBUV4aXZzqAEVp1c4,1874
|
52
52
|
rclone_api/s3/multipart/upload_parts_inline.py,sha256=V7syKjFyVIe4U9Ahl5XgqVTzt9akiew3MFjGmufLo2w,12503
|
53
|
-
rclone_api/s3/multipart/upload_parts_resumable.py,sha256=
|
53
|
+
rclone_api/s3/multipart/upload_parts_resumable.py,sha256=6-nlMclS8jyVvMvFbQDcZOX9MY1WbCcKA_s9bwuYxnk,9793
|
54
54
|
rclone_api/s3/multipart/upload_parts_server_side_merge.py,sha256=Fp2pdrs5dONQI9LkfNolgAGj1-Z2V1SsRd0r0sreuXI,18040
|
55
55
|
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.
|
56
|
+
rclone_api-1.5.13.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
57
|
+
rclone_api-1.5.13.dist-info/METADATA,sha256=GZbzZ8SIa3OXE_8lB_hGrK0y10KHCG5jUkn2sjPPQE0,32657
|
58
|
+
rclone_api-1.5.13.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
59
|
+
rclone_api-1.5.13.dist-info/entry_points.txt,sha256=fJteOlYVwgX3UbNuL9jJ0zUTuX2O79JFAeNgK7Sw7EQ,255
|
60
|
+
rclone_api-1.5.13.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
61
|
+
rclone_api-1.5.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|