예제 #1
0
def service_add_archive(request):
    """
    Add a new Archive

    :parameters:

        * **archive:** string, a code of the archive, required
        * **institution:** string - code of the institution, required
        * **archive_description:** string,
        * **country_code:** string
        * **institution_description:** string
        * **user:** optional, a string.

    :returns: a JSON object with the id and url.

    archive and institution taken together should be unique.

    see :ref:`TestArchive.test_add`
    """
    archive = Archive()
    for k, v in request.validated.items():
        setattr(archive, k, v)

    request.db.add(archive)
    request.db.flush()
    request._dbentity['archive'] = archive
    user = get_user(request)
    log_events(request.db, user, [{
        'object_id': request._dbentity['archive'].id,
        'object_type': 'archive',
        'message': 'create'
    }])

    return archive.to_dict(request)
예제 #2
0
def delete_archive(request):
    """
    Delete this archive

    An archive can only be deleted if it is not references by any scans, and it is not referenced in any EAD file.

    see :ref:`TestArchive.test_delete`
    """
    user = get_user(request)
    log_events(request.db, user, [{
        'object_id': request._dbentity['archive'].id,
        'object_type': 'archive',
        'message': 'delete'
    }])
    archive = request._dbentity['archive']
    request.db.delete(archive)
    return {'success': True}
예제 #3
0
def update_archive(request):
    """
    Update an Archive

    parameters:
        see add_archive.

    :returns:
        a JSON object representing the updated archive

    see :ref:`TestArchive.test_update`
    """
    archive = request._dbentity['archive']

    # if identifying properties get changed, we raise an error
    is_dirty = filter(None, [
        getattr(archive, attr) != request.validated[attr]
        for attr in ARCHIVE_IDENTIFIERS if request.validated[attr]
    ])
    if is_dirty:
        if not has_no_eads(request):
            msg = 'You cannot change the attributes %s of this archive, because it has EAD files connected' % ', '.join(
                ['"%s"' % x for x in ARCHIVE_IDENTIFIERS])
            request.errors.add('data', ERRORS.archive_has_eads.name, msg)
            return archive.to_dict(request)
        elif not has_no_scans(request):
            msg = 'You cannot change the attributes %s of this archive, because it has scans connected' % ', '.join(
                ['"%s"' % x for x in ARCHIVE_IDENTIFIERS])
            request.errors.add('data', ERRORS.archive_has_scans.name, msg)
            return archive.to_dict(request)

    for k, v in request.validated.items():
        setattr(archive, k, v)
    user = get_user(request)
    log_events(request.db, user, [{
        'object_id': archive.id,
        'object_type': 'archive',
        'message': 'update'
    }])
    return archive.to_dict(request)
예제 #4
0
def delete_ead_file(request):
    """Delete this file

    see :ref:`TestEad.test_delete`
    """
    user = get_user(request)
    log_events(request.db, user, [{
        'object_id': request._dbentity['ead'].name,
        'object_type': 'ead',
        'message': 'delete'
    }])
    ead = request._dbentity['ead']
    delete_file(ead.get_file_path())
    request.db.delete(ead)
    request.solr_ead.delete_by_key(ead.name)
    request.solr_eadcomponent.delete_by_query('ead_id:' + ead.name)
    #
    # get the archivefiles belonging to this ead
    documents = request.solr_archivefile.search(q='ead_ids:' + ead.name).documents

    # some archivefiles will need to be udpated, others deleted
    documents_to_update = []
    documents_to_delete = []
    for document in documents:
        if len(document['ead_ids']) > 1 or document['number_of_scans'] > 0:
            document['ead_ids'].remove(ead.name)

            # we need to manually set the sort_field, as this is not a stored field
            document['sort_field'] = sort_field(archive_id=document['archive_id'], archiveFile=document['archiveFile'])
            documents_to_update.append(document)
        else:
            documents_to_delete.append(document)

    request.solr_archivefile.update(documents_to_update)
    ead_id = ead.name
    for document in documents:
        pagebrowser.update.delete_book(request, ead_id=ead_id, archivefile_id=document['archivefile_id'])
    return {'success': True}
