Esempio n. 1
0
    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
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
    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
                            })