Exemple #1
0
def check_record_doi(record, update=False):
    """ Checks that the DOI of a record is registered."""
    recid = record.get('_deposit', {}).get('id')
    click.secho('checking DOI for record {}'.format(recid))
    doi_list = [DataCiteProvider.get(d.get('value'))
                for d in record['_pid']
                if d.get('type') == 'DOI']
    for doi in doi_list:
        if _datacite_doi_reference(doi.pid.pid_value) is None:
            if doi.pid.status == PIDStatus.REGISTERED:
                # the doi is not truly registered with datacite
                click.secho('    {}: not registered with datacite'.format(
                    doi.pid.pid_value))
                doi.pid.status = PIDStatus.RESERVED

        click.secho('    {}: {}'.format(doi.pid.pid_value, doi.pid.status))
        if doi.pid.status != PIDStatus.RESERVED:
            continue

        # RESERVED but not REGISTERED
        if update:
            recid = record.get('_deposit', {}).get('id')
            url = make_record_url(recid)
            doc = datacite_v31.serialize(doi.pid, record)
            _datacite_register_doi(doi, url, doc)
            db.session.commit()
            click.secho('    registered just now', fg='green', bold=True)
        else:
            click.secho('    not registered', fg='red', bold=True)
Exemple #2
0
def datacite_register(pid_value, record_uuid):
    """Mint the DOI with DataCite.

    :param pid_value: Value of record PID, with pid_type='recid'.
    :type pid_value: str
    """
    try:
        record = Record.get_record(record_uuid)
        # Bail out if not a Zenodo DOI.
        if not is_local_doi(record['doi']):
            return

        dcp = DataCiteProvider.get(record['doi'])

        url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
            recid=pid_value)
        doc = datacite_v31.serialize(dcp.pid, record)

        if dcp.pid.status == PIDStatus.REGISTERED:
            dcp.update(url, doc)
        else:
            dcp.register(url, doc)
        db.session.commit()
    except Exception as exc:
        datacite_register.retry(exc=exc)
Exemple #3
0
def register_doi(doi, url, xml, uuid):
    """
    Given a data submission id, this method takes it's assigned DOI, creates the DataCite XML,
    and registers the DOI.
    :param data_submissions:
    :param recid:
    :return:
    """

    log.info('{0} - {1}'.format(doi, url))

    try:
        provider = DataCiteProvider.get(doi, 'doi')
    except PIDDoesNotExistError:
        provider = create_doi(doi)

    pidstore_obj = PersistentIdentifier.query.filter_by(pid_value=doi).first()
    if pidstore_obj:
        pidstore_obj.object_uuid = uuid
        db.session.add(pidstore_obj)
        db.session.commit()
    try:
        provider.register(url, xml)
    except DataCiteUnauthorizedError:
        log.error('Unable to mint DOI. No authorisation credentials provided.')
    except PIDInvalidAction:
        provider.update(url, xml)
    except IntegrityError:
        provider.update(url, xml)
    except DataCiteError as dce:
        log.error('Error registering {0} for URL {1}\n\n{2}'
                  .format(doi, url, dce))
Exemple #4
0
def register_doi(doi, url, xml, uuid):
    """
    Given a data submission id, this method takes it's assigned DOI, creates the DataCite XML,
    and registers the DOI.
    :param data_submissions:
    :param recid:
    :return:
    """

    log.info('{0} - {1}'.format(doi, url))

    try:
        provider = DataCiteProvider.get(doi, 'doi')
    except PIDDoesNotExistError:
        provider = create_doi(doi)

    pidstore_obj = PersistentIdentifier.query.filter_by(pid_value=doi).first()
    if pidstore_obj:
        pidstore_obj.object_uuid = uuid
        db.session.add(pidstore_obj)
        db.session.commit()
    try:
        provider.register(url, xml)
    except DataCiteUnauthorizedError:
        log.error('Unable to mint DOI. No authorisation credentials provided.')
    except PIDInvalidAction:
        provider.update(url, xml)
    except IntegrityError:
        provider.update(url, xml)
    except DataCiteError as dce:
        log.error('Error registering {0} for URL {1}\n\n{2}'
                  .format(doi, url, dce))
