Esempio n. 1
0
def aip_file_download(request, uuid):
    es_client = es.get_client()

    # get AIP file properties
    aipfile = es.get_aipfile_data(es_client, uuid, fields="filePath,FILEUUID,AIPUUID")

    # get file's AIP's properties
    sipuuid = aipfile["_source"]["AIPUUID"]
    aip = es.get_aip_data(
        es_client, sipuuid, fields="uuid,name,filePath,size,origin,created"
    )
    aip_filepath = aip["_source"]["filePath"]

    # work out path components
    aip_archive_filename = os.path.basename(aip_filepath)

    # splittext doesn't deal with double extensions, so special-case .tar.bz2
    if aip_archive_filename.endswith(".tar.bz2"):
        subdir = aip_archive_filename[:-8]
    else:
        subdir = os.path.splitext(aip_archive_filename)[0]

    file_relative_path = os.path.join(subdir, "data", aipfile["_source"]["filePath"])

    redirect_url = storage_service.extract_file_url(
        aip["_source"]["uuid"], file_relative_path
    )
    return helpers.stream_file_from_storage_service(
        redirect_url, "Storage service returned {}; check logs?"
    )
Esempio n. 2
0
def aip_file_download(request, uuid):
    # get file basename
    file = models.File.objects.get(uuid=uuid)
    file_basename = os.path.basename(file.currentlocation)

    # get file's AIP's properties
    sipuuid = helpers.get_file_sip_uuid(uuid)
    es_client = elasticSearchFunctions.get_client()
    aip = elasticSearchFunctions.get_aip_data(es_client, sipuuid, fields='uuid,name,filePath,size,origin,created')
    aip_filepath = aip['fields']['filePath'][0]

    # work out path components
    aip_archive_filename = os.path.basename(aip_filepath)

    # splittext doesn't deal with double extensions, so special-case .tar.bz2
    if aip_archive_filename.endswith('.tar.bz2'):
        subdir = aip_archive_filename[:-8]
    else:
        subdir = os.path.splitext(aip_archive_filename)[0]

    # Strip %Directory% from the path
    path_to_file_within_aip_data_dir = os.path.dirname(file.currentlocation.replace('%transferDirectory%', '').replace('%SIPDirectory%', ''))

    file_relative_path = os.path.join(
        subdir,
        'data',
        path_to_file_within_aip_data_dir,
        file_basename
    )

    redirect_url = storage_service.extract_file_url(aip['fields']['uuid'][0], file_relative_path)
    return helpers.stream_file_from_storage_service(redirect_url, 'Storage service returned {}; check logs?')
Esempio n. 3
0
def search_augment_file_results(es_client, raw_results):
    modifiedResults = []

    for item in raw_results['hits']['hits']:
        if 'fields' not in item:
            continue

        clone = {k: v[0] for k, v in item['fields'].copy().items()}

        # try to find AIP details in database
        try:
            # get AIP data from ElasticSearch
            aip = elasticSearchFunctions.get_aip_data(es_client, clone['AIPUUID'], fields='uuid,name,filePath,size,origin,created,encrypted')

            # augment result data
            clone['sipname'] = aip['fields']['name'][0]
            clone['fileuuid'] = clone['FILEUUID']
            clone['href'] = aip['fields']['filePath'][0].replace(AIPSTOREPATH + '/', "AIPsStore/")

        except:
            aip = None
            clone['sipname'] = False

        clone['filename'] = os.path.basename(clone['filePath'])
        clone['document_id'] = item['_id']
        clone['document_id_no_hyphens'] = item['_id'].replace('-', '____')

        modifiedResults.append(clone)

    return modifiedResults
Esempio n. 4
0
def search_augment_file_results(es_client, raw_results):
    modifiedResults = []

    for item in raw_results["hits"]["hits"]:
        if "_source" not in item:
            continue

        clone = item["_source"].copy()

        # try to find AIP details in database
        try:
            # get AIP data from ElasticSearch
            aip = elasticSearchFunctions.get_aip_data(
                es_client,
                clone["AIPUUID"],
                fields="uuid,name,filePath,size,origin,created,encrypted",
            )

            # augment result data
            clone["sipname"] = aip["_source"]["name"]
            clone["fileuuid"] = clone["FILEUUID"]
            clone["href"] = aip["_source"]["filePath"].replace(
                AIPSTOREPATH + "/", "AIPsStore/")

        except:
            aip = None
            clone["sipname"] = False

        clone["filename"] = os.path.basename(clone["filePath"])
        clone["document_id"] = item["_id"]
        clone["document_id_no_hyphens"] = item["_id"].replace("-", "____")

        modifiedResults.append(clone)

    return modifiedResults
