Beispiel #1
0
def ajax_save_annotations(request, annotationForm):
    """
    Called via Ajax from the annotation tool form, if the user clicked
    the "Save Annotations" button.

    Takes: the annotation form field names and values, serialized with jQuery's serializeArray()
    Does: saves the annotations in the database
    Returns: false if successful, an error string if there was a problem
    """

    #TODO: just use request.POST instead of the annotationForm parameter
    formDict = dict([ (d['name'], d['value']) for d in annotationForm ])

    image = Image.objects.get(pk=formDict['image_id'])
    user = User.objects.get(pk=formDict['user_id'])
    source = image.source
    sourceLabels = source.labelset.labels.all()

    # Sanity checks
    if user != request.user:
        return simplejson.dumps(dict(error="User id error"))
    if not user.has_perm(Source.PermTypes.EDIT.code, image.source):
        return simplejson.dumps(dict(error="Image id error"))

    # Get stuff from the DB in advance, should save time
    pointsList = list(Point.objects.filter(image=image))
    points = dict([ (p.point_number, p) for p in pointsList ])

    annotationsList = list(Annotation.objects.filter(image=image, source=source))
    annotations = dict([ (a.point_id, a) for a in annotationsList ])

    for name, value in formDict.iteritems():

        if name.startswith('label_'):

            # Get this annotation's point
            pointNum = name[len('label_'):]   # The part after 'label_'
            point = points[int(pointNum)]

            # Does the form field have a non-human-confirmed robot annotation?
            isFormRobotAnnotation = simplejson.loads(formDict['robot_' + pointNum])

            # Get the label that the form field value refers to.
            # Anticipate errors, even if we plan to check input with JS.
            labelCode = value
            if labelCode == '':
                label = None
            else:
                labels = Label.objects.filter(code=labelCode)
                if len(labels) == 0:
                    return simplejson.dumps(dict(error="No label with code %s." % labelCode))

                label = labels[0]
                if label not in sourceLabels:
                    return simplejson.dumps(dict(error="The labelset has no label with code %s." % labelCode))

            # An annotation of this point number exists in the database
            if annotations.has_key(point.id):
                anno = annotations[point.id]
                # Label field is now blank.
                # We're not allowing label deletions, so don't do anything in this case.
                if label is None:
                    pass
                # Label was robot annotated, and then the human user confirmed or changed it
                elif is_robot_user(anno.user) and not isFormRobotAnnotation:
                    anno.label = label
                    anno.user = user
                    anno.save()
                # Label was otherwise changed
                elif label != anno.label:
                    anno.label = label
                    anno.user = user
                    anno.save()

            # No annotation of this point number in the database yet
            else:
                if label is not None:
                    newAnno = Annotation(point=point, user=user, image=image, source=source, label=label)
                    newAnno.save()

    # Are all points human annotated?
    all_done = image_annotation_all_done(image)

    # Update image status, if needed
    if image.status.annotatedByHuman:
        image.after_completed_annotations_change()
    if image.status.annotatedByHuman != all_done:
        image.status.annotatedByHuman = all_done
        image.status.save()

    if all_done:
        # Need simplejson.dumps() to convert the Python True to a JS true
        return simplejson.dumps(dict(all_done=True))
    else:
        return dict()
Beispiel #2
0
def ajax_is_all_done(request, image_id):
    image = get_object_or_404(Image, id=image_id)
    return simplejson.dumps(image_annotation_all_done(image))