Exemple #5
0
def check_record_doi(record, update=False):
    """ Checks that the DOI of a record is registered."""
    recid = record.get('_deposit', {}).get('id')
    click.secho('checking DOI for record {}'.format(recid))
    doi_list = [
        DataCiteProvider.get(d.get('value')) for d in record['_pid']
        if d.get('type') == 'DOI'
    ]
    for doi in doi_list:
        if _datacite_doi_reference(doi.pid.pid_value) is None:
            if doi.pid.status == PIDStatus.REGISTERED:
                # the doi is not truly registered with datacite
                click.secho('    {}: not registered with datacite'.format(
                    doi.pid.pid_value))
                doi.pid.status = PIDStatus.RESERVED

        click.secho('    {}: {}'.format(doi.pid.pid_value, doi.pid.status))
        if doi.pid.status != PIDStatus.RESERVED:
            continue

        # RESERVED but not REGISTERED
        if update:
            recid = record.get('_deposit', {}).get('id')
            url = make_record_url(recid)
            doc = datacite_v31.serialize(doi.pid, record)
            _datacite_register_doi(doi, url, doc)
            db.session.commit()
            click.secho('    registered just now', fg='green', bold=True)
        else:
            click.secho('    not registered', fg='red', bold=True)
Exemple #6
0
def datacite_register(self,
                      pid_value,
                      record_uuid,
                      max_retries=5,
                      countdown=5):
    """Mint the DOI with DataCite.

    :param pid_value: Value of record PID, with pid_type='recid'.
    :type pid_value: str
    """
    try:
        record = Record.get_record(record_uuid)
        # Bail out if not a CDS DOI.
        if not is_local_doi(record['doi']) or \
                not current_app.config['DEPOSIT_DATACITE_MINTING_ENABLED']:
            return

        dcp = DataCiteProvider.get(record['doi'])

        url = current_app.config['CDS_RECORDS_UI_LINKS_FORMAT'].format(
            recid=pid_value)
        doc = datacite_v31.serialize(dcp.pid, record)

        if dcp.pid.status == PIDStatus.REGISTERED:
            dcp.update(url, doc)
        else:
            dcp.register(url, doc)
        db.session.commit()
    except Exception as exc:
        db.session.rollback()
        raise self.retry(max_retries=max_retries, countdown=countdown, exc=exc)
Exemple #7
0
def datacite_register(pid_value, record_uuid):
    """Mint DOI and Concept DOI with DataCite.

    :param pid_value: Value of record PID, with pid_type='recid'.
    :type pid_value: str
    :param record_uuid: Record Metadata UUID.
    :type record_uuid: str
    """
    try:
        record = Record.get_record(record_uuid)
        # Bail out if not a Zenodo DOI.
        if not is_local_doi(record['doi']):
            return

        dcp = DataCiteProvider.get(record['doi'])
        doc = datacite_v41.serialize(dcp.pid, record)

        url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
            recid=pid_value)
        if dcp.pid.status == PIDStatus.REGISTERED:
            dcp.update(url, doc)
        else:
            dcp.register(url, doc)

        # If this is the latest record version, update/register the Concept DOI
        # using the metadata of the record.
        recid = PersistentIdentifier.get('recid', str(record['recid']))
        pv = PIDVersioning(child=recid)
        conceptdoi = record.get('conceptdoi')
        if conceptdoi and pv.exists and pv.is_last_child:
            conceptrecid = record.get('conceptrecid')
            concept_dcp = DataCiteProvider.get(conceptdoi)
            url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
                recid=conceptrecid)

            doc = datacite_v41.serialize(concept_dcp.pid, record)
            if concept_dcp.pid.status == PIDStatus.REGISTERED:
                concept_dcp.update(url, doc)
            else:
                concept_dcp.register(url, doc)

        db.session.commit()
    except Exception as exc:
        datacite_register.retry(exc=exc)
Exemple #8
0
def datacite_register(pid_value, record_uuid):
    """Mint DOI and Concept DOI with DataCite.

    :param pid_value: Value of record PID, with pid_type='recid'.
    :type pid_value: str
    :param record_uuid: Record Metadata UUID.
    :type record_uuid: str
    """
    try:
        record = Record.get_record(record_uuid)
        # Bail out if not a Zenodo DOI.
        if not is_local_doi(record['doi']):
            return

        dcp = DataCiteProvider.get(record['doi'])
        doc = datacite_v41.serialize(dcp.pid, record)

        url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
            recid=pid_value)
        if dcp.pid.status == PIDStatus.REGISTERED:
            dcp.update(url, doc)
        else:
            dcp.register(url, doc)

        # If this is the latest record version, update/register the Concept DOI
        # using the metadata of the record.
        recid = PersistentIdentifier.get('recid', str(record['recid']))
        pv = PIDVersioning(child=recid)
        conceptdoi = record.get('conceptdoi')
        if conceptdoi and pv.exists and pv.is_last_child:
            conceptrecid = record.get('conceptrecid')
            concept_dcp = DataCiteProvider.get(conceptdoi)
            url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
                recid=conceptrecid)

            doc = datacite_v41.serialize(concept_dcp.pid, record)
            if concept_dcp.pid.status == PIDStatus.REGISTERED:
                concept_dcp.update(url, doc)
            else:
                concept_dcp.register(url, doc)

        db.session.commit()
    except Exception as exc:
        datacite_register.retry(exc=exc)
