rclone-api 1.3.28__py2.py3-none-any.whl → 1.4.1__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.
Files changed (34) hide show
  1. rclone_api/__init__.py +491 -4
  2. rclone_api/cmd/copy_large_s3.py +17 -10
  3. rclone_api/db/db.py +3 -3
  4. rclone_api/detail/copy_file_parts.py +382 -0
  5. rclone_api/dir.py +1 -1
  6. rclone_api/dir_listing.py +1 -1
  7. rclone_api/file.py +8 -0
  8. rclone_api/file_part.py +198 -0
  9. rclone_api/file_stream.py +52 -0
  10. rclone_api/http_server.py +15 -21
  11. rclone_api/{rclone.py → rclone_impl.py} +153 -321
  12. rclone_api/remote.py +3 -3
  13. rclone_api/rpath.py +11 -4
  14. rclone_api/s3/chunk_task.py +3 -19
  15. rclone_api/s3/multipart/file_info.py +7 -0
  16. rclone_api/s3/multipart/finished_piece.py +38 -0
  17. rclone_api/s3/multipart/upload_info.py +62 -0
  18. rclone_api/s3/{chunk_types.py → multipart/upload_state.py} +3 -99
  19. rclone_api/s3/s3_multipart_uploader.py +138 -28
  20. rclone_api/s3/types.py +1 -1
  21. rclone_api/s3/upload_file_multipart.py +6 -13
  22. rclone_api/scan_missing_folders.py +1 -1
  23. rclone_api/types.py +136 -165
  24. rclone_api/util.py +22 -2
  25. {rclone_api-1.3.28.dist-info → rclone_api-1.4.1.dist-info}/METADATA +1 -1
  26. rclone_api-1.4.1.dist-info/RECORD +55 -0
  27. rclone_api/mount_read_chunker.py +0 -130
  28. rclone_api/profile/mount_copy_bytes.py +0 -311
  29. rclone_api-1.3.28.dist-info/RECORD +0 -51
  30. /rclone_api/{walk.py → detail/walk.py} +0 -0
  31. {rclone_api-1.3.28.dist-info → rclone_api-1.4.1.dist-info}/LICENSE +0 -0
  32. {rclone_api-1.3.28.dist-info → rclone_api-1.4.1.dist-info}/WHEEL +0 -0
  33. {rclone_api-1.3.28.dist-info → rclone_api-1.4.1.dist-info}/entry_points.txt +0 -0
  34. {rclone_api-1.3.28.dist-info → rclone_api-1.4.1.dist-info}/top_level.txt +0 -0
rclone_api/http_server.py CHANGED
@@ -5,30 +5,19 @@ Unit test file for testing rclone mount functionality.
5
5
  import tempfile
6
6
  import warnings
7
7
  from concurrent.futures import Future, ThreadPoolExecutor
8
- from dataclasses import dataclass
9
8
  from pathlib import Path
9
+ from threading import Semaphore
10
10
  from typing import Any
11
11
 
12
12
  import httpx
13
13
 
14
+ from rclone_api.file_part import FilePart
14
15
  from rclone_api.process import Process
15
- from rclone_api.types import FilePart, SizeSuffix, get_chunk_tmpdir
16
+ from rclone_api.types import Range, SizeSuffix, get_chunk_tmpdir
16
17
 
17
18
  _TIMEOUT = 10 * 60 # 10 minutes
18
19
 
19
20
 
20
- @dataclass
21
- class Range:
22
- start: int
23
- end: int
24
-
25
- def to_header(self) -> dict[str, str]:
26
- val = f"bytes={self.start}-{self.end-1}"
27
- return {
28
- "Range": val,
29
- }
30
-
31
-
32
21
  _range = range
33
22
 
34
23
 
@@ -49,10 +38,10 @@ class HttpServer:
49
38
  def get_fetcher(self, path: str, n_threads: int = 16) -> "HttpFetcher":
50
39
  return HttpFetcher(self, path, n_threads=n_threads)
51
40
 
52
- def get(self, path: str) -> bytes | Exception:
41
+ def get(self, path: str, range: Range | None = None) -> bytes | Exception:
53
42
  """Get bytes from the server."""
54
43
  with tempfile.TemporaryFile() as file:
55
- self.download(path, Path(file.name), None)
44
+ self.download(path, Path(file.name), range)
56
45
  file.seek(0)
57
46
  return file.read()
58
47
 
@@ -124,8 +113,13 @@ class HttpServer:
124
113
  with ThreadPoolExecutor(max_workers=n_threads) as executor:
125
114
  try:
126
115
  futures: list[Future[Path | Exception]] = []
127
- for start in _range(range.start, range.end, chunk_size):
128
- end = min(start + chunk_size, range.end)
116
+ start: int
117
+ for start in _range(
118
+ range.start.as_int(), range.end.as_int(), chunk_size
119
+ ):
120
+ end = min(
121
+ SizeSuffix(start + chunk_size).as_int(), range.end.as_int()
122
+ )
129
123
  r = Range(start=start, end=end)
130
124
 
131
125
  def task(r: Range = r) -> Path | Exception:
@@ -200,11 +194,11 @@ class HttpFetcher:
200
194
  self.server = server
201
195
  self.path = path
202
196
  self.executor = ThreadPoolExecutor(max_workers=n_threads)
203
- from threading import Semaphore
204
-
197
+ # Semaphore throttles the number of concurrent fetches
198
+ # TODO this is kind of a hack.
205
199
  self.semaphore = Semaphore(n_threads)
206
200
 
207
- def fetch(
201
+ def bytes_fetcher(
208
202
  self, offset: int | SizeSuffix, size: int | SizeSuffix, extra: Any
209
203
  ) -> Future[FilePart]:
210
204
  if isinstance(offset, SizeSuffix):