rclone-api 1.3.23__tar.gz → 1.3.24__tar.gz
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-1.3.23 → rclone_api-1.3.24}/PKG-INFO +1 -1
- {rclone_api-1.3.23 → rclone_api-1.3.24}/pyproject.toml +1 -1
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/s3/chunk_task.py +2 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/s3/upload_file_multipart.py +45 -27
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/types.py +11 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api.egg-info/PKG-INFO +1 -1
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.aiderignore +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.github/workflows/lint.yml +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.github/workflows/push_macos.yml +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.github/workflows/push_ubuntu.yml +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.github/workflows/push_win.yml +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.gitignore +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.pylintrc +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.vscode/launch.json +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.vscode/settings.json +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/.vscode/tasks.json +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/LICENSE +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/MANIFEST.in +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/README.md +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/clean +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/install +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/lint +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/requirements.testing.txt +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/setup.cfg +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/setup.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/__init__.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/assets/example.txt +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/cli.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/cmd/analyze.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/cmd/copy_large_s3.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/cmd/list_files.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/cmd/save_to_db.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/completed_process.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/config.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/convert.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/db/__init__.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/db/db.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/db/models.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/deprecated.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/diff.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/dir.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/dir_listing.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/exec.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/experimental/flags.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/experimental/flags_base.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/file.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/file_item.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/filelist.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/group_files.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/http_server.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/log.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/mount.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/mount_read_chunker.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/process.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/profile/mount_copy_bytes.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/rclone.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/remote.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/rpath.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/s3/api.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/s3/basic_ops.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/s3/chunk_types.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/s3/create.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/s3/types.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/scan_missing_folders.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/util.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api/walk.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api.egg-info/SOURCES.txt +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api.egg-info/dependency_links.txt +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api.egg-info/entry_points.txt +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api.egg-info/requires.txt +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/src/rclone_api.egg-info/top_level.txt +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/test +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/archive/test_paramiko.py.disabled +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_cmd_list_files.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_copy.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_copy_bytes.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_copy_file_resumable_s3.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_copy_files.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_db.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_diff.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_file_item.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_group_files.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_is_synced.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_ls.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_ls_stream_files.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_mount.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_mount_s3.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_obscure.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_rclone_config.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_remote_control.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_remotes.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_s3.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_scan_missing_folders.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_serve_http.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_size_files.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_size_suffix.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tests/test_walk.py +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/tox.ini +0 -0
- {rclone_api-1.3.23 → rclone_api-1.3.24}/upload_package.sh +0 -0
@@ -189,6 +189,8 @@ def file_chunker(
|
|
189
189
|
)
|
190
190
|
fut.add_done_callback(callback.on_complete)
|
191
191
|
# wait until the queue_upload queue can accept the next chunk
|
192
|
+
qsize = queue_upload.qsize()
|
193
|
+
print(f"queue_upload_size: {qsize}")
|
192
194
|
while queue_upload.full():
|
193
195
|
time.sleep(0.1)
|
194
196
|
except Exception as e:
|
@@ -25,7 +25,10 @@ _MIN_UPLOAD_CHUNK_SIZE = 5 * 1024 * 1024 # 5MB
|
|
25
25
|
|
26
26
|
|
27
27
|
def upload_task(
|
28
|
-
info: UploadInfo,
|
28
|
+
info: UploadInfo,
|
29
|
+
chunk: FilePart,
|
30
|
+
part_number: int,
|
31
|
+
retries: int,
|
29
32
|
) -> FinishedPiece:
|
30
33
|
file_or_err: Path | Exception = chunk.get_file()
|
31
34
|
if isinstance(file_or_err, Exception):
|
@@ -139,6 +142,40 @@ def _abort_previous_upload(upload_state: UploadState) -> None:
|
|
139
142
|
locked_print(f"Error aborting previous upload: {e}")
|
140
143
|
|
141
144
|
|
145
|
+
def upload_runner(
|
146
|
+
upload_state: UploadState,
|
147
|
+
upload_info: UploadInfo,
|
148
|
+
upload_threads: int,
|
149
|
+
queue_upload: Queue[FilePart | EndOfStream],
|
150
|
+
cancel_chunker_event: Event,
|
151
|
+
) -> None:
|
152
|
+
with ThreadPoolExecutor(max_workers=upload_threads) as executor:
|
153
|
+
try:
|
154
|
+
while True:
|
155
|
+
file_chunk: FilePart | EndOfStream = queue_upload.get()
|
156
|
+
if isinstance(file_chunk, EndOfStream):
|
157
|
+
break
|
158
|
+
|
159
|
+
def task(upload_info=upload_info, file_chunk=file_chunk):
|
160
|
+
return handle_upload(upload_info, file_chunk)
|
161
|
+
|
162
|
+
fut = executor.submit(task)
|
163
|
+
|
164
|
+
def done_cb(fut=fut):
|
165
|
+
result = fut.result()
|
166
|
+
if isinstance(result, Exception):
|
167
|
+
warnings.warn(f"Error uploading part: {result}, skipping")
|
168
|
+
return
|
169
|
+
# upload_state.finished_parts.put(result)
|
170
|
+
upload_state.add_finished(result)
|
171
|
+
|
172
|
+
fut.add_done_callback(done_cb)
|
173
|
+
except Exception:
|
174
|
+
cancel_chunker_event.set()
|
175
|
+
executor.shutdown(wait=False, cancel_futures=True)
|
176
|
+
raise
|
177
|
+
|
178
|
+
|
142
179
|
def upload_file_multipart(
|
143
180
|
s3_client: BaseClient,
|
144
181
|
chunk_fetcher: Callable[[int, int, Any], Future[FilePart]],
|
@@ -265,32 +302,13 @@ def upload_file_multipart(
|
|
265
302
|
try:
|
266
303
|
thread_chunker = Thread(target=chunker_task, daemon=True)
|
267
304
|
thread_chunker.start()
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
def task(upload_info=upload_info, file_chunk=file_chunk):
|
277
|
-
return handle_upload(upload_info, file_chunk)
|
278
|
-
|
279
|
-
fut = executor.submit(task)
|
280
|
-
|
281
|
-
def done_cb(fut=fut):
|
282
|
-
result = fut.result()
|
283
|
-
if isinstance(result, Exception):
|
284
|
-
warnings.warn(f"Error uploading part: {result}, skipping")
|
285
|
-
return
|
286
|
-
# upload_state.finished_parts.put(result)
|
287
|
-
upload_state.add_finished(result)
|
288
|
-
|
289
|
-
fut.add_done_callback(done_cb)
|
290
|
-
except Exception:
|
291
|
-
cancel_chunker_event.set()
|
292
|
-
executor.shutdown(wait=False, cancel_futures=True)
|
293
|
-
raise
|
305
|
+
upload_runner(
|
306
|
+
upload_state=upload_state,
|
307
|
+
upload_info=upload_info,
|
308
|
+
upload_threads=upload_threads,
|
309
|
+
queue_upload=queue_upload,
|
310
|
+
cancel_chunker_event=cancel_chunker_event,
|
311
|
+
)
|
294
312
|
# upload_state.finished_parts.put(None) # Signal the end of the queue
|
295
313
|
upload_state.add_finished(EndOfStream())
|
296
314
|
thread_chunker.join()
|
@@ -299,6 +299,7 @@ class FilePart:
|
|
299
299
|
self.payload = payload
|
300
300
|
return
|
301
301
|
if isinstance(payload, bytes):
|
302
|
+
print(f"Creating file part with payload: {len(payload)}")
|
302
303
|
self.payload = get_chunk_tmpdir() / f"{random_str(12)}.chunk"
|
303
304
|
with _TMP_DIR_ACCESS_LOCK:
|
304
305
|
if not self.payload.parent.exists():
|
@@ -306,7 +307,9 @@ class FilePart:
|
|
306
307
|
self.payload.write_bytes(payload)
|
307
308
|
_add_for_cleanup(self.payload)
|
308
309
|
if isinstance(payload, Path):
|
310
|
+
print("Adopting payload: ", payload)
|
309
311
|
self.payload = payload
|
312
|
+
_add_for_cleanup(self.payload)
|
310
313
|
|
311
314
|
def get_file(self) -> Path | Exception:
|
312
315
|
return self.payload
|
@@ -344,18 +347,26 @@ class FilePart:
|
|
344
347
|
return isinstance(self.payload, Exception)
|
345
348
|
|
346
349
|
def dispose(self) -> None:
|
350
|
+
print("Disposing file part")
|
347
351
|
with self._lock:
|
348
352
|
if isinstance(self.payload, Exception):
|
349
353
|
warnings.warn(
|
350
354
|
f"Cannot close file part because the payload represents an error: {self.payload}"
|
351
355
|
)
|
356
|
+
print("Cannot close file part because the payload represents an error")
|
352
357
|
return
|
353
358
|
if self.payload.exists():
|
359
|
+
print(f"File part {self.payload} exists")
|
354
360
|
try:
|
361
|
+
print(f"Unlinking file part {self.payload}")
|
355
362
|
self.payload.unlink()
|
356
363
|
print(f"File part {self.payload} deleted")
|
357
364
|
except Exception as e:
|
358
365
|
warnings.warn(f"Cannot close file part because of error: {e}")
|
366
|
+
else:
|
367
|
+
warnings.warn(
|
368
|
+
f"Cannot close file part because it does not exist: {self.payload}"
|
369
|
+
)
|
359
370
|
|
360
371
|
def __del__(self):
|
361
372
|
self.dispose()
|
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
|
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
|