def test_datacite_create_get(app, db):
    """Test datacite provider create/get."""
    with app.app_context():
        provider = DataCiteProvider.create('10.1234/a')
        assert provider.pid.status == PIDStatus.NEW
        assert provider.pid.pid_provider == 'datacite'

        # Crete passing client kwarg to provider object creation
        provider = DataCiteProvider.create('10.1234/b', client=MagicMock())
        assert provider.pid.status == PIDStatus.NEW
        assert provider.pid.pid_provider == 'datacite'
        assert isinstance(provider.api, MagicMock)

        provider = DataCiteProvider.get('10.1234/a')
        assert provider.pid.status == PIDStatus.NEW
        assert provider.pid.pid_provider == 'datacite'

        provider = DataCiteProvider.get('10.1234/a', client=MagicMock())
        assert isinstance(provider.api, MagicMock)
Exemple #10
0
def create_doi(doi):
    """
    :param doi: Creates a DOI using the data provider. If it already exists, we return back the existing provider.
    :return: DataCiteProvider
    """
    try:
        return DataCiteProvider.create(doi)
    except DataCiteUnauthorizedError:
        log.error('Unable to mint DOI. No authorisation credentials provided.')
    except Exception:
        return DataCiteProvider.get(doi, 'doi')
Exemple #11
0
def create_doi(doi):
    """
    :param doi: Creates a DOI using the data provider. If it already exists, we return back the existing provider.
    :return: DataCiteProvider
    """
    try:
        return DataCiteProvider.create(doi)
    except DataCiteUnauthorizedError:
        log.error('Unable to mint DOI. No authorisation credentials provided.')
    except Exception:
        return DataCiteProvider.get(doi, 'doi')
Exemple #12
0
def datacite_inactivate(pid_value):
    """Mint the DOI with DataCite.

    :param pid_value: Value of record PID, with pid_type='recid'.
    :type pid_value: str
    """
    try:
        dcp = DataCiteProvider.get(pid_value)
        dcp.delete()
        db.session.commit()
    except Exception as exc:
        datacite_inactivate.retry(exc=exc)
Exemple #13
0
def datacite_inactivate(pid_value):
    """Mint the DOI with DataCite.

    :param pid_value: Value of record PID, with pid_type='recid'.
    :type pid_value: str
    """
    try:
        dcp = DataCiteProvider.get(pid_value)
        dcp.delete()
        db.session.commit()
    except Exception as exc:
        datacite_inactivate.retry(exc=exc)
Exemple #14
0
def register_doi(doi, url, xml, uuid):
    """
    Given a data submission id, this method takes its assigned DOI, creates the DataCite XML,
    and registers the DOI.

    :param data_submissions:
    :param recid:
    :return:
    """
    if current_app.config.get('NO_DOI_MINTING', False) or not doi:
        return None

    log.info('{0} - {1}'.format(doi, url))

    print('Minting doi {}'.format(doi))
    try:
        provider = DataCiteProvider.get(doi, 'doi')
    except PIDDoesNotExistError:
        provider = create_doi(doi)

    pidstore_obj = PersistentIdentifier.query.filter_by(pid_value=doi).first()
    if pidstore_obj:
        pidstore_obj.object_uuid = uuid
        db.session.add(pidstore_obj)
        db.session.commit()
    try:
        provider.register(url, xml)
    except DataCiteUnauthorizedError:
        log.error('Unable to mint DOI. No authorisation credentials provided.')
    except (PIDInvalidAction, IntegrityError):
        try:
            provider.update(url, xml)  # try again in case of temporary problem
        except DataCiteError:
            try:
                provider.update(url, xml)
            except DataCiteError as dce:
                log.error('Error updating {0} for URL {1}\n\n{2}'.format(
                    doi, url, dce))
    except DataCiteError:
        try:
            provider.register(url,
                              xml)  # try again in case of temporary problem
        except (PIDInvalidAction, IntegrityError):
            try:
                provider.update(url, xml)
            except DataCiteError as dce:
                log.error('Error updating {0} for URL {1}\n\n{2}'.format(
                    doi, url, dce))
        except DataCiteError as dce:
            log.error('Error registering {0} for URL {1}\n\n{2}'.format(
                doi, url, dce))
