def test_bag_ingestion(self): from hs_core.views.utils import unzip_file def normalize_metadata(metadata_str): """Prepares metadata string to match resource id and hydroshare url of original""" return metadata_str\ .replace(current_site_url(), "http://www.hydroshare.org")\ .replace(res.short_id, "97523bdb7b174901b3fc2d89813458f1") # create empty resource res = resource.create_resource( 'CompositeResource', self.user, 'My Test Resource' ) full_paths = {} files_to_upload = [UploadedFile(file=open('hs_core/tests/data/test_resource_metadata_files.zip', 'rb'), name="test_resource_metadata_files.zip")] add_resource_files(res.short_id, *files_to_upload, full_paths=full_paths) unzip_file(self.user, res.short_id, "data/contents/test_resource_metadata_files.zip", True, overwrite=True, auto_aggregate=True, ingest_metadata=True) def compare_metadatas(new_metadata_str, original_metadata_file): original_graph = Graph() with open(os.path.join(self.extracted_directory, original_metadata_file), "r") as f: original_graph = original_graph.parse(data=f.read()) new_graph = Graph() new_graph = new_graph.parse(data=normalize_metadata(new_metadata_str)) # remove modified date, they'll never match subject = new_graph.value(predicate=RDF.type, object=DCTERMS.modified) new_graph.remove((subject, None, None)) subject = original_graph.value(predicate=RDF.type, object=DCTERMS.modified) original_graph.remove((subject, None, None)) for (new_triple, original_triple) in _squashed_graphs_triples(new_graph, original_graph): self.assertEquals(new_triple, original_triple, "Ingested resource metadata does not match original") res.refresh_from_db() compare_metadatas(res.metadata.get_xml(), "resourcemetadata.xml") compare_metadatas(res.get_logical_files(GenericLogicalFile.type_name())[0].metadata.get_xml(), "test_meta.xml") compare_metadatas(res.get_logical_files(FileSetLogicalFile.type_name())[0].metadata.get_xml(), "asdf/asdf_meta.xml") compare_metadatas(res.get_logical_files(GeoFeatureLogicalFile.type_name())[0].metadata.get_xml(), "watersheds_meta.xml") compare_metadatas(res.get_logical_files(GeoRasterLogicalFile.type_name())[0].metadata.get_xml(), "logan_meta.xml") compare_metadatas(res.get_logical_files(NetCDFLogicalFile.type_name())[0].metadata.get_xml(), "SWE_time_meta.xml") compare_metadatas(res.get_logical_files(RefTimeseriesLogicalFile.type_name())[0].metadata.get_xml(), "msf_version.refts_meta.xml") compare_metadatas(res.get_logical_files(TimeSeriesLogicalFile.type_name())[0].metadata.get_xml(), "ODM2_Multi_Site_One_Variable_meta.xml")
def unzip_task(user_pk, res_id, zip_with_rel_path, bool_remove_original, overwrite=False, auto_aggregate=False, ingest_metadata=False): from hs_core.views.utils import unzip_file user = User.objects.get(pk=user_pk) unzip_file(user, res_id, zip_with_rel_path, bool_remove_original, overwrite, auto_aggregate, ingest_metadata)
def data_store_folder_unzip(request, **kwargs): """ Unzip requested zip file while preserving folder structures in hydroshareZone or any federated zone used for HydroShare resource backend store. It is invoked by an AJAX call, and returns json object that holds the root path that contains the zipped content if it succeeds, and an empty string if it fails. The AJAX request must be a POST request with input data passed in for res_id, zip_with_rel_path, and remove_original_zip where zip_with_rel_path is the zip file name with relative path under res_id collection to be unzipped, and remove_original_zip has a value of "true" or "false" (default is "true") indicating whether original zip file will be deleted after unzipping. """ res_id = request.POST.get('res_id', kwargs.get('res_id')) if res_id is None: return HttpResponse('Bad request - resource id is not included', status=status.HTTP_400_BAD_REQUEST) res_id = str(res_id).strip() try: resource, _, user = authorize(request, res_id, needed_permission=ACTION_TO_AUTHORIZE.EDIT_RESOURCE) except NotFound: return HttpResponse('Bad request - resource not found', status=status.HTTP_400_BAD_REQUEST) except PermissionDenied: return HttpResponse('Permission denied', status=status.HTTP_401_UNAUTHORIZED) zip_with_rel_path = request.POST.get('zip_with_rel_path', kwargs.get('zip_with_rel_path')) try: zip_with_rel_path = _validate_path(zip_with_rel_path, 'zip_with_rel_path') except ValidationError as ex: return HttpResponse(ex.message, status=status.HTTP_400_BAD_REQUEST) overwrite = request.POST.get('overwrite', 'false').lower() == 'true' # False by default remove_original_zip = request.POST.get('remove_original_zip', 'true').lower() == 'true' try: unzip_file(user, res_id, zip_with_rel_path, bool_remove_original=remove_original_zip, overwrite=overwrite) except SessionException as ex: specific_msg = "iRODS error resulted in unzip being cancelled. This may be due to " \ "protection from overwriting existing files. Unzip in a different " \ "location (e.g., folder) or move or rename the file being overwritten. " \ "iRODS error follows: " return HttpResponse(specific_msg + ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) # this unzipped_path can be used for POST request input to data_store_structure() # to list the folder structure after unzipping return_object = {'unzipped_path': os.path.dirname(zip_with_rel_path)} return HttpResponse( json.dumps(return_object), content_type="application/json" )
def resource_file_oprs(self): """Test common iRODS file operations. This is a common test utility function to be called by both regular folder operation testing and federated zone folder operation testing. Make sure the calling TestCase object has the following attributes defined before calling this method: self.res: resource that has been created that contains files listed in file_name_list self.user: owner of the resource self.file_name_list: a list of three file names that have been added to the res object self.test_file_1 needs to be present for the calling object for doing regular folder operations without involving federated zone so that the same opened file can be re-added to the resource for testing the case where zipping cannot overwrite existing file """ user = self.user res = self.res file_name_list = self.file_name_list # create a folder, if folder is created successfully, no exception is raised, otherwise, # an iRODS exception will be raised which will be caught by the test runner and mark as # a test failure create_folder(res.short_id, 'data/contents/sub_test_dir') istorage = res.get_irods_storage() res_path = res.file_path store = istorage.listdir(res_path) self.assertIn('sub_test_dir', store[0], msg='resource does not contain created sub-folder') # rename the third file in file_name_list move_or_rename_file_or_folder(user, res.short_id, 'data/contents/' + file_name_list[2], 'data/contents/new_' + file_name_list[2]) # move the first two files in file_name_list to the new folder move_or_rename_file_or_folder( user, res.short_id, 'data/contents/' + file_name_list[0], 'data/contents/sub_test_dir/' + file_name_list[0]) move_or_rename_file_or_folder( user, res.short_id, 'data/contents/' + file_name_list[1], 'data/contents/sub_test_dir/' + file_name_list[1]) updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertIn('new_' + file_name_list[2], updated_res_file_names, msg="resource does not contain the updated file new_" + file_name_list[2]) self.assertNotIn(file_name_list[2], updated_res_file_names, msg='resource still contains the old file ' + file_name_list[2] + ' after renaming') self.assertIn('sub_test_dir/' + file_name_list[0], updated_res_file_names, msg='resource does not contain ' + file_name_list[0] + ' moved to a folder') self.assertNotIn(file_name_list[0], updated_res_file_names, msg='resource still contains the old ' + file_name_list[0] + 'after moving to a folder') self.assertIn('sub_test_dir/' + file_name_list[1], updated_res_file_names, msg='resource does not contain ' + file_name_list[1] + 'moved to a new folder') self.assertNotIn(file_name_list[1], updated_res_file_names, msg='resource still contains the old ' + file_name_list[1] + ' after moving to a folder') # zip the folder output_zip_fname, size = \ zip_folder(user, res.short_id, 'data/contents/sub_test_dir', 'sub_test_dir.zip', True) self.assertGreater(size, 0, msg='zipped file has a size of 0') # Now resource should contain only two files: new_file3.txt and sub_test_dir.zip # since the folder is zipped into sub_test_dir.zip with the folder deleted self.assertEqual(res.files.all().count(), 2, msg="resource file count didn't match-") # test unzip does not allow override of existing files # add an existing file in the zip to the resource if res.resource_federation_path: fed_test_file1_full_path = '/{zone}/home/{uname}/{fname}'.format( zone=settings.HS_USER_IRODS_ZONE, uname=user.username, fname=file_name_list[0]) # TODO: why isn't this a method of resource? # TODO: Why do we repeat the resource_federation_path? add_resource_files(res.short_id, source_names=[fed_test_file1_full_path], move=False) else: # TODO: Why isn't this a method of resource? add_resource_files(res.short_id, self.test_file_1) # TODO: use ResourceFile.create_folder, which doesn't require data/contents prefix create_folder(res.short_id, 'data/contents/sub_test_dir') # TODO: use ResourceFile.rename, which doesn't require data/contents prefix move_or_rename_file_or_folder( user, res.short_id, 'data/contents/' + file_name_list[0], 'data/contents/sub_test_dir/' + file_name_list[0]) # Now resource should contain three files: file3_new.txt, sub_test_dir.zip, and file1.txt self.assertEqual(res.files.all().count(), 3, msg="resource file count didn't match") with self.assertRaises(SessionException): unzip_file(user, res.short_id, 'data/contents/sub_test_dir.zip', False) # Resource should still contain three files: file3_new.txt, sub_test_dir.zip, and file1.txt file_cnt = res.files.all().count() self.assertEqual(file_cnt, 3, msg="resource file count didn't match - " + str(file_cnt) + " != 3") # test unzipping the file succeeds now after deleting the existing folder # TODO: this causes a multiple delete because the paths are valid now. istorage = res.get_irods_storage() remove_folder(user, res.short_id, 'data/contents/sub_test_dir') # Now resource should contain two files: file3_new.txt and sub_test_dir.zip file_cnt = res.files.all().count() self.assertEqual(file_cnt, 2, msg="resource file count didn't match - " + str(file_cnt) + " != 2") unzip_file(user, res.short_id, 'data/contents/sub_test_dir.zip', True) # Now resource should contain three files: file1.txt, file2.txt, and file3_new.txt self.assertEqual(res.files.all().count(), 3, msg="resource file count didn't match") updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertNotIn( 'sub_test_dir.zip', updated_res_file_names, msg="resource still contains the zip file after unzipping") self.assertIn('sub_test_dir/' + file_name_list[0], updated_res_file_names, msg='resource does not contain unzipped file ' + file_name_list[0]) self.assertIn('sub_test_dir/' + file_name_list[1], updated_res_file_names, msg='resource does not contain unzipped file ' + file_name_list[1]) self.assertIn('new_' + file_name_list[2], updated_res_file_names, msg='resource does not contain unzipped file new_' + file_name_list[2]) # rename a folder move_or_rename_file_or_folder(user, res.short_id, 'data/contents/sub_test_dir', 'data/contents/sub_dir') updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertNotIn('sub_test_dir/' + file_name_list[0], updated_res_file_names, msg='resource still contains ' + file_name_list[0] + ' in the old folder after renaming') self.assertIn('sub_dir/' + file_name_list[0], updated_res_file_names, msg='resource does not contain ' + file_name_list[0] + ' in the new folder after renaming') self.assertNotIn('sub_test_dir/' + file_name_list[1], updated_res_file_names, msg='resource still contains ' + file_name_list[1] + ' in the old folder after renaming') self.assertIn('sub_dir/' + file_name_list[1], updated_res_file_names, msg='resource does not contain ' + file_name_list[1] + ' in the new folder after renaming') # remove a folder # TODO: utilize ResourceFile.remove_folder instead. Takes a short path. remove_folder(user, res.short_id, 'data/contents/sub_dir') # Now resource only contains one file self.assertEqual(res.files.all().count(), 1, msg="resource file count didn't match") updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertEqual(len(updated_res_file_names), 1) self.assertEqual(updated_res_file_names[0], 'new_' + file_name_list[2])
def resource_file_oprs(self): """Test common iRODS file operations. This is a common test utility function to be called by both regular folder operation testing and federated zone folder operation testing. Make sure the calling TestCase object has the following attributes defined before calling this method: self.res: resource that has been created that contains files listed in file_name_list self.user: owner of the resource self.file_name_list: a list of three file names that have been added to the res object self.test_file_1 needs to be present for the calling object for doing regular folder operations without involving federated zone so that the same opened file can be re-added to the resource for testing the case where zipping cannot overwrite existing file """ user = self.user res = self.res file_name_list = self.file_name_list # create a folder, if folder is created successfully, no exception is raised, otherwise, # an iRODS exception will be raised which will be caught by the test runner and mark as # a test failure create_folder(res.short_id, 'data/contents/sub_test_dir') istorage = res.get_irods_storage() res_path = res.file_path store = istorage.listdir(res_path) self.assertIn('sub_test_dir', store[0], msg='resource does not contain created sub-folder') # rename the third file in file_name_list move_or_rename_file_or_folder(user, res.short_id, 'data/contents/' + file_name_list[2], 'data/contents/new_' + file_name_list[2]) # move the first two files in file_name_list to the new folder move_or_rename_file_or_folder(user, res.short_id, 'data/contents/' + file_name_list[0], 'data/contents/sub_test_dir/' + file_name_list[0]) move_or_rename_file_or_folder(user, res.short_id, 'data/contents/' + file_name_list[1], 'data/contents/sub_test_dir/' + file_name_list[1]) updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertIn('new_' + file_name_list[2], updated_res_file_names, msg="resource does not contain the updated file new_" + file_name_list[2]) self.assertNotIn(file_name_list[2], updated_res_file_names, msg='resource still contains the old file ' + file_name_list[2] + ' after renaming') self.assertIn('sub_test_dir/' + file_name_list[0], updated_res_file_names, msg='resource does not contain ' + file_name_list[0] + ' moved to a folder') self.assertNotIn(file_name_list[0], updated_res_file_names, msg='resource still contains the old ' + file_name_list[0] + 'after moving to a folder') self.assertIn('sub_test_dir/' + file_name_list[1], updated_res_file_names, msg='resource does not contain ' + file_name_list[1] + 'moved to a new folder') self.assertNotIn(file_name_list[1], updated_res_file_names, msg='resource still contains the old ' + file_name_list[1] + ' after moving to a folder') # zip the folder output_zip_fname, size = \ zip_folder(user, res.short_id, 'data/contents/sub_test_dir', 'sub_test_dir.zip', True) self.assertGreater(size, 0, msg='zipped file has a size of 0') # Now resource should contain only two files: new_file3.txt and sub_test_dir.zip # since the folder is zipped into sub_test_dir.zip with the folder deleted self.assertEqual(res.files.all().count(), 2, msg="resource file count didn't match-") # test unzip does not allow override of existing files # add an existing file in the zip to the resource if res.resource_federation_path: fed_test_file1_full_path = '/{zone}/home/{uname}/{fname}'.format( zone=settings.HS_USER_IRODS_ZONE, uname=user.username, fname=file_name_list[0]) # TODO: why isn't this a method of resource? # TODO: Why do we repeat the resource_federation_path? add_resource_files(res.short_id, source_names=[fed_test_file1_full_path], move=False) else: # TODO: Why isn't this a method of resource? add_resource_files(res.short_id, self.test_file_1) # TODO: use ResourceFile.create_folder, which doesn't require data/contents prefix create_folder(res.short_id, 'data/contents/sub_test_dir') # TODO: use ResourceFile.rename, which doesn't require data/contents prefix move_or_rename_file_or_folder(user, res.short_id, 'data/contents/' + file_name_list[0], 'data/contents/sub_test_dir/' + file_name_list[0]) # Now resource should contain three files: file3_new.txt, sub_test_dir.zip, and file1.txt self.assertEqual(res.files.all().count(), 3, msg="resource file count didn't match") unzip_file(user, res.short_id, 'data/contents/sub_test_dir.zip', False) # Resource should still contain 5 files: file3_new.txt (2), sub_test_dir.zip, # and file1.txt (2) file_cnt = res.files.all().count() self.assertEqual(file_cnt, 5, msg="resource file count didn't match - " + str(file_cnt) + " != 5") # remove all files except the zippped file remove_folder(user, res.short_id, 'data/contents/sub_test_dir') remove_folder(user, res.short_id, 'data/contents/sub_test_dir-1') # Now resource should contain two files: file3_new.txt sub_test_dir.zip file_cnt = res.files.all().count() self.assertEqual(file_cnt, 2, msg="resource file count didn't match - " + str(file_cnt) + " != 2") unzip_file(user, res.short_id, 'data/contents/sub_test_dir.zip', True) # Now resource should contain three files: file1.txt, file2.txt, and file3_new.txt self.assertEqual(res.files.all().count(), 3, msg="resource file count didn't match") updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertNotIn('sub_test_dir.zip', updated_res_file_names, msg="resource still contains the zip file after unzipping") self.assertIn('sub_test_dir/sub_test_dir/' + file_name_list[0], updated_res_file_names, msg='resource does not contain unzipped file ' + file_name_list[0]) self.assertIn('sub_test_dir/sub_test_dir/' + file_name_list[1], updated_res_file_names, msg='resource does not contain unzipped file ' + file_name_list[1]) self.assertIn('new_' + file_name_list[2], updated_res_file_names, msg='resource does not contain unzipped file new_' + file_name_list[2]) # rename a folder move_or_rename_file_or_folder(user, res.short_id, 'data/contents/sub_test_dir/sub_test_dir', 'data/contents/sub_dir') updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertNotIn('sub_test_dir/sub_test_dir/' + file_name_list[0], updated_res_file_names, msg='resource still contains ' + file_name_list[0] + ' in the old folder after renaming') self.assertIn('sub_dir/' + file_name_list[0], updated_res_file_names, msg='resource does not contain ' + file_name_list[0] + ' in the new folder after renaming') self.assertNotIn('sub_test_dir/sub_test_dir/' + file_name_list[1], updated_res_file_names, msg='resource still contains ' + file_name_list[1] + ' in the old folder after renaming') self.assertIn('sub_dir/' + file_name_list[1], updated_res_file_names, msg='resource does not contain ' + file_name_list[1] + ' in the new folder after renaming') # remove a folder # TODO: utilize ResourceFile.remove_folder instead. Takes a short path. remove_folder(user, res.short_id, 'data/contents/sub_dir') # Now resource only contains one file self.assertEqual(res.files.all().count(), 1, msg="resource file count didn't match") updated_res_file_names = [] for rf in ResourceFile.objects.filter(object_id=res.id): updated_res_file_names.append(rf.short_path) self.assertEqual(len(updated_res_file_names), 1) self.assertEqual(updated_res_file_names[0], 'new_' + file_name_list[2])
def data_store_folder_unzip(request, **kwargs): """ Unzip requested zip file while preserving folder structures in hydroshareZone or any federated zone used for CommonsShare resource backend store. It is invoked by an AJAX call, and returns json object that holds the root path that contains the zipped content if it succeeds, and an empty string if it fails. The AJAX request must be a POST request with input data passed in for res_id, zip_with_rel_path, and remove_original_zip where zip_with_rel_path is the zip file name with relative path under res_id collection to be unzipped, and remove_original_zip has a value of "true" or "false" (default is "true") indicating whether original zip file will be deleted after unzipping. """ res_id = request.POST.get('res_id', kwargs.get('res_id')) if res_id is None: return HttpResponse('Bad request - resource id is not included', status=status.HTTP_400_BAD_REQUEST) res_id = str(res_id).strip() try: resource, _, user = authorize( request, res_id, needed_permission=ACTION_TO_AUTHORIZE.EDIT_RESOURCE) except NotFound: return HttpResponse('Bad request - resource not found', status=status.HTTP_400_BAD_REQUEST) except PermissionDenied: return HttpResponse('Permission denied', status=status.HTTP_401_UNAUTHORIZED) zip_with_rel_path = request.POST.get('zip_with_rel_path', kwargs.get('zip_with_rel_path')) if zip_with_rel_path is None: return HttpResponse('Bad request - zip_with_rel_path is not included', status=status.HTTP_400_BAD_REQUEST) zip_with_rel_path = str(zip_with_rel_path).strip() if not zip_with_rel_path: return HttpResponse('Bad request - zip_with_rel_path cannot be empty', status=status.HTTP_400_BAD_REQUEST) # security checks deny illicit requests if not zip_with_rel_path.startswith('data/contents/'): return HttpResponse( 'Bad request - zip_with_rel_path must start with data/contents/', status=status.HTTP_400_BAD_REQUEST) if zip_with_rel_path.find('/../') >= 0 or zip_with_rel_path.endswith( '/..'): return HttpResponse( 'Bad request - zip_with_rel_path must not contain /../', status=status.HTTP_400_BAD_REQUEST) remove_original = request.POST.get('remove_original_zip', None) bool_remove_original = True if remove_original: remove_original = str(remove_original).strip().lower() if remove_original == 'false': bool_remove_original = False try: unzip_file(user, res_id, zip_with_rel_path, bool_remove_original) except SessionException as ex: specific_msg = "iRODS error resulted in unzip being cancelled. This may be due to " \ "protection from overwriting existing files. Unzip in a different " \ "location (e.g., folder) or move or rename the file being overwritten. " \ "iRODS error follows: " return HttpResponse(specific_msg + ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) # this unzipped_path can be used for POST request input to data_store_structure() # to list the folder structure after unzipping return_object = {'unzipped_path': os.path.dirname(zip_with_rel_path)} return HttpResponse(json.dumps(return_object), content_type="application/json")
def data_store_folder_unzip(request, **kwargs): """ Unzip requested zip file while preserving folder structures in hydroshareZone or any federated zone used for HydroShare resource backend store. It is invoked by an AJAX call, and returns json object that holds the root path that contains the zipped content if it succeeds, and an empty string if it fails. The AJAX request must be a POST request with input data passed in for res_id, zip_with_rel_path, and remove_original_zip where zip_with_rel_path is the zip file name with relative path under res_id collection to be unzipped, and remove_original_zip has a value of "true" or "false" (default is "true") indicating whether original zip file will be deleted after unzipping. """ res_id = request.POST.get('res_id', kwargs.get('res_id')) if res_id is None: return HttpResponse('Bad request - resource id is not included', status=status.HTTP_400_BAD_REQUEST) res_id = str(res_id).strip() try: resource, _, user = authorize( request, res_id, needed_permission=ACTION_TO_AUTHORIZE.EDIT_RESOURCE) except NotFound: return HttpResponse('Bad request - resource not found', status=status.HTTP_400_BAD_REQUEST) except PermissionDenied: return HttpResponse('Permission denied', status=status.HTTP_401_UNAUTHORIZED) zip_with_rel_path = request.POST.get('zip_with_rel_path', kwargs.get('zip_with_rel_path')) try: zip_with_rel_path = _validate_path(zip_with_rel_path, 'zip_with_rel_path') except ValidationError as ex: return HttpResponse(str(ex), status=status.HTTP_400_BAD_REQUEST) overwrite = request.POST.get('overwrite', 'false').lower() == 'true' # False by default auto_aggregate = request.POST.get( 'auto_aggregate', 'true').lower() == 'true' # True by default ingest_metadata = request.POST.get( 'ingest_metadata', 'false').lower() == 'true' # False by default remove_original_zip = request.POST.get('remove_original_zip', 'true').lower() == 'true' if request.is_ajax(): task = unzip_task.apply_async( (user.pk, res_id, zip_with_rel_path, remove_original_zip, overwrite, auto_aggregate, ingest_metadata)) task_id = task.task_id task_dict = get_or_create_task_notification( task_id, name='file unzip', username=request.user.username, payload=resource.get_absolute_url()) return JsonResponse(task_dict) else: try: unzip_file(user, res_id, zip_with_rel_path, remove_original_zip, overwrite, auto_aggregate, ingest_metadata) except SessionException as ex: specific_msg = "iRODS error resulted in unzip being cancelled. This may be due to " \ "protection from overwriting existing files. Unzip in a different " \ "location (e.g., folder) or move or rename the file being overwritten. " \ "iRODS error follows: " return HttpResponse(specific_msg + ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) # this unzipped_path can be used for POST request input to data_store_structure() # to list the folder structure after unzipping return_object = {'unzipped_path': os.path.dirname(zip_with_rel_path)} return HttpResponse(json.dumps(return_object), content_type="application/json")