def get(self, request, ticket_number): """ Get the resource's download contents. Parameters ---------- ticket_number: str The ticket number of the download being prepared. Returns ------- 200: OK Returns the zip of resources to be downloaded. 400: Bad Request { "error": "'eaasi_token' not found as query parameter." } 401: Unauthorized { "PresQT Error: Header 'eaasi_token' does not match the 'eaasi_token' for this server process." } 404: Not Found { "message": "File unavailable." } """ try: token = request.query_params['eaasi_token'] except MultiValueDictKeyError: return Response( data={'error': "'eaasi_token' not found as query parameter."}, status=status.HTTP_400_BAD_REQUEST) # Perform token validation. Read data from the process_info file. try: data = get_process_info_data('downloads', ticket_number) process_token_validation(token, data, 'eaasi_token') except PresQTValidationError as e: return Response(data={'error': e.data}, status=e.status_code) # Return the file to download if it has finished. if data['status'] == 'finished': # Path to the file to be downloaded zip_name = data['zip_name'] zip_file_path = os.path.join('mediafiles', 'downloads', ticket_number, zip_name) response = HttpResponse(open(zip_file_path, 'rb'), content_type='application/zip') response['Content-Disposition'] = 'attachment; filename={}'.format( zip_name) else: response = Response(data={'message': 'File unavailable.'}, status=status.HTTP_404_NOT_FOUND) return response
def get(self, request, ticket_number): """ Check in on the resource's transfer process state. Parameters ---------- ticket_number : str The ticket number of the transfer being prepared. Returns ------- 200: OK """ # Perform token validation. Read data from the process_info file. try: destination_token = get_destination_token(request) source_token = get_source_token(request) process_data = get_process_info_data('transfers', ticket_number) process_token_validation(hash_tokens(destination_token), process_data, 'presqt-destination-token') process_token_validation(hash_tokens(source_token), process_data, 'presqt-source-token') except PresQTValidationError as e: return Response(data={'error': e.data}, status=e.status_code) transfer_status = process_data['status'] data = {'status_code': process_data['status_code'], 'message': process_data['message']} if transfer_status == 'finished': http_status = status.HTTP_200_OK data['failed_fixity'] = process_data['failed_fixity'] data['resources_ignored'] = process_data['resources_ignored'] data['resources_updated'] = process_data['resources_updated'] else: if transfer_status == 'in_progress': http_status = status.HTTP_202_ACCEPTED else: http_status = status.HTTP_500_INTERNAL_SERVER_ERROR return Response(status=http_status, data=data)
def patch(self, request, ticket_number): """ Cancel the resource upload process on the server. Update the process_info.json file appropriately. Parameters ---------- ticket_number : str The ticket number of the upload being prepared. Returns ------- 200: OK { "status_code": "499", "message": "Upload was cancelled by the user" } 400: Bad Request { "error": "'presqt-destination-token' missing in the request headers." } 401: Unauthorized { "error": "Header 'presqt-destination-token' does not match the 'presqt-destination-token' for this server process." } 404: Not Found { "error": "Invalid ticket number, '1234'." } 406: Not Acceptable { "status_code": "200", "message": "Upload Successful" } """ # Perform token validation. Read data from the process_info file. try: token = get_destination_token(request) data = get_process_info_data('uploads', ticket_number) process_token_validation(hash_tokens(token), data, 'presqt-destination-token') except PresQTValidationError as e: return Response(data={'error': e.data}, status=e.status_code) # Wait until the spawned off process has started to cancel the upload while data['function_process_id'] is None: try: data = get_process_info_data('uploads', ticket_number) except json.decoder.JSONDecodeError: # Pass while the process_info file is being written to pass # If upload is still in progress then cancel the subprocess if data['status'] == 'in_progress': for process in multiprocessing.active_children(): if process.pid == data['function_process_id']: process.kill() process.join() data['status'] = 'failed' data['message'] = 'Upload was cancelled by the user' data['status_code'] = '499' data['expiration'] = str(timezone.now() + relativedelta(hours=1)) process_info_path = 'mediafiles/uploads/{}/process_info.json'.format( ticket_number) write_file(process_info_path, data, True) return Response(data={ 'status_code': data['status_code'], 'message': data['message'] }, status=status.HTTP_200_OK) # If upload is finished then don't attempt to cancel subprocess else: return Response(data={ 'status_code': data['status_code'], 'message': data['message'] }, status=status.HTTP_406_NOT_ACCEPTABLE)
def get(self, request, ticket_number): """ Check in on the resource's upload process state. Parameters ---------- ticket_number : str The ticket number of the upload being prepared. Returns ------- 200: OK { "status_code": "200", "message": "Upload successful", "failed_fixity": [], "resources_ignored": [], "resources_updated": [] } 202: Accepted { "status_code": null, "message": "Upload is being processed on the server" } 400: Bad Request { "error": "PresQT Error: 'presqt-destination-token' missing in the request headers." } 401: Unauthorized { "error": "PresQT Error: Header 'presqt-destination-token' does not match the 'presqt-destination-token' for this server process." } 404: Not Found { "error": "PresQT Error: Invalid ticket number, '1234'." } 500: Internal Server Error { "status_code": "404", "message": "Resource with id 'bad_id' not found for this user." } """ # Perform token validation. Read data from the process_info file. try: token = get_destination_token(request) process_data = get_process_info_data('uploads', ticket_number) process_token_validation(hash_tokens(token), process_data, 'presqt-destination-token') except PresQTValidationError as e: return Response(data={'error': e.data}, status=e.status_code) upload_status = process_data['status'] data = { 'status_code': process_data['status_code'], 'message': process_data['message'] } if upload_status == 'finished': http_status = status.HTTP_200_OK data['failed_fixity'] = process_data['failed_fixity'] data['resources_ignored'] = process_data['resources_ignored'] data['resources_updated'] = process_data['resources_updated'] else: if upload_status == 'in_progress': http_status = status.HTTP_202_ACCEPTED else: http_status = status.HTTP_500_INTERNAL_SERVER_ERROR return Response(status=http_status, data=data)
def get(self, request, ticket_number, response_format=None): """ Check in on the resource's download process state. Parameters ---------- ticket_number : str The ticket number of the download being prepared. response_format: str The type of response to return. Either json or zip Returns ------- 200: OK Returns the zip of resources to be downloaded. or { "status_code": "200", "message": "Download successful but with fixity errors.", "failed_fixity": ["/Character Sheet - Alternative - Print Version.pdf"] } 202: Accepted { "status_code": null, "message": "Download is being processed on the server" } 400: Bad Request { "error": "PresQT Error: 'presqt-source-token' missing in the request headers." } or { "error": "PresQT Error: 'csv' is not a valid format for this endpoint." } 401: Unauthorized { "error": "PresQT Error: Header 'presqt-source-token' does not match the 'presqt-source-token' for this server process." } 404: Not Found { "error": "PresQT Error: Invalid ticket number, '1234'." } 500: Internal Server Error { "status_code": "404", "message": "Resource with id 'bad_id' not found for this user." } """ # Perform token validation. Read data from the process_info file. try: token = get_source_token(request) data = get_process_info_data('downloads', ticket_number) process_token_validation(hash_tokens(token), data, 'presqt-source-token') except PresQTValidationError as e: return Response(data={'error': e.data}, status=e.status_code) # Verify that the only acceptable response format was provided if response_format and response_format not in ['json', 'zip']: return Response(data={ 'error': 'PresQT Error: {} is not a valid format for this endpoint.'. format(response_format) }, status=status.HTTP_400_BAD_REQUEST) download_status = data['status'] message = data['message'] status_code = data['status_code'] # Return the file to download if it has finished. if download_status == 'finished': if response_format == 'zip': # Path to the file to be downloaded zip_name = data['zip_name'] zip_file_path = os.path.join('mediafiles', 'downloads', ticket_number, zip_name) response = HttpResponse(open(zip_file_path, 'rb'), content_type='application/zip') response[ 'Content-Disposition'] = 'attachment; filename={}'.format( zip_name) else: response = Response(data={ 'status_code': status_code, 'message': message, 'zip_name': data['zip_name'], 'failed_fixity': data['failed_fixity'] }, status=status.HTTP_200_OK) return response else: if download_status == 'in_progress': http_status = status.HTTP_202_ACCEPTED else: http_status = status.HTTP_500_INTERNAL_SERVER_ERROR return Response(status=http_status, data={ 'status_code': status_code, 'message': message })