22from typing import List
33from typing import Optional
44
5- import superannotate .lib .core as constances
5+ import superannotate .lib .core as constants
66from lib .core .conditions import Condition
77from lib .core .conditions import CONDITION_EQ as EQ
88from lib .core .entities import AttachmentEntity
2222from lib .core .serviceproviders import SuperannotateServiceProvider
2323from lib .core .usecases .base import BaseReportableUseCase
2424from lib .core .usecases .base import BaseUseCase
25+ from lib .core .entities import ImageEntity
2526from superannotate .logger import get_default_logger
2627
2728logger = get_default_logger ()
2829
30+ class GetBulkItems (BaseUseCase ):
31+ def __init__ (
32+ self ,
33+ service : SuperannotateServiceProvider ,
34+ project_id : int ,
35+ team_id : int ,
36+ folder_id : int ,
37+ items : List [str ],
38+ ):
39+ super ().__init__ ()
40+ self ._service = service
41+ self ._project_id = project_id
42+ self ._team_id = team_id
43+ self ._folder_id = folder_id
44+ self ._items = items
45+ self ._chunk_size = 500
46+
47+ def execute (self ):
48+ res = []
49+ for i in range (0 , len (self ._items ), self ._chunk_size ):
50+ response = self ._service .get_bulk_items (
51+ project_id = self ._project_id ,
52+ team_id = self ._team_id ,
53+ folder_id = self ._folder_id ,
54+ items = self ._items [i : i + self ._chunk_size ], # noqa: E203
55+ )
56+
57+ if not response .ok :
58+ raise AppException (response .error )
59+ #TODO stop using Image Entity when it gets deprecated and from_dict gets implemented for items
60+ res += [ImageEntity .from_dict (** item ) for item in response .data ]
61+ self ._response .data = res
62+ return self ._response
2963
3064class GetItem (BaseReportableUseCase ):
3165 def __init__ (
@@ -44,22 +78,22 @@ def __init__(
4478
4579 @staticmethod
4680 def serialize_entity (entity : Entity , project : ProjectEntity ):
47- if project .upload_state != constances .UploadState .EXTERNAL .value :
81+ if project .upload_state != constants .UploadState .EXTERNAL .value :
4882 entity .url = None
4983 if project .type in (
50- constances .ProjectType .VECTOR .value ,
51- constances .ProjectType .PIXEL .value ,
84+ constants .ProjectType .VECTOR .value ,
85+ constants .ProjectType .PIXEL .value ,
5286 ):
5387 tmp_entity = entity
54- if project .type == constances .ProjectType .VECTOR .value :
88+ if project .type == constants .ProjectType .VECTOR .value :
5589 entity .segmentation_status = None
56- if project .upload_state == constances .UploadState .EXTERNAL .value :
90+ if project .upload_state == constants .UploadState .EXTERNAL .value :
5791 tmp_entity .prediction_status = None
5892 tmp_entity .segmentation_status = None
5993 return TmpImageEntity (** tmp_entity .dict (by_alias = True ))
60- elif project .type == constances .ProjectType .VIDEO .value :
94+ elif project .type == constants .ProjectType .VIDEO .value :
6195 return VideoEntity (** entity .dict (by_alias = True ))
62- elif project .type == constances .ProjectType .DOCUMENT .value :
96+ elif project .type == constants .ProjectType .DOCUMENT .value :
6397 return DocumentEntity (** entity .dict (by_alias = True ))
6498 return entity
6599
@@ -320,13 +354,13 @@ def __init__(
320354 attachments : List [AttachmentEntity ],
321355 annotation_status : str ,
322356 backend_service_provider : SuperannotateServiceProvider ,
323- upload_state_code : int = constances .UploadState .EXTERNAL .value ,
357+ upload_state_code : int = constants .UploadState .EXTERNAL .value ,
324358 ):
325359 super ().__init__ (reporter )
326360 self ._project = project
327361 self ._folder = folder
328362 self ._attachments = attachments
329- self ._annotation_status_code = constances .AnnotationStatus .get_value (
363+ self ._annotation_status_code = constants .AnnotationStatus .get_value (
330364 annotation_status
331365 )
332366 self ._upload_state_code = upload_state_code
@@ -349,18 +383,18 @@ def validate_limitations(self):
349383 if not response .ok :
350384 raise AppValidationException (response .error )
351385 if attachments_count > response .data .folder_limit .remaining_image_count :
352- raise AppValidationException (constances .ATTACH_FOLDER_LIMIT_ERROR_MESSAGE )
386+ raise AppValidationException (constants .ATTACH_FOLDER_LIMIT_ERROR_MESSAGE )
353387 elif attachments_count > response .data .project_limit .remaining_image_count :
354- raise AppValidationException (constances .ATTACH_PROJECT_LIMIT_ERROR_MESSAGE )
388+ raise AppValidationException (constants .ATTACH_PROJECT_LIMIT_ERROR_MESSAGE )
355389 elif (
356390 response .data .user_limit
357391 and attachments_count > response .data .user_limit .remaining_image_count
358392 ):
359- raise AppValidationException (constances .ATTACH_USER_LIMIT_ERROR_MESSAGE )
393+ raise AppValidationException (constants .ATTACH_USER_LIMIT_ERROR_MESSAGE )
360394
361395 def validate_upload_state (self ):
362- if self ._project .upload_state == constances .UploadState .BASIC .value :
363- raise AppValidationException (constances .ATTACHING_UPLOAD_STATE_ERROR )
396+ if self ._project .upload_state == constants .UploadState .BASIC .value :
397+ raise AppValidationException (constants .ATTACHING_UPLOAD_STATE_ERROR )
364398
365399 @staticmethod
366400 def generate_meta ():
@@ -447,9 +481,9 @@ def _validate_limitations(self, items_count):
447481 if not response .ok :
448482 raise AppValidationException (response .error )
449483 if items_count > response .data .folder_limit .remaining_image_count :
450- raise AppValidationException (constances .COPY_FOLDER_LIMIT_ERROR_MESSAGE )
484+ raise AppValidationException (constants .COPY_FOLDER_LIMIT_ERROR_MESSAGE )
451485 if items_count > response .data .project_limit .remaining_image_count :
452- raise AppValidationException (constances .COPY_PROJECT_LIMIT_ERROR_MESSAGE )
486+ raise AppValidationException (constants .COPY_PROJECT_LIMIT_ERROR_MESSAGE )
453487
454488 def validate_item_names (self ):
455489 if self ._item_names :
@@ -575,9 +609,9 @@ def _validate_limitations(self, items_count):
575609 if not response .ok :
576610 raise AppValidationException (response .error )
577611 if items_count > response .data .folder_limit .remaining_image_count :
578- raise AppValidationException (constances .MOVE_FOLDER_LIMIT_ERROR_MESSAGE )
612+ raise AppValidationException (constants .MOVE_FOLDER_LIMIT_ERROR_MESSAGE )
579613 if items_count > response .data .project_limit .remaining_image_count :
580- raise AppValidationException (constances .MOVE_PROJECT_LIMIT_ERROR_MESSAGE )
614+ raise AppValidationException (constants .MOVE_PROJECT_LIMIT_ERROR_MESSAGE )
581615
582616 def execute (self ):
583617 if self .is_valid ():
@@ -635,7 +669,7 @@ def __init__(
635669 self ._folder = folder
636670 self ._item_names = item_names
637671 self ._items = items
638- self ._annotation_status_code = constances .AnnotationStatus .get_value (
672+ self ._annotation_status_code = constants .AnnotationStatus .get_value (
639673 annotation_status
640674 )
641675 self ._backend_service = backend_service_provider
@@ -687,3 +721,57 @@ def execute(self):
687721 self ._response .errors = AppException (self .ERROR_MESSAGE )
688722 break
689723 return self ._response
724+
725+ class DeleteItemsUseCase (BaseUseCase ):
726+ CHUNK_SIZE = 1000
727+
728+ def __init__ (
729+ self ,
730+ project : ProjectEntity ,
731+ folder : FolderEntity ,
732+ backend_service_provider : SuperannotateServiceProvider ,
733+ items : BaseReadOnlyRepository ,
734+ item_names : List [str ] = None ,
735+ ):
736+ super ().__init__ ()
737+ self ._project = project
738+ self ._folder = folder
739+ self ._items = items
740+ self ._backend_service = backend_service_provider
741+ self ._item_names = item_names
742+
743+ def execute (self ):
744+ if self .is_valid ():
745+ if self ._item_names :
746+ item_ids = [
747+ item .uuid
748+ for item in GetBulkItems (
749+ service = self ._backend_service ,
750+ project_id = self ._project .id ,
751+ team_id = self ._project .team_id ,
752+ folder_id = self ._folder .uuid ,
753+ items = self ._item_names ,
754+ )
755+ .execute ()
756+ .data
757+ ]
758+ else :
759+ condition = (
760+ Condition ("team_id" , self ._project .team_id , EQ )
761+ & Condition ("project_id" , self ._project .id , EQ )
762+ & Condition ("folder_id" , self ._folder .uuid , EQ )
763+ )
764+ item_ids = [item .id for item in self ._items .get_all (condition )]
765+
766+ for i in range (0 , len (item_ids ), self .CHUNK_SIZE ):
767+ response = self ._backend_service .delete_items (
768+ project_id = self ._project .id ,
769+ team_id = self ._project .team_id ,
770+ item_ids = item_ids [i : i + self .CHUNK_SIZE ], # noqa: E203
771+ )
772+
773+ logger .info (
774+ f"Items deleted in project { self ._project .name } { '/' + self ._folder .name if not self ._folder .is_root else '' } "
775+ )
776+
777+ return self ._response
0 commit comments