@@ -72,55 +72,70 @@ def create(self, request: Request) -> Response:
7272
7373 selected_label_ids = {label ["id" ] for label in selected_labels }
7474
75+ try :
76+ self ._update_labelings (problem , user , selected_label_ids , remarks )
77+ except PermissionError as e :
78+ return Response ({"detail" : str (e )}, status = 403 )
79+
80+ return Response ({"ok" : True }, status = HTTP_200_OK )
81+
82+ def _update_labelings (
83+ self ,
84+ problem : Problem ,
85+ user : User ,
86+ selected_label_ids : set [int ],
87+ remarks : str ,
88+ ) -> None :
89+ """Update labelings for a problem based on selected labels."""
90+
7591 with transaction .atomic ():
76- # Get all active labelings for this problem
7792 active_labelings = Labeling .objects .filter (
7893 problem = problem , removed_at__isnull = True
79- )
94+ ). select_related ( "label" , "attached_by" )
8095
81- # Determine which labels to remove and which to add
8296 current_label_ids = {labeling .label .pk for labeling in active_labelings }
8397 labels_to_remove = current_label_ids - selected_label_ids
8498 labels_to_add = selected_label_ids - current_label_ids
8599
86- # Mark labels as removed
87100 for labeling in active_labelings :
88101 if labeling .label .pk in labels_to_remove :
89- # Check permission for removal
90- if not self ._can_remove_labeling (user , labeling ):
91- logger .warning (
92- f"User { user .username } attempted to remove label { labeling .label .pk } "
93- f"attached by { labeling .attached_by .username } "
94- )
95- return Response (
96- {
97- "error" : "You can only remove labels you attached yourself."
98- },
99- status = 403 ,
100- )
101- labeling .removed_at = timezone .now ()
102- labeling .removed_by = user
103- if remarks :
104- labeling .notes = remarks
105- labeling .save ()
106-
107- # Add new labels
102+ self ._remove_labeling (
103+ labeling = labeling ,
104+ user = user ,
105+ remarks = remarks ,
106+ )
107+
108108 for label_id in labels_to_add :
109- Labeling .objects .create (
110- problem = problem ,
109+ self ._create_labeling (
111110 label_id = label_id ,
112- attached_by = user ,
113- notes = remarks ,
111+ problem = problem ,
112+ user = user ,
113+ remarks = remarks ,
114114 )
115115
116- return Response ({"ok" : True }, status = HTTP_200_OK )
117-
118- def _can_remove_labeling (self , user : User , labeling : Labeling ) -> bool :
119- """Check if user can remove a specific labeling."""
120- if user .is_superuser or user .has_perm ("annotation.delete_any_labeling" ):
121- return True
122-
123- if user .has_perm ("annotation.delete_own_labeling" ):
124- return labeling .attached_by .pk == user .pk
125-
126- return False
116+ def _create_labeling (
117+ self , label_id : int , problem : Problem , user : User , remarks : str
118+ ) -> None :
119+ """Create a new labeling."""
120+
121+ Labeling .objects .create (
122+ problem = problem ,
123+ label_id = label_id ,
124+ attached_by = user ,
125+ notes = remarks ,
126+ )
127+
128+ def _remove_labeling (self , labeling : Labeling , user : User , remarks : str ) -> None :
129+ """Mark a labeling as removed."""
130+
131+ if not user .can_remove_labeling (labeling ):
132+ logger .warning (
133+ f"User { user .username } attempted to remove label { labeling .label .pk } "
134+ f"attached by { labeling .attached_by .username } "
135+ )
136+ raise PermissionError ("You can only remove labels you attached yourself." )
137+ labeling .removed_at = timezone .now ()
138+ labeling .removed_by = user
139+ if remarks :
140+ labeling .notes = remarks
141+ labeling .save ()
0 commit comments