Exemple #15
0
def datacite_register(pid_value, record_uuid):
    """Mint the DOI with DataCite.

    :param pid_value: Value of record PID, with pid_type='recid'.
    :type pid_value: str
    """
    record = Record.get_record(record_uuid)
    dcp = DataCiteProvider.get(record['doi'])

    url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
        recid=pid_value)
    doc = datacite_v31.serialize(dcp.pid, record)

    dcp.update(url, doc) if dcp.pid.status == PIDStatus.REGISTERED \
        else dcp.register(url, doc)
    db.session.commit()
Exemple #16
0
def update_datacite_metadata(doi, object_uuid, job_id):
    """Update DataCite metadata of a single PersistentIdentifier.

    :param doi: Value of doi PID, with pid_type='doi'. It could be a normal
    DOI or a concept DOI.
    :type doi: str
    :param object_uuid: Record Metadata UUID.
    :type object_uuid: str
    :param job_id: id of the job to which this task belongs.
    :type job_id: str
    """
    task_details = current_cache.get('update_datacite:task_details')

    if task_details is None or job_id != task_details['job_id']:
        return

    record = Record.get_record(object_uuid)

    dcp = DataCiteProvider.get(doi)
    if dcp.pid.status != PIDStatus.REGISTERED:
        return

    doc = datacite_v41.serialize(dcp.pid, record)

    for validator in xsd41():
        validator.assertValid(etree.XML(doc.encode('utf8')))

    url = None
    if doi == record.get('doi'):
        url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
            recid=str(record['recid']))
    elif doi == record.get('conceptdoi'):
        url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
            recid=str(record['conceptrecid']))

    result = dcp.update(url, doc)
    if result is True:
        dcp.pid.updated = datetime.utcnow()
        db.session.commit()
Exemple #17
0
def update_datacite_metadata(doi, object_uuid, job_id):
    """Update DataCite metadata of a single PersistentIdentifier.

    :param doi: Value of doi PID, with pid_type='doi'. It could be a normal
    DOI or a concept DOI.
    :type doi: str
    :param object_uuid: Record Metadata UUID.
    :type object_uuid: str
    :param job_id: id of the job to which this task belongs.
    :type job_id: str
    """
    task_details = current_cache.get('update_datacite:task_details')

    if task_details is None or job_id != task_details['job_id']:
        return

    record = Record.get_record(object_uuid)

    dcp = DataCiteProvider.get(doi)
    if dcp.pid.status != PIDStatus.REGISTERED:
        return

    doc = datacite_v41.serialize(dcp.pid, record)

    for validator in xsd41():
        validator.assertValid(etree.XML(doc.encode('utf8')))

    url = None
    if doi == record.get('doi'):
        url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
            recid=str(record['recid']))
    elif doi == record.get('conceptdoi'):
        url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
            recid=str(record['conceptrecid']))

    result = dcp.update(url, doc)
    if result is True:
        dcp.pid.updated = datetime.utcnow()
        db.session.commit()
Exemple #18
0
def update_datacite_metadata(pid_value, object_uuid, job_id):
    """Update DataCite metadata of a single PersistentIdentifier."""

    task_details = current_cache.get('update_datacite:task_details')

    if task_details is None or job_id != task_details['job_id']:
        return

    record = Record.get_record(object_uuid)

    dcp = DataCiteProvider.get(record['doi'])

    doc = datacite_v41.serialize(dcp.pid, record)

    for validator in xsd41():
        validator.assertValid(etree.XML(doc.encode('utf8')))

    url = current_app.config['ZENODO_RECORDS_UI_LINKS_FORMAT'].format(
        recid=pid_value)

    result = dcp.update(url, doc)
    if result is True:
        dcp.pid.updated = datetime.utcnow()
        db.session.commit()
Exemple #19
0
 def select_doi(metadata, status):
     doi_list = [DataCiteProvider.get(d.get('value'))
                 for d in metadata['_pid']
                 if d.get('type') == 'DOI']
     return [d for d in doi_list
             if d and d.pid and d.pid.status == status]
Exemple #20
0
 def select_doi(metadata, status):
     doi_list = [DataCiteProvider.get(d.get('value'))
                 for d in metadata['_pid']
                 if d.get('type') == 'DOI']
     return [d for d in doi_list
             if d and d.pid and d.pid.status == status]