def source_new(request): """ Page with the form to create a new Source. """ # We can get here one of two ways: either we just got to the form # page, or we just submitted the form. If POST, we submitted; if # GET, we just got here. if request.method == 'POST': # A form bound to the POST data sourceForm = ImageSourceForm(request.POST) pointGenForm = PointGenForm(request.POST) annotationAreaForm = AnnotationAreaPercentsForm(request.POST) # is_valid() calls our ModelForm's clean() and checks validity source_form_is_valid = sourceForm.is_valid() point_gen_form_is_valid = pointGenForm.is_valid() annotation_area_form_is_valid = annotationAreaForm.is_valid() if source_form_is_valid and point_gen_form_is_valid and annotation_area_form_is_valid: # After calling a ModelForm's is_valid(), an instance is created. # We can get this instance and add a bit more to it before saving to the DB. newSource = sourceForm.instance newSource.default_point_generation_method = PointGen.args_to_db_format(**pointGenForm.cleaned_data) newSource.image_annotation_area = AnnotationAreaUtils.percentages_to_db_format(**annotationAreaForm.cleaned_data) newSource.labelset = LabelSet.getEmptyLabelset() newSource.save() # Make the user a source admin newSource.assign_role(request.user, Source.PermTypes.ADMIN.code) # Add a success message messages.success(request, 'Source successfully created.') # Redirect to the source's main page return HttpResponseRedirect(reverse('source_main', args=[newSource.id])) else: # Show the form again, with error message messages.error(request, 'Please correct the errors below.') else: # An unbound form (empty form) sourceForm = ImageSourceForm() pointGenForm = PointGenForm() annotationAreaForm = AnnotationAreaPercentsForm() # RequestContext needed for CSRF verification of POST form, # and to correctly get the path of the CSS file being used. return render_to_response('images/source_new.html', { 'sourceForm': sourceForm, 'pointGenForm': pointGenForm, 'annotationAreaForm': annotationAreaForm, }, context_instance=RequestContext(request) )
def labelset_list(request): """ Page with a list of all the labelsets Not sure where to put a link to this page. It's a little less useful when each source has its own labelset, but this view still might be useful if someone wants to browse through labelsets that they could base their labelset off of. """ publicSources = Source.objects.filter(visibility=Source.VisibilityTypes.PUBLIC) publicSourcesWithLabelsets = publicSources.exclude(labelset=LabelSet.getEmptyLabelset()) return render_to_response('annotations/labelset_list.html', { 'publicSourcesWithLabelsets': publicSourcesWithLabelsets, }, context_instance=RequestContext(request) )
def test_post_success(self): """ Successful creation of a new source. """ datetime_before_creation = datetime.datetime.now().replace(microsecond=0) response = self.client.post(reverse('source_new'), self.source_args) source_id = Source.objects.latest('create_date').pk self.assertRedirects(response, reverse('source_main', kwargs={ 'source_id': source_id, } )) new_source = Source.objects.get(pk=source_id) self.assertEqual(new_source.name, self.source_args['name']) self.assertEqual(new_source.visibility, self.source_args['visibility']) self.assertEqual(new_source.labelset, LabelSet.getEmptyLabelset()) self.assertEqual(new_source.key1, self.source_args['key1']) self.assertEqual(new_source.key2, '') self.assertEqual(new_source.key3, '') self.assertEqual(new_source.key4, '') self.assertEqual(new_source.key5, '') self.assertEqual(new_source.default_point_generation_method, PointGen.args_to_db_format( point_generation_type=self.source_args['point_generation_type'], simple_number_of_points=self.source_args['simple_number_of_points'], )) self.assertEqual(new_source.image_height_in_cm, self.source_args['image_height_in_cm']) self.assertEqual(new_source.image_annotation_area, AnnotationAreaUtils.percentages_to_db_format( min_x=self.source_args['min_x'], max_x=self.source_args['max_x'], min_y=self.source_args['min_y'], max_y=self.source_args['max_y'], )) self.assertEqual(new_source.longitude, self.source_args['longitude']) self.assertEqual(new_source.latitude, self.source_args['latitude']) self.assertEqual(new_source.enable_robot_classifier, True) # This check is of limited use since database datetimes (in # MySQL 5.1 at least) get truncated to whole seconds. But it still # doesn't hurt to check. self.assertTrue(datetime_before_creation <= new_source.create_date) self.assertTrue(new_source.create_date <= datetime.datetime.now().replace(microsecond=0))
def test_post_success(self): """ Successful edit of an existing source. """ original_source = Source.objects.get(pk=self.source_id) original_create_date = original_source.create_date original_enable_robot = original_source.enable_robot_classifier response = self.client.post(reverse('source_edit', kwargs={'source_id': self.source_id}), self.source_args, ) self.assertRedirects(response, reverse('source_main', kwargs={'source_id': self.source_id} )) edited_source = Source.objects.get(pk=self.source_id) self.assertEqual(edited_source.name, self.source_args['name']) self.assertEqual(edited_source.visibility, self.source_args['visibility']) self.assertEqual(edited_source.create_date, original_create_date) self.assertEqual(edited_source.labelset, LabelSet.getEmptyLabelset()) self.assertEqual(edited_source.key1, self.source_args['key1']) self.assertEqual(edited_source.key2, '') self.assertEqual(edited_source.key3, '') self.assertEqual(edited_source.key4, '') self.assertEqual(edited_source.key5, '') self.assertEqual(edited_source.default_point_generation_method, PointGen.args_to_db_format( point_generation_type=self.source_args['point_generation_type'], simple_number_of_points=self.source_args['simple_number_of_points'], )) self.assertEqual(edited_source.image_height_in_cm, self.source_args['image_height_in_cm']) self.assertEqual(edited_source.image_annotation_area, AnnotationAreaUtils.percentages_to_db_format( min_x=self.source_args['min_x'], max_x=self.source_args['max_x'], min_y=self.source_args['min_y'], max_y=self.source_args['max_y'], )) self.assertEqual(edited_source.longitude, self.source_args['longitude']) self.assertEqual(edited_source.latitude, self.source_args['latitude']) self.assertEqual(edited_source.enable_robot_classifier, original_enable_robot)
def import_labels(request, source_id): """ Create a labelset through a text file. NOTE: This view might be obsolete. Or site-admin only. """ source = get_object_or_404(Source, id=source_id) #creates a new labelset for the source labelset = LabelSet() labelset.save() labelsImported = 0 newLabels = 0 existingLabels = 0 if request.method == 'POST': labelImportForm = LabelImportForm(request.POST, request.FILES) if labelImportForm.is_valid(): file = request.FILES['labels_file'] # We'll assume we're using an InMemoryUploadedFile, as opposed to a filename of a temp-disk-storage file. # If we encounter a case where we have a filename, use the below: #file = open(fileLocation, 'r') #opens the file for reading #iterates over each line in the file and processes it for line in file: #sanitizes and splits apart the string/line line = line.strip().replace("; ", ';') words = line.split(';') # Ignore blank lines if line == '': continue labelName, labelCode, groupName = words[0], words[1], words[2] group = get_object_or_404(LabelGroup, name=groupName) # (1) Create a new label, (2) use an existing label, # or (3) throw an error if a file label and existing # label of the same code don't match. try: existingLabel = Label.objects.get(code=labelCode) except Label.DoesNotExist: #creates a label object and stores it in the database label = Label(name=labelName, code=labelCode, group=group) label.save() newLabels += 1 else: if (existingLabel.name == labelName and existingLabel.code == labelCode and existingLabel.group == group ): label = existingLabel existingLabels += 1 else: raise ValidationError( """Our database already has a label with code %s, but it doesn't match yours. Ours: %s, %s, %s Yours: %s, %s, %s""" % ( labelCode, existingLabel.name, existingLabel.code, existingLabel.group.name, labelName, labelCode, groupName )) #adds label to the labelset labelset.labels.add(label) labelsImported += 1 file.close() #closes file since we're done labelset.description = labelImportForm.cleaned_data['labelset_description'] labelset.save() source.labelset = labelset source.save() success_msg = "%d labels imported: %d new labels and %d existing labels." % (labelsImported, newLabels, existingLabels) messages.success(request, success_msg) return HttpResponseRedirect(reverse('source_main', args=[source_id])) else: messages.error(request, 'Please correct the errors below.') # GET else: labelImportForm = LabelImportForm() return render_to_response('images/label_import.html', { 'labelImportForm': labelImportForm, 'source': source, }, context_instance=RequestContext(request) )
def source_new(request): """ Page with the form to create a new Source. """ # We can get here one of two ways: either we just got to the form # page, or we just submitted the form. If POST, we submitted; if # GET, we just got here. if request.method == 'POST': # Bind the forms to the submitted POST data. sourceForm = ImageSourceForm(request.POST) location_key_form = LocationKeyForm(request.POST) pointGenForm = PointGenForm(request.POST) annotationAreaForm = AnnotationAreaPercentsForm(request.POST) # <form>.is_valid() calls <form>.clean() and checks field validity. # Make sure is_valid() is called for all forms, so all forms are checked and # all relevant error messages appear. source_form_is_valid = sourceForm.is_valid() location_key_form_is_valid = location_key_form.is_valid() point_gen_form_is_valid = pointGenForm.is_valid() annotation_area_form_is_valid = annotationAreaForm.is_valid() if source_form_is_valid and location_key_form_is_valid \ and point_gen_form_is_valid and annotation_area_form_is_valid: # Since sourceForm is a ModelForm, after calling sourceForm's # is_valid(), a Source instance is created. We retrieve this # instance and add the other values to it before saving to the DB. newSource = sourceForm.instance for key_field in ['key1', 'key2', 'key3', 'key4', 'key5']: if key_field in location_key_form.cleaned_data: setattr(newSource, key_field, location_key_form.cleaned_data[key_field]) newSource.default_point_generation_method = PointGen.args_to_db_format(**pointGenForm.cleaned_data) newSource.image_annotation_area = AnnotationAreaUtils.percentages_to_db_format(**annotationAreaForm.cleaned_data) newSource.labelset = LabelSet.getEmptyLabelset() newSource.save() # Make the current user an admin of the new source newSource.assign_role(request.user, Source.PermTypes.ADMIN.code) # Add a success message messages.success(request, 'Source successfully created.') # Redirect to the source's main page return HttpResponseRedirect(reverse('source_main', args=[newSource.id])) else: # Show the form again, with error message messages.error(request, 'Please correct the errors below.') else: # Unbound (empty) forms sourceForm = ImageSourceForm() location_key_form = LocationKeyForm() pointGenForm = PointGenForm() annotationAreaForm = AnnotationAreaPercentsForm() # RequestContext is needed for CSRF verification of the POST form, # and to correctly get the path of the CSS file being used. return render_to_response('images/source_new.html', { 'sourceForm': sourceForm, 'location_key_form': location_key_form, 'pointGenForm': pointGenForm, 'annotationAreaForm': annotationAreaForm, }, context_instance=RequestContext(request) )