Esempio n. 5
0
def aip_mets_file_download(request, uuid):
    """Download an individual AIP METS file."""
    es_client = es.get_client()
    try:
        aip = es.get_aip_data(es_client, uuid, fields="name")
    except IndexError:
        # TODO: 404 settings for the project do not display this to the user (only DEBUG).
        raise Http404(
            _("The AIP package containing the requested METS cannot be found")
        )
    transfer_name = aip["_source"]["name"]
    return helpers.stream_mets_from_storage_service(
        transfer_name=transfer_name, sip_uuid=uuid
    )
Esempio n. 6
0
def search_augment_file_results(es_client, raw_results):
    """Augment file results.

    :param es_client: Elasticsearch client.
    :param raw_results: Raw results returned from ES.

    :return: Augmented and formatted results.
    """
    modifiedResults = []

    for item in raw_results["hits"]["hits"]:
        if "_source" not in item:
            continue

        clone = item["_source"].copy()

        try:
            aip = es.get_aip_data(
                es_client,
                clone["AIPUUID"],
                fields="uuid,name,filePath,size,origin,created,encrypted",
            )

            clone["sipname"] = aip["_source"]["name"]
            clone["fileuuid"] = clone["FILEUUID"]
            clone["href"] = aip["_source"]["filePath"].replace(
                AIPSTOREPATH + "/", "AIPsStore/"
            )

        except ElasticsearchException:
            aip = None
            clone["sipname"] = False

        clone["status"] = AIP_STATUS_DESCRIPTIONS[
            clone.get("status", es.STATUS_UPLOADED)
        ]
        clone["filename"] = os.path.basename(clone["filePath"])
        clone["document_id"] = item["_id"]
        clone["document_id_no_hyphens"] = item["_id"].replace("-", "____")

        modifiedResults.append(clone)

    return modifiedResults
Esempio n. 7
0
def view_aip(request, uuid):
    es_client = es.get_client()
    try:
        es_aip_doc = es.get_aip_data(
            es_client, uuid, fields="name,size,created,status,filePath,encrypted"
        )
    except IndexError:
        raise Http404

    source = es_aip_doc["_source"]
    name = source.get("name")
    active_tab = None

    form_upload = forms.UploadMetadataOnlyAtomForm(prefix="upload")
    form_reingest = forms.ReingestAIPForm(prefix="reingest")
    form_delete = forms.DeleteAIPForm(prefix="delete", uuid=uuid)

    # Process metadata-only DIP upload form
    if request.POST and "submit-upload-form" in request.POST:
        form_upload = forms.UploadMetadataOnlyAtomForm(request.POST, prefix="upload")
        active_tab = "upload"
        if form_upload.is_valid():
            try:
                file_slug = upload_dip_metadata_to_atom(
                    name, uuid, form_upload.cleaned_data["slug"]
                )
            except AtomMetadataUploadError:
                messages.error(
                    request,
                    _(
                        "Metadata-only DIP upload failed, check the logs for more details"
                    ),
                )
                logger.error(
                    "Unexepected error during metadata-only DIP upload (UUID: %s)",
                    uuid,
                    exc_info=True,
                )
            else:
                messages.success(
                    request,
                    _(
                        "Metadata-only DIP upload has been completed successfully. New resource has slug: %(slug)s"
                    )
                    % {"slug": file_slug},
                )
            form_upload = forms.UploadMetadataOnlyAtomForm(
                prefix="upload"
            )  # Reset form

    # Process reingest form
    if request.POST and "submit-reingest-form" in request.POST:
        form_reingest = forms.ReingestAIPForm(request.POST, prefix="reingest")
        active_tab = "reingest"
        if form_reingest.is_valid():
            response = storage_service.request_reingest(
                uuid,
                form_reingest.cleaned_data["reingest_type"],
                form_reingest.cleaned_data["processing_config"],
            )
            error = response.get("error", True)
            message = response.get("message", "An unknown error occurred.")
            if error:
                messages.error(
                    request,
                    _("Error re-ingesting package: %(message)s") % {"message": message},
                )
            else:
                messages.success(request, message)
            return redirect("archival_storage:archival_storage_index")

    # Process delete form
    if request.POST and "submit-delete-form" in request.POST:
        form_delete = forms.DeleteAIPForm(request.POST, prefix="delete", uuid=uuid)
        active_tab = "delete"
        if form_delete.is_valid():
            response = storage_service.request_file_deletion(
                uuid,
                request.user.id,
                request.user.email,
                form_delete.cleaned_data["reason"],
            )
            messages.info(request, response["message"])
            es_client = es.get_client()
            es.mark_aip_deletion_requested(es_client, uuid)
            return redirect("archival_storage:archival_storage_index")

    context = {
        "uuid": uuid,
        "name": name,
        "created": source.get("created"),
        "status": AIP_STATUS_DESCRIPTIONS[source.get("status", es.STATUS_UPLOADED)],
        "encrypted": source.get("encrypted", False),
        "size": "{0:.2f} MB".format(source.get("size", 0)),
        "location_basename": os.path.basename(source.get("filePath")),
        "active_tab": active_tab,
        "forms": {
            "upload": form_upload,
            "reingest": form_reingest,
            "delete": form_delete,
        },
    }

    return render(request, "archival_storage/view.html", context)
