Skip to content

Commit ff1109a

Browse files
committed
Add drag-and-drop image upload & quarantine
Add support for uploading images via drag-and-drop and bulk form uploads and handle unreadable images by quarantining them. Backend: new endpoints for single and bulk uploads (/api/local/sessions/{id}/images/upload and /bulk-upload), session notifications endpoint, CacheStore.delete_dataset_manifest_images, upload helpers (sanitize, temp write, chunked reads), quarantine/move-to-not_valid logic, InvalidSessionImageError, and integration into fingerprint warmup/duplicate search flows. Frontend: drag-and-drop overlay, handlers, batching, upload progress UI, new API types and upload functions, notification polling, and updates to deletion flow to use summary responses. Also add CSS for the drop overlay and add python-multipart to requirements for multipart uploads.
1 parent 3770019 commit ff1109a

6 files changed

Lines changed: 1335 additions & 64 deletions

File tree

backend/app/cache_store.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,53 @@ def save_dataset_manifest(
511511
(dataset_key, dataset_key),
512512
)
513513

514+
def delete_dataset_manifest_images(
515+
self,
516+
root_path: Path,
517+
image_ids: Sequence[str],
518+
relative_paths: Sequence[str],
519+
image_count: int,
520+
):
521+
dataset_key = self.dataset_key_for_path(root_path)
522+
unique_image_ids = list(dict.fromkeys(image_ids))
523+
unique_relative_paths = list(dict.fromkeys(relative_paths))
524+
now = time.time()
525+
526+
if not unique_image_ids and not unique_relative_paths:
527+
return
528+
529+
with self._lock:
530+
with self._connect() as connection:
531+
if unique_relative_paths:
532+
connection.executemany(
533+
"""
534+
DELETE FROM dataset_images
535+
WHERE dataset_key = ? AND relative_path = ?
536+
""",
537+
[
538+
(dataset_key, relative_path)
539+
for relative_path in unique_relative_paths
540+
],
541+
)
542+
543+
if unique_image_ids:
544+
connection.executemany(
545+
"""
546+
DELETE FROM image_fingerprints
547+
WHERE dataset_key = ? AND image_id = ?
548+
""",
549+
[(dataset_key, image_id) for image_id in unique_image_ids],
550+
)
551+
552+
connection.execute(
553+
"""
554+
UPDATE dataset_manifests
555+
SET image_count = ?, updated_at = ?
556+
WHERE dataset_key = ?
557+
""",
558+
(image_count, now, dataset_key),
559+
)
560+
514561
def update_dataset_annotation_metadata(
515562
self,
516563
root_path: Path,

0 commit comments

Comments
 (0)