예제 #5
0
def update_ead_file(request):
    """
    Update an EAD file

    parameters:

        * **file:**
            the XML file to
        * **user:**
             the name of a user - optional, will be used for logging info
        %(PARAM_STATUS)s

    returns: JSON object representing the EAD file

    see :ref:`TestEad.test_ead_update`
    """
    eadfile=request._dbentity['ead']
    ead_id=eadfile.name

    path=eadfile.get_file_path()
    if 'raw_file' in request.validated:
        store_file(path, request.validated['raw_file'])
    if 'status' in request.POST:
        eadfile.status=request.validated['status']
    user=get_user(request)
    if 'raw_file' in request.validated or eadfile in request.db.dirty:
        eadfile.last_modified=now()
        log_events(request.db, user, [{
            'object_id': ead_id,
            'object_type': 'ead',
            'message': 'update'
        }])
    request.solr_ead.update([eadfile.get_solr_data()])
    request.solr.commit()  # we need to commit before we index the archivefile

    request.solr_eadcomponent.delete_by_query('ead_id:' + ead_id)
    components = eadfile.extract_component_dicts()
    request.solr_eadcomponent.update(components)
    request.solr.commit()

    # archivefiles that are already indexed
    indexed_archivefiles = request.solr_archivefile.search(q='ead_ids:' + eadfile.name).documents
    # components of this ead file that are to be indexed as archivefiles
    to_index_archivefiles = [cast_component_as_archivefile(x).get_solr_data(request) for x in components if x['is_archiveFile']]
    to_index_archivefile_ids = [x['archivefile_id'] for x in to_index_archivefiles]
    to_delete_archivefiles = []

    for x in indexed_archivefiles:
        # delete all archivefiles that have no scans available, and are not in this ead file (anymore)
        if x['number_of_scans'] == 0 and x['archivefile_id'] not in to_index_archivefile_ids:
            request.solr_archivefile.delete_by_key(x['id'])
            to_delete_archivefiles.append(x)

    db_records = get_archivefiles(request, archive_id=x['archive_id'])
    db_records = {db_record.id: db_record for db_record in db_records}
    for document in to_index_archivefiles:
        if document['archivefile_id'] in db_records:
            db_record = db_records[document['archivefile_id']]
            if document['status'] != db_record.status:
                document['status'] = db_record.status

    request.solr_archivefile.update(to_index_archivefiles)

    # commit, and ping the pagebrowser
    for x in to_delete_archivefiles:
        pagebrowser.update.delete_book(request, ead_id=ead_id, archivefile_id=x['archivefile_id'])
    for document in to_index_archivefiles:
        if document['archivefile_id'] in db_records:
            if document['status'] == STATUS_PUBLISHED:
                pagebrowser.update.refresh_book(request, ead_id=ead_id, archivefile_id=document['archivefile_id'])
            else:
                pagebrowser.update.delete_book(request, ead_id=ead_id, archivefile_id=document['archivefile_id'])

    return eadfile.to_dict(request)
예제 #6
0
def service_add_ead_file(request):
    """
    Add a new EAD file

    parameters:

        * **file:**
        * **user:**
            the name of a user - optional, will be used for logging info
        * **status:**
            optional, a value among :ref:`status_values` (except 0)

        :returns: a JSON object with the id and url.

        See :ref:`TestEad.test_add`

    If successful, the file will be available on ``/ead/{ead_id}``,
    where ``{ead_id}`` is determined as follows:

        1. the value of ``/ead/eadheader/eadid/attribute::urn`` is defined,
           if this exists
        2. otherwise, the file name of the uploaded file

    If a file with this id exists, an error is raised.
    See :ref:`TestEad.test_error_if_upload_twice_id_from_filename`
    and :ref:`TestEad.test_error_if_upload_twice_id_from_content`

    If the file is not valid, an error is raised.
    See :ref:`TestEad.test_invalid_xml` and
    :ref:`TestEad.test_valid_xml_but_wrong_as_dtd`

    """
    eadfile = db.ead.add_ead_file(
        context=request,
        name=request.validated['ead_id'],
        status=request.validated['status'],
        filecontents=request.validated['raw_file'],
    )

    request._dbentity['ead'] = eadfile

    user = get_user(request)
    log_events(request.db, user, [{
        'object_id': request._dbentity['ead'].name,
        'object_type': 'ead',
        'message': 'create'
    }])

    context = request
    context.solr_ead.update([eadfile.get_solr_data()])

    components = eadfile.extract_component_dicts()
    context.solr_eadcomponent.update(components)
    context.solr.commit()

    archivefiles = [cast_component_as_archivefile(x).get_solr_data(context) for x in components if x['is_archiveFile']]
    for archivefile in archivefiles:
        db_records = get_archivefiles(request, archiveFile=archivefile['archiveFile'], archive_id=archivefile['archive_id'])
        if db_records:
            db_record = db_records[0]
            archivefile['status'] = db_record.status

    context.solr_archivefile.update(archivefiles)

    ead_id = eadfile.name
    for archivefile in archivefiles:
        if archivefile['status'] == config.STATUS_PUBLISHED:
            pagebrowser.update.refresh_book(context, ead_id=ead_id, archivefile_id=archivefile['archivefile_id'])

    return eadfile.to_dict(request)