def test_extract_features(self): # Create a dataset and an instance dataset = DatasetFactory() instance = InstanceFactory() dataset.instances.add(instance) dataset.save() # The file path of the test audio file file_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), self.audio_file_name ) # Extract the features extract_features(dataset.pk, instance.pk, file_path) # The duration, rate, and ZCR duration = Feature.objects.get(name='duration') duration_value = instance.values.get(feature=duration) sample_rate = Feature.objects.get(name='sample rate') sample_rate_value = instance.values.get(feature=sample_rate) spec_centroid = Feature.objects.get(name='spectral centroid') spec_centroid_value = instance.values.get(feature=spec_centroid) zcr = Feature.objects.get(name='zcr') zcr_value = instance.values.get(feature=zcr) # Test that the values are correct assert_equal(round(duration_value.value, 3), 9.639) assert_equal(round(sample_rate_value.value, 3), 11025.000) assert_equal(round(spec_centroid_value.value, 3), 112.283) assert_equal(round(zcr_value.value, 3), 0.061) # The features should have correct units assert_equal('s', duration.unit) assert_equal('Hz', sample_rate.unit) assert_equal("Hz", zcr.unit)
def multiple_uploader(request, pk): '''View for handling file uploads with the jQuery multiple file upload widget. NOTE: must be a POST request. ''' d = Dataset.objects.get(pk=pk) options = { # the maximum file size "maxfilesize": 2 * 2 ** 20, # 2 Mb # the minimum file size (must be in bytes) "minfilesize": 1 * 2 ** 10, # 1 Kb # the file types which are going to be allowed for upload # must be a mimetype "acceptedformats": ( "audio/wav", 'audio/x-wav', 'audio/wav', 'audio/x-wav', 'audio/wave', 'audio/vnd.wave' ) } if request.POST: if request.FILES == None: raise Http404("No objects uploaded") f = request.FILES[u'files[]'] filtered_files = Audio.objects.filter( instance__dataset=d).values_list( 'audio_file', flat=True) # the paths of files associated with this dataet filtered_paths = [os.path.join(settings.MEDIA_ROOT, file_url) for file_url in filtered_files] # the path where the file would be uploaded to file_path = os.path.join(settings.MEDIA_ROOT, 'audio', f.name) # initialize the error # If error occurs, this will have the string error message so # uploader can display the appropriate message error = False # check against options for errors # file size if f.size > options["maxfilesize"]: error = "maxFileSize" if f.size < options["minfilesize"]: error = "minFileSize" # allowed file type if f.content_type not in options["acceptedformats"]: error = "acceptFileTypes" # prevent uploading of duplicate files # FIXME: this validatio doesn't work after a file is deleted if file_path in filtered_paths: error = 'fileAlreadyExists' # FIXME: can't upload files with a space in filename # because spaces get converted to underscores on upload and result in a FileNotFound error # NOTE: this is a temporary fix if ' ' in f.name: error = 'invalidFileName' result = {'name': f.name, 'size': f.size, } if error: # append error message result["error"] = error # generate json response_data = simplejson.dumps([result]) # return response to uploader with error # so it can display error message return HttpResponse(response_data, mimetype='application/json') if f.content_type in ('audio/wav', 'audio/x-wav', 'audio/wave', 'audio/vnd.wave'): # Create new Audio object # This uploads the file to media/audio audio_obj = Audio(audio_file=f) audio_obj.save() if audio_obj: # Create new instance and associate it with the audio file instance = Instance(dataset=d) instance.audio = audio_obj instance.save() extract_features(d.pk, instance.pk, os.path.join(settings.MEDIA_ROOT, 'audio', f.name)) result['url'] = audio_obj.audio_file.url # data that is dynamically added as a table row after the upload is finished result['instance_data'] = instance.as_table_row() result['instance_id'] = instance.pk # Label name obj. NOTE: assumes one label per dataset label_name = instance.labels().keys()[0] result['edit_label_url'] = reverse('datasets:update_instance_label', args=(instance.dataset.pk, instance.pk, label_name.pk)) response_data = simplejson.dumps([result]) mimetype = 'text/plain' if request.is_ajax(): mimetype = 'application/json' return HttpResponse(response_data, mimetype=mimetype) else: return HttpResponse('Only POST accepted')