def get_sessions_and_total_times(self, annotation_data, current_user): # Paperjs objects are complex, so they will not always be passed. Therefor we update # the annotation twice, checking if the paperjs exists. sessions = [] total_time = 0 for session in annotation_data.get('sessions', []): date = datetime.datetime.fromtimestamp( int(session.get('start')) / 1e3) model = SessionEvent( user=current_user.get_username(), created_at=date, milliseconds=session.get('milliseconds'), tools_used=session.get('tools'), ) total_time += session.get('milliseconds') sessions.append(model) return sessions, total_time
def disconnect(): if current_user.is_authenticated: logger.info( f'Socket connection has been disconnected with {current_user.username}' ) image_id = session.get('annotating') # Remove user from room if image_id is not None: image = ImageModel.objects(id=image_id).first() if image is not None: start = session.get('annotating_time', time.time()) event = SessionEvent.create(start, current_user) image.add_event(event) image.update(pull__annotating=current_user.username) emit('annotating', { 'image_id': image_id, 'active': False, 'username': current_user.username }, broadcast=True, include_self=False)
def post(self): """ Called when saving data from the annotator client """ data = request.get_json(force=True) image = data.get('image') dataset = data.get('dataset') image_id = image.get('id') image_model = ImageModel.objects(id=image_id).first() if image_model is None: return {'success': False, 'message': 'Image does not exist'}, 400 # Check if current user can access dataset db_dataset = current_user.datasets.filter( id=image_model.dataset_id).first() if dataset is None: return { 'success': False, 'message': 'Could not find associated dataset' } db_dataset.update(annotate_url=dataset.get('annotate_url', '')) categories = CategoryModel.objects.all() annotations = AnnotationModel.objects(image_id=image_id) current_user.update(preferences=data.get('user', {})) annotated = False # Iterate every category passed in the data for category in data.get('categories', []): category_id = category.get('id') # Find corresponding category object in the database db_category = categories.filter(id=category_id).first() if db_category is None: continue category_update = {'color': category.get('color')} if current_user.can_edit(db_category): category_update['keypoint_edges'] = category.get( 'keypoint_edges', []) category_update['keypoint_labels'] = category.get( 'keypoint_labels', []) db_category.update(**category_update) # Iterate every annotation from the data annotations for annotation in category.get('annotations', []): # Find corresponding annotation object in database annotation_id = annotation.get('id') db_annotation = annotations.filter(id=annotation_id).first() if db_annotation is None: continue # Paperjs objects are complex, so they will not always be passed. Therefor we update # the annotation twice, checking if the paperjs exists. # Update annotation in database sessions = [] total_time = 0 for session in annotation.get('sessions', []): date = datetime.datetime.fromtimestamp( int(session.get('start')) / 1e3) model = SessionEvent( user=current_user.username, created_at=date, milliseconds=session.get('milliseconds'), tools_used=session.get('tools')) total_time += session.get('milliseconds') sessions.append(model) db_annotation.update(add_to_set__events=sessions, inc__milliseconds=total_time, set__keypoints=annotation.get( 'keypoints', []), set__metadata=annotation.get('metadata'), set__color=annotation.get('color')) paperjs_object = annotation.get('compoundPath', []) # Update paperjs if it exists if len(paperjs_object) == 2: width = db_annotation.width height = db_annotation.height # Generate coco formatted segmentation data segmentation, area, bbox = coco_util.\ paperjs_to_coco(width, height, paperjs_object) db_annotation.update( set__segmentation=segmentation, set__area=area, set__bbox=bbox, set__paper_object=paperjs_object, ) if area > 0: annotated = True image_model.update(set__metadata=image.get('metadata', {}), set__annotated=annotated, set__category_ids=image.get('category_ids', []), set__regenerate_thumbnail=annotated) return {"success": True}
def annotating(data): """ Socket for handling image locking and time logging """ image_id = data.get('image_id') active = data.get('active') image = ImageModel.objects(id=image_id).first() if image is None: # invalid image ID return emit('annotating', { 'image_id': image_id, 'active': active, 'username': current_user.username }, broadcast=True, include_self=False) if active: logger.info( f'{current_user.username} has started annotating image {image_id}') # Remove user from pervious room previous = session.get('annotating') if previous is not None: leave_room(previous) previous_image = ImageModel.objects(id=previous).first() if previous_image is not None: start = session.get('annotating_time', time.time()) event = SessionEvent.create(start, current_user) previous_image.add_event(event) previous_image.update(pull__annotating=current_user.username) emit('annotating', { 'image_id': previous, 'active': False, 'username': current_user.username }, broadcast=True, include_self=False) join_room(image_id) session['annotating'] = image_id session['annotating_time'] = time.time() image.update(add_to_set__annotating=current_user.username) else: leave_room(image_id) start = session.get('annotating_time', time.time()) event = SessionEvent.create(start, current_user) image.add_event(event) image.update(pull__annotating=current_user.username) session['annotating'] = None session['time'] = None