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)
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)
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))
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)
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)
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)
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')
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)
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))
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()
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()
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()
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]