def data_store_file_or_folder_move_or_rename(request, res_id=None): """ Move or rename a file or folder in hydroshareZone or any federated zone used for HydroShare resource backend store. It is invoked by an AJAX call and returns json object that has the relative path of the target file or folder being moved to if succeeds, and return empty string if fails. The AJAX request must be a POST request with input data passed in for res_id, source_path, and target_path where source_path and target_path are the relative paths for the source and target file or folder under res_id collection/directory. """ res_id = request.POST.get('res_id', 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) src_path = resolve_request(request).get('source_path', None) tgt_path = resolve_request(request).get('target_path', None) if src_path is None or tgt_path is None: return HttpResponse( 'Bad request - src_path or tgt_path is not included', status=status.HTTP_400_BAD_REQUEST) src_path = str(src_path).strip() tgt_path = str(tgt_path).strip() if not src_path or not tgt_path: return HttpResponse( 'Bad request - src_path or tgt_path cannot be empty', status=status.HTTP_400_BAD_REQUEST) try: move_or_rename_file_or_folder(user, res_id, src_path, tgt_path) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'target_rel_path': tgt_path} return HttpResponse(json.dumps(return_object), content_type='application/json')
def data_store_file_or_folder_move_or_rename(request, res_id=None): """ Move or rename a file or folder in hydroshareZone or any federated zone used for HydroShare resource backend store. It is invoked by an AJAX call and returns json object that has the relative path of the target file or folder being moved to if succeeds, and return empty string if fails. The AJAX request must be a POST request with input data passed in for res_id, source_path, and target_path where source_path and target_path are the relative paths (relative to path res_id/data/contents) for the source and target file or folder under res_id collection/directory. """ res_id = request.POST.get('res_id', 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) src_path = resolve_request(request).get('source_path', None) tgt_path = resolve_request(request).get('target_path', None) try: src_path = _validate_path(src_path, 'src_path') tgt_path = _validate_path(tgt_path, 'tgt_path') except ValidationError as ex: return HttpResponse(ex.message, status=status.HTTP_400_BAD_REQUEST) try: move_or_rename_file_or_folder(user, res_id, src_path, tgt_path) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'target_rel_path': tgt_path} return HttpResponse( json.dumps(return_object), content_type='application/json' )
def data_store_rename_file_or_folder(request, pk=None): """ Rename one file or folder in a resource file hierarchy. It is invoked by an AJAX call :param request: a REST request :param pk: the short_id of a resource to modify, from REST URL. This is invoked by an AJAX call in the UI. It returns a json object that has the relative path of the target file or folder that has been renamed. The AJAX request must be a POST request with input data for source_path and target_path, where source_path and target_path are the relative paths for the source and target file or folder. This routine is **specifically** targeted at validating requests from the UI. Thus it is much more limiting than a general purpose REST responder. """ pk = request.POST.get('res_id', pk) if pk is None: return HttpResponse('Bad request - resource id is not included', status=status.HTTP_400_BAD_REQUEST) pk = str(pk).strip() try: resource, _, user = authorize( request, pk, 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) src_path = resolve_request(request).get('source_path', None) tgt_path = resolve_request(request).get('target_path', None) if src_path is None or tgt_path is None: return HttpResponse('Source or target name is not specified', status=status.HTTP_400_BAD_REQUEST) if not src_path or not tgt_path: return HttpResponse('Source or target name is empty', status=status.HTTP_400_BAD_REQUEST) src_path = str(src_path).strip() tgt_path = str(tgt_path).strip() src_folder, src_base = os.path.split(src_path) tgt_folder, tgt_base = os.path.split(tgt_path) if src_folder != tgt_folder: return HttpResponse( 'Rename: Source and target names must be in same folder', status=status.HTTP_400_BAD_REQUEST) if not src_path.startswith('data/contents/'): return HttpResponse( 'Rename: Source path must start with data/contents/', status=status.HTTP_400_BAD_REQUEST) if src_path.find('/../') >= 0 or src_path.endswith('/..'): return HttpResponse('Rename: Source path cannot contain /../', status=status.HTTP_400_BAD_REQUEST) if not tgt_path.startswith('data/contents/'): return HttpResponse( 'Rename: Target path must start with data/contents/', status=status.HTTP_400_BAD_REQUEST) if tgt_path.find('/../') >= 0 or tgt_path.endswith('/..'): return HttpResponse('Rename: Target path cannot contain /../', status=status.HTTP_400_BAD_REQUEST) istorage = resource.get_irods_storage() # protect against stale data botches: source files should exist src_storage_path = os.path.join(resource.root_path, src_path) try: folder, base = ResourceFile.resource_path_is_acceptable( resource, src_storage_path, test_exists=True) except ValidationError: return HttpResponse('Object to be renamed does not exist', status=status.HTTP_400_BAD_REQUEST) if not irods_path_is_directory(istorage, src_storage_path): try: # Django record should exist for each file ResourceFile.get(resource, base, folder=folder) except ResourceFile.DoesNotExist: return HttpResponse('Object to be renamed does not exist', status=status.HTTP_400_BAD_REQUEST) # check that the target doesn't exist tgt_storage_path = os.path.join(resource.root_path, tgt_path) tgt_short_path = tgt_path[len('data/contents/'):] if istorage.exists(tgt_storage_path): return HttpResponse('Desired name is already in use', status=status.HTTP_400_BAD_REQUEST) try: folder, base = ResourceFile.resource_path_is_acceptable( resource, tgt_storage_path, test_exists=False) except ValidationError: return HttpResponse( 'Poorly structured desired name {}'.format(tgt_short_path), status=status.HTTP_400_BAD_REQUEST) try: ResourceFile.get(resource, base, folder=tgt_short_path) return HttpResponse( 'Desired name {} is already in use'.format(tgt_short_path), status=status.HTTP_400_BAD_REQUEST) except ResourceFile.DoesNotExist: pass # correct response try: rename_file_or_folder(user, pk, src_path, tgt_path) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'target_rel_path': tgt_path} return HttpResponse(json.dumps(return_object), content_type='application/json')
def data_store_move_to_folder(request, pk=None): """ Move a list of files and/or folders to another folder in a resource file hierarchy. :param request: a REST request :param pk: the short_id of a resource to modify, from REST URL. It is invoked by an AJAX call and returns a json object that has the relative paths of the target files or folders to which files have been moved. The AJAX request must be a POST request with input data passed in for source_paths and target_path where source_paths and target_path are the relative paths for the source and target file or folder in the res_id file directory. This routine is **specifically** targeted at validating requests from the UI. Thus it is much more limiting than a general purpose REST responder. """ pk = request.POST.get('res_id', pk) if pk is None: return HttpResponse('Bad request - resource id is not included', status=status.HTTP_400_BAD_REQUEST) # whether to treat request as atomic: skip overwrites for valid request atomic = request.POST.get('atomic', 'false') == 'true' # False by default pk = str(pk).strip() try: resource, _, user = authorize( request, pk, 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) tgt_path = resolve_request(request).get('target_path', None) src_paths = resolve_request(request).get('source_paths', None) if src_paths is None or tgt_path is None: return HttpResponse( 'Bad request - src_paths or tgt_path is not included', status=status.HTTP_400_BAD_REQUEST) tgt_path = str(tgt_path).strip() if not tgt_path: return HttpResponse('Target directory not specified', status=status.HTTP_400_BAD_REQUEST) # protect against common hacking attacks if not tgt_path.startswith('data/contents/'): return HttpResponse( 'Target directory path must start with data/contents/', status=status.HTTP_400_BAD_REQUEST) if tgt_path.find('/../') >= 0 or tgt_path.endswith('/..'): return HttpResponse('Bad request - tgt_path cannot contain /../', status=status.HTTP_400_BAD_REQUEST) istorage = resource.get_irods_storage() # strip trailing slashes (if any) tgt_path = tgt_path.rstrip('/') tgt_short_path = tgt_path[len('data/contents/'):] tgt_storage_path = os.path.join(resource.root_path, tgt_path) if not irods_path_is_directory(istorage, tgt_storage_path): return HttpResponse('Target of move is not an existing folder', status=status.HTTP_400_BAD_REQUEST) src_paths = json.loads(src_paths) for i in range(len(src_paths)): src_paths[i] = str(src_paths[i]).strip().rstrip('/') # protect against common hacking attacks for src_path in src_paths: if not src_path.startswith('data/contents/'): return HttpResponse( 'Paths to be moved must start with data/contents/', status=status.HTTP_400_BAD_REQUEST) if src_path.find('/../') >= 0 or src_path.endswith('/..'): return HttpResponse('Paths to be moved cannot contain /../', status=status.HTTP_400_BAD_REQUEST) valid_src_paths = [] skipped_tgt_paths = [] for src_path in src_paths: src_storage_path = os.path.join(resource.root_path, src_path) src_short_path = src_path[len('data/contents/'):] # protect against stale data botches: source files should exist try: folder, file = ResourceFile.resource_path_is_acceptable( resource, src_storage_path, test_exists=True) except ValidationError: return HttpResponse( 'Source file {} does not exist'.format(src_short_path), status=status.HTTP_400_BAD_REQUEST) if not irods_path_is_directory( istorage, src_storage_path): # there is django record try: ResourceFile.get(resource, file, folder=folder) except ResourceFile.DoesNotExist: return HttpResponse( 'Source file {} does not exist'.format(src_short_path), status=status.HTTP_400_BAD_REQUEST) # protect against inadvertent overwrite base = os.path.basename(src_storage_path) tgt_overwrite = os.path.join(tgt_storage_path, base) if not istorage.exists(tgt_overwrite): valid_src_paths.append( src_path) # partly qualified path for operation else: # skip pre-existing objects skipped_tgt_paths.append(os.path.join(tgt_short_path, base)) if skipped_tgt_paths: if atomic: message = 'move would overwrite {}'.format( ', '.join(skipped_tgt_paths)) return HttpResponse(message, status=status.HTTP_400_BAD_REQUEST) # if not atomic, then try to move the files that don't have conflicts # stop immediately on error. try: move_to_folder(user, pk, valid_src_paths, tgt_path) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'target_rel_path': tgt_path} if skipped_tgt_paths: # add information on skipped steps message = '[Warn] skipped move to existing {}'.format( ', '.join(skipped_tgt_paths)) return_object['additional_status'] = message return HttpResponse(json.dumps(return_object), content_type='application/json')
def data_store_folder_zip(request, res_id=None): """ Zip requested files and folders into a zip file 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 created zip file name 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, input_coll_path, output_zip_file_name, and remove_original_after_zip where input_coll_path is the relative sub-collection path under res_id collection to be zipped, output_zip_file_name is the file name only with no path of the generated zip file name, and remove_original_after_zip has a value of "true" or "false" (default is "true") indicating whether original files will be deleted after zipping. """ res_id = request.POST.get('res_id', 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) input_coll_path = resolve_request(request).get('input_coll_path', None) if input_coll_path is None: return HttpResponse('Bad request - input_coll_path is not included', status=status.HTTP_400_BAD_REQUEST) input_coll_path = str(input_coll_path).strip() if not input_coll_path: return HttpResponse('Bad request - input_coll_path cannot be empty', status=status.HTTP_400_BAD_REQUEST) if not input_coll_path.startswith('data/contents/'): return HttpResponse( 'Bad request - input_coll_path must start with data/contents/', status=status.HTTP_400_BAD_REQUEST) if input_coll_path.find('/../') >= 0 or input_coll_path.endswith('/..'): return HttpResponse( 'Bad request - input_coll_path must not contain /../', status=status.HTTP_400_BAD_REQUEST) output_zip_fname = resolve_request(request).get('output_zip_file_name', None) if output_zip_fname is None: return HttpResponse('Bad request - output_zip_fname is not included', status=status.HTTP_400_BAD_REQUEST) output_zip_fname = str(output_zip_fname).strip() if not output_zip_fname: return HttpResponse('Bad request - output_zip_fname cannot be empty', status=status.HTTP_400_BAD_REQUEST) if output_zip_fname.find('/') >= 0: return HttpResponse('Bad request - output_zip_fname cannot contain /', status=status.HTTP_400_BAD_REQUEST) remove_original = resolve_request(request).get('remove_original_after_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: output_zip_fname, size = \ zip_folder(user, res_id, input_coll_path, output_zip_fname, bool_remove_original) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'name': output_zip_fname, 'size': size, 'type': 'zip'} return HttpResponse(json.dumps(return_object), content_type="application/json")
def data_store_rename_file_or_folder(request, pk=None): """ Rename one file or folder in a resource file hierarchy. It is invoked by an AJAX call :param request: a REST request :param pk: the short_id of a resource to modify, from REST URL. This is invoked by an AJAX call in the UI. It returns a json object that has the relative path of the target file or folder that has been renamed. The AJAX request must be a POST request with input data for source_path and target_path, where source_path and target_path are the relative paths (relative to path res_id/data/contents) for the source and target file or folder. This routine is **specifically** targeted at validating requests from the UI. Thus it is much more limiting than a general purpose REST responder. """ pk = request.POST.get('res_id', pk) if pk is None: return HttpResponse('Bad request - resource id is not included', status=status.HTTP_400_BAD_REQUEST) pk = str(pk).strip() try: resource, _, user = authorize(request, pk, 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) src_path = resolve_request(request).get('source_path', None) tgt_path = resolve_request(request).get('target_path', None) try: src_path = _validate_path(src_path, 'src_path') tgt_path = _validate_path(tgt_path, 'tgt_path') except ValidationError as ex: return HttpResponse(ex.message, status=status.HTTP_400_BAD_REQUEST) src_folder, src_base = os.path.split(src_path) tgt_folder, tgt_base = os.path.split(tgt_path) if src_folder != tgt_folder: return HttpResponse('Rename: Source and target names must be in same folder', status=status.HTTP_400_BAD_REQUEST) istorage = resource.get_irods_storage() # protect against stale data botches: source files should exist src_storage_path = os.path.join(resource.root_path, src_path) try: folder, base = ResourceFile.resource_path_is_acceptable(resource, src_storage_path, test_exists=True) except ValidationError: return HttpResponse('Object to be renamed does not exist', status=status.HTTP_400_BAD_REQUEST) if not irods_path_is_directory(istorage, src_storage_path): try: # Django record should exist for each file ResourceFile.get(resource, base, folder=folder) except ResourceFile.DoesNotExist: return HttpResponse('Object to be renamed does not exist', status=status.HTTP_400_BAD_REQUEST) # check that the target doesn't exist tgt_storage_path = os.path.join(resource.root_path, tgt_path) tgt_short_path = tgt_path[len('data/contents/'):] if istorage.exists(tgt_storage_path): return HttpResponse('Desired name is already in use', status=status.HTTP_400_BAD_REQUEST) try: folder, base = ResourceFile.resource_path_is_acceptable(resource, tgt_storage_path, test_exists=False) except ValidationError: return HttpResponse('Poorly structured desired name {}' .format(tgt_short_path), status=status.HTTP_400_BAD_REQUEST) try: ResourceFile.get(resource, base, folder=tgt_short_path) return HttpResponse('Desired name {} is already in use' .format(tgt_short_path), status=status.HTTP_400_BAD_REQUEST) except ResourceFile.DoesNotExist: pass # correct response try: rename_file_or_folder(user, pk, src_path, tgt_path) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'target_rel_path': tgt_path} return HttpResponse( json.dumps(return_object), content_type='application/json' )
def data_store_move_to_folder(request, pk=None): """ Move a list of files and/or folders to another folder in a resource file hierarchy. :param request: a REST request :param pk: the short_id of a resource to modify, from REST URL. It is invoked by an AJAX call and returns a json object that has the relative paths of the target files or folders to which files have been moved. The AJAX request must be a POST request with input data passed in for source_paths and target_path where source_paths and target_path are the relative paths (relative to path res_id/data/contents) for the source and target file or folder in the res_id file directory. This routine is **specifically** targeted at validating requests from the UI. Thus it is much more limiting than a general purpose REST responder. """ pk = request.POST.get('res_id', pk) if pk is None: return HttpResponse('Bad request - resource id is not included', status=status.HTTP_400_BAD_REQUEST) # whether to treat request as atomic: skip overwrites for valid request atomic = request.POST.get('atomic', 'false') == 'true' # False by default pk = str(pk).strip() try: resource, _, user = authorize(request, pk, 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) tgt_path = resolve_request(request).get('target_path', None) src_paths = resolve_request(request).get('source_paths', None) try: tgt_path = _validate_path(tgt_path, 'tgt_path', check_path_empty=False) except ValidationError as ex: return HttpResponse(ex.message, status=status.HTTP_400_BAD_REQUEST) istorage = resource.get_irods_storage() tgt_short_path = tgt_path[len('data/contents/'):] tgt_storage_path = os.path.join(resource.root_path, tgt_path) if not irods_path_is_directory(istorage, tgt_storage_path): return HttpResponse('Target of move is not an existing folder', status=status.HTTP_400_BAD_REQUEST) src_paths = json.loads(src_paths) # protect against common hacking attacks for index, src_path in enumerate(src_paths): try: src_paths[index] = _validate_path(src_path, 'src_paths') except ValidationError as ex: return HttpResponse(ex.message, status=status.HTTP_400_BAD_REQUEST) valid_src_paths = [] skipped_tgt_paths = [] for src_path in src_paths: src_storage_path = os.path.join(resource.root_path, src_path) src_short_path = src_path[len('data/contents/'):] # protect against stale data botches: source files should exist try: folder, file = ResourceFile.resource_path_is_acceptable(resource, src_storage_path, test_exists=True) except ValidationError: return HttpResponse('Source file {} does not exist'.format(src_short_path), status=status.HTTP_400_BAD_REQUEST) if not irods_path_is_directory(istorage, src_storage_path): # there is django record try: ResourceFile.get(resource, file, folder=folder) except ResourceFile.DoesNotExist: return HttpResponse('Source file {} does not exist'.format(src_short_path), status=status.HTTP_400_BAD_REQUEST) # protect against inadvertent overwrite base = os.path.basename(src_storage_path) tgt_overwrite = os.path.join(tgt_storage_path, base) if not istorage.exists(tgt_overwrite): valid_src_paths.append(src_path) # partly qualified path for operation else: # skip pre-existing objects skipped_tgt_paths.append(os.path.join(tgt_short_path, base)) if skipped_tgt_paths: if atomic: message = 'move would overwrite {}'.format(', '.join(skipped_tgt_paths)) return HttpResponse(message, status=status.HTTP_400_BAD_REQUEST) # if not atomic, then try to move the files that don't have conflicts # stop immediately on error. try: move_to_folder(user, pk, valid_src_paths, tgt_path) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'target_rel_path': tgt_path} if skipped_tgt_paths: # add information on skipped steps message = '[Warn] skipped move to existing {}'.format(', '.join(skipped_tgt_paths)) return_object['additional_status'] = message return HttpResponse( json.dumps(return_object), content_type='application/json' )
def data_store_folder_zip(request, res_id=None): """ Zip requested files and folders into a zip file 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 created zip file name 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, input_coll_path, output_zip_file_name, and remove_original_after_zip where input_coll_path is the relative path under res_id/data/contents to be zipped, output_zip_file_name is the file name only with no path of the generated zip file name, and remove_original_after_zip has a value of "true" or "false" (default is "true") indicating whether original files will be deleted after zipping. """ res_id = request.POST.get('res_id', 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) input_coll_path = resolve_request(request).get('input_coll_path', None) try: input_coll_path = _validate_path(input_coll_path, 'input_coll_path') except ValidationError as ex: return HttpResponse(ex.message, status=status.HTTP_400_BAD_REQUEST) output_zip_fname = resolve_request(request).get('output_zip_file_name', None) if output_zip_fname is None: return HttpResponse('Bad request - output_zip_fname is not included', status=status.HTTP_400_BAD_REQUEST) output_zip_fname = str(output_zip_fname).strip() if not output_zip_fname: return HttpResponse('Bad request - output_zip_fname cannot be empty', status=status.HTTP_400_BAD_REQUEST) if output_zip_fname.find('/') >= 0: return HttpResponse('Bad request - output_zip_fname cannot contain /', status=status.HTTP_400_BAD_REQUEST) remove_original = resolve_request(request).get('remove_original_after_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: output_zip_fname, size = \ zip_folder(user, res_id, input_coll_path, output_zip_fname, bool_remove_original) except SessionException as ex: return HttpResponse(ex.stderr, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except DRF_ValidationError as ex: return HttpResponse(ex.detail, status=status.HTTP_400_BAD_REQUEST) return_object = {'name': output_zip_fname, 'size': size, 'type': 'zip'} return HttpResponse( json.dumps(return_object), content_type="application/json" )