Esempio n. 8
0
def view_aip(request, uuid):
    es_client = elasticSearchFunctions.get_client()
    try:
        es_aip_doc = elasticSearchFunctions.get_aip_data(es_client, uuid, fields='name,size,created,status,filePath,encrypted')
    except IndexError:
        raise Http404

    name = _get_es_field(es_aip_doc['fields'], 'name')
    active_tab = None

    form_upload = forms.UploadMetadataOnlyAtomForm(prefix='upload')
    form_reingest = forms.ReingestAIPForm(prefix='reingest')
    form_delete = forms.DeleteAIPForm(prefix='delete', uuid=uuid)

    # Process metadata-only DIP upload form
    if request.POST and 'submit-upload-form' in request.POST:
        form_upload = forms.UploadMetadataOnlyAtomForm(request.POST, prefix='upload')
        active_tab = 'upload'
        if form_upload.is_valid():
            try:
                file_slug = upload_dip_metadata_to_atom(name, uuid, form_upload.cleaned_data['slug'])
            except AtomMetadataUploadError:
                messages.error(request, _('Metadata-only DIP upload failed, check the logs for more details'))
                logger.error('Unexepected error during metadata-only DIP upload (UUID: %s)', uuid, exc_info=True)
            else:
                messages.success(request, _('Metadata-only DIP upload has been completed successfully. New resource has slug: %(slug)s') % {'slug': file_slug})
            form_upload = forms.UploadMetadataOnlyAtomForm(prefix='upload')  # Reset form

    # Process reingest form
    if request.POST and 'submit-reingest-form' in request.POST:
        form_reingest = forms.ReingestAIPForm(request.POST, prefix='reingest')
        active_tab = 'reingest'
        if form_reingest.is_valid():
            response = storage_service.request_reingest(uuid, form_reingest.cleaned_data['reingest_type'], form_reingest.cleaned_data['processing_config'])
            error = response.get('error', True)
            message = response.get('message', 'An unknown error occurred.')
            if error:
                messages.error(request, _('Error re-ingesting package: %(message)s') % {'message': message})
            else:
                messages.success(request, message)
            return redirect('archival_storage_index')

    # Process delete form
    if request.POST and 'submit-delete-form' in request.POST:
        form_delete = forms.DeleteAIPForm(request.POST, prefix='delete', uuid=uuid)
        active_tab = 'delete'
        if form_delete.is_valid():
            response = storage_service.request_file_deletion(uuid, request.user.id, request.user.email, form_delete.cleaned_data['reason'])
            messages.info(request, response['message'])
            es_client = elasticSearchFunctions.get_client()
            elasticSearchFunctions.mark_aip_deletion_requested(es_client, uuid)
            return redirect('archival_storage_index')

    context = {
        'uuid': uuid,
        'name': name,
        'created': _get_es_field(es_aip_doc['fields'], 'created'),
        'status': AIP_STATUS_DESCRIPTIONS[_get_es_field(es_aip_doc['fields'], 'status', 'UPLOADED')],
        'encrypted': _get_es_field(es_aip_doc['fields'], 'encrypted', False),
        'size': '{0:.2f} MB'.format(_get_es_field(es_aip_doc['fields'], 'size', 0)),
        'location_basename': os.path.basename(_get_es_field(es_aip_doc['fields'], 'filePath')),
        'active_tab': active_tab,
        'forms': {
            'upload': form_upload,
            'reingest': form_reingest,
            'delete': form_delete,
        },
    }

    return render(request, 'archival_storage/view.html', context)