def test_doi_generator(app): """Test doi_generator.""" p = app.config['PIDSTORE_DATACITE_DOI_PREFIX'] # Check normal generation. assert doi_generator(1234) == '{prefix}/zenodo.1234'.format(prefix=p) # Check doi id for recid mapping assert doi_generator(7468) == '{prefix}/zenodo.7448'.format(prefix=p)
def translator(data): # Replace refs when we are in request context. context = dict(replace_refs=has_request_context()) # DOI validation context if request and request.view_args.get('pid_value'): managed_prefix = current_app.config['PIDSTORE_DATACITE_DOI_PREFIX'] _, record = request.view_args.get('pid_value').data context['recid'] = record['recid'] if record.has_minted_doi() or record.get('conceptdoi'): context['required_doi'] = record['doi'] elif not record.is_published(): context['allowed_dois'] = [doi_generator(record['recid'])] else: # Ensure we cannot change to e.g. empty string. context['doi_required'] = True context['managed_prefixes'] = [managed_prefix] context['banned_prefixes'] = \ ['10.5072'] if managed_prefix != '10.5072' else [] # Extra context context.update(kwargs) # Load data result = schema_class(context=context).load(data) if result.errors: raise MarshmallowErrors(result.errors) return result.data
def translator(data): # Replace refs when we are in request context. context = dict(replace_refs=has_request_context()) # DOI validation context if request and request.view_args.get('pid_value'): managed_prefix = current_app.config['PIDSTORE_DATACITE_DOI_PREFIX'] _, record = request.view_args.get('pid_value').data context['recid'] = record['recid'] if record.has_minted_doi(): context['required_doi'] = record['doi'] elif not record.is_published(): context['allowed_dois'] = [doi_generator(record['recid'])] else: # Ensure we cannot change to e.g. empty string. context['doi_required'] = True context['managed_prefixes'] = [managed_prefix] context['banned_prefixes'] = \ ['10.5072'] if managed_prefix != '10.5072' else [] # Extra context context.update(kwargs) # Load data result = schema_class(context=context).load(data) if result.errors: raise MarshmallowErrors(result.errors) return result.data
def translator(data): # Replace refs when we are in request context. context = dict(replace_refs=has_request_context()) # DOI validation context if request and request.view_args.get('pid_value'): managed_prefix = current_app.config['PIDSTORE_DATACITE_DOI_PREFIX'] _, record = request.view_args.get('pid_value').data context['recid'] = record['recid'] if record.has_minted_doi() or record.get('conceptdoi'): # if record has Zenodo DOI it's not allowed to change context['required_doi'] = record['doi'] elif not record.is_published(): context['allowed_dois'] = [doi_generator(record['recid'])] if record.is_published() or record.get('conceptdoi'): # if the record is published or this is a new version # of a published record then the DOI is required context['doi_required'] = True data.setdefault('metadata', {}) if 'doi' not in data['metadata']: # if the payload doesn't contain the DOI field # for the record keep the existing one data['metadata']['doi'] = record['doi'] context['managed_prefixes'] = [managed_prefix] context['banned_prefixes'] = \ ['10.5072'] if managed_prefix != '10.5072' else [] # Extra context context.update(kwargs) # Load data result = schema_class(context=context).load(data) if result.errors: raise MarshmallowErrors(result.errors) return result.data
def newversion(self, pid=None): """Create a new version deposit.""" if not self.is_published(): raise PIDInvalidAction() # Check that there is not a newer draft version for this record pid, record = self.fetch_published() pv = PIDVersioning(child=pid) if (not pv.draft_child and is_doi_locally_managed(record['doi'])): with db.session.begin_nested(): # Get copy of the latest record latest_record = ZenodoRecord.get_record( pv.last_child.object_uuid) data = latest_record.dumps() # Get the communities from the last deposit # and push those to the new version latest_depid = PersistentIdentifier.get( 'depid', data['_deposit']['id']) latest_deposit = ZenodoDeposit.get_record( latest_depid.object_uuid) last_communities = latest_deposit.get('communities', []) owners = data['_deposit']['owners'] # TODO: Check other data that may need to be removed keys_to_remove = ( '_deposit', 'doi', '_oai', '_files', '_buckets', '$schema') for k in keys_to_remove: data.pop(k, None) # NOTE: We call the superclass `create()` method, because we # don't want a new empty bucket, but an unlocked snapshot of # the old record's bucket. deposit = (super(ZenodoDeposit, self).create(data)) # Injecting owners is required in case of creating new # version this outside of request context deposit['_deposit']['owners'] = owners if last_communities: deposit['communities'] = last_communities ### conceptrecid = PersistentIdentifier.get( 'recid', data['conceptrecid']) recid = PersistentIdentifier.get( 'recid', str(data['recid'])) depid = PersistentIdentifier.get( 'depid', str(data['_deposit']['id'])) PIDVersioning(parent=conceptrecid).insert_draft_child( child=recid) RecordDraft.link(recid, depid) # Pre-fill the Zenodo DOI to prevent the user from changing it # to a custom DOI. deposit['doi'] = doi_generator(recid.pid_value) pv = PIDVersioning(child=pid) index_siblings(pv.draft_child, neighbors_eager=True, with_deposits=True) with db.session.begin_nested(): # Create snapshot from the record's bucket and update data snapshot = latest_record.files.bucket.snapshot(lock=False) snapshot.locked = False if 'extra_formats' in latest_record['_buckets']: extra_formats_snapshot = \ latest_record.extra_formats.bucket.snapshot( lock=False) deposit['_buckets'] = {'deposit': str(snapshot.id)} RecordsBuckets.create(record=deposit.model, bucket=snapshot) if 'extra_formats' in latest_record['_buckets']: deposit['_buckets']['extra_formats'] = \ str(extra_formats_snapshot.id) RecordsBuckets.create( record=deposit.model, bucket=extra_formats_snapshot) deposit.commit() return self
def newversion(self, pid=None): """Create a new version deposit.""" if not self.is_published(): raise PIDInvalidAction() # Check that there is not a newer draft version for this record pid, record = self.fetch_published() pv = PIDVersioning(child=pid) if (not pv.draft_child and is_doi_locally_managed(record['doi'])): with db.session.begin_nested(): # Get copy of the latest record latest_record = ZenodoRecord.get_record( pv.last_child.object_uuid) data = latest_record.dumps() # Get the communities from the last deposit # and push those to the new version latest_depid = PersistentIdentifier.get( 'depid', data['_deposit']['id']) latest_deposit = ZenodoDeposit.get_record( latest_depid.object_uuid) last_communities = latest_deposit.get('communities', []) owners = data['_deposit']['owners'] # TODO: Check other data that may need to be removed keys_to_remove = ( '_deposit', 'doi', '_oai', '_files', '_buckets', '$schema') for k in keys_to_remove: data.pop(k, None) # NOTE: We call the superclass `create()` method, because we # don't want a new empty bucket, but an unlocked snapshot of # the old record's bucket. deposit = (super(ZenodoDeposit, self).create(data)) # Injecting owners is required in case of creating new # version this outside of request context deposit['_deposit']['owners'] = owners if last_communities: deposit['communities'] = last_communities ### conceptrecid = PersistentIdentifier.get( 'recid', data['conceptrecid']) recid = PersistentIdentifier.get( 'recid', str(data['recid'])) depid = PersistentIdentifier.get( 'depid', str(data['_deposit']['id'])) PIDVersioning(parent=conceptrecid).insert_draft_child( child=recid) RecordDraft.link(recid, depid) # Pre-fill the Zenodo DOI to prevent the user from changing it # to a custom DOI. deposit['doi'] = doi_generator(recid.pid_value) pv = PIDVersioning(child=pid) index_siblings(pv.draft_child, neighbors_eager=True, with_deposits=True) with db.session.begin_nested(): # Create snapshot from the record's bucket and update data snapshot = latest_record.files.bucket.snapshot(lock=False) snapshot.locked = False # FIXME: `snapshot.id` might not be present because we need to # commit first to the DB. # db.session.commit() deposit['_buckets'] = {'deposit': str(snapshot.id)} RecordsBuckets.create(record=deposit.model, bucket=snapshot) deposit.commit() return self