def _publish_new(self, id_=None): """Publish new deposit with communities handling.""" dep_comms = set(self.pop('communities', [])) record = super(ZenodoDeposit, self)._publish_new(id_=id_) conceptrecid = PersistentIdentifier.get('recid', record['conceptrecid']) pv = PIDVersioning(parent=conceptrecid) if pv.children.count() > 1: files_set = set(f.get_version().file.checksum for f in self.files) for prev_recid in pv.children.all()[:-1]: rec = ZenodoRecord.get_record(prev_recid.object_uuid) prev_files_set = set(f.get_version().file.checksum for f in rec.files) if files_set == prev_files_set: raise VersioningFilesError() prev_recid = pv.children.all()[-2] rec_comms = set(ZenodoRecord.get_record( prev_recid.get_assigned_object()).get('communities', [])) else: rec_comms = set() record = self._sync_communities(dep_comms, rec_comms, record) record.commit() # Update the concept recid redirection pv.update_redirect() RecordDraft.unlink(record.pid, self.pid) index_siblings(record.pid, neighbors_eager=True, with_deposits=True) return record
def create(cls, data, id_=None): """Create a deposit. Adds bucket creation immediately on deposit creation. """ bucket = Bucket.create( quota_size=current_app.config['ZENODO_BUCKET_QUOTA_SIZE'], max_file_size=current_app.config['ZENODO_MAX_FILE_SIZE'], ) data['_buckets'] = {'deposit': str(bucket.id)} deposit = super(ZenodoDeposit, cls).create(data, id_=id_) RecordsBuckets.create(record=deposit.model, bucket=bucket) recid = PersistentIdentifier.get( 'recid', str(data['recid'])) conceptrecid = PersistentIdentifier.get( 'recid', str(data['conceptrecid'])) depid = PersistentIdentifier.get( 'depid', str(data['_deposit']['id'])) PIDVersioning(parent=conceptrecid).insert_draft_child(child=recid) RecordDraft.link(recid, depid) return deposit
def versioning_new_deposit(uuid): """Migrate a yet-unpublished deposit to a versioning scheme.""" deposit = ZenodoDeposit.get_record(uuid) if 'conceptrecid' in deposit: return # ASSERT ZENODO DOI ONLY! assert 'conceptrecid' not in deposit, 'Concept RECID already in record.' conceptrecid = zenodo_concept_recid_minter(uuid, deposit) recid = PersistentIdentifier.get('recid', str(deposit['recid'])) depid = PersistentIdentifier.get('depid', str(deposit['_deposit']['id'])) pv = PIDVersioning(parent=conceptrecid) pv.insert_draft_child(recid) RecordDraft.link(recid, depid) deposit.commit() db.session.commit()
def create(cls, data, id_=None): """Create a deposit. Adds bucket creation immediately on deposit creation. """ bucket = Bucket.create( quota_size=current_app.config['WEKO_BUCKET_QUOTA_SIZE'], max_file_size=current_app.config['WEKO_MAX_FILE_SIZE'], ) if '$schema' in data: data.pop('$schema') data['_buckets'] = {'deposit': str(bucket.id)} # save user_name & display name. if current_user and current_user.is_authenticated: user = UserProfile.get_by_userid(current_user.get_id()) username = '' displayname = '' if user is not None: username = user._username displayname = user._displayname if '_deposit' in data: data['_deposit']['owners_ext'] = { 'username': username, 'displayname': displayname, 'email': current_user.email } deposit = super(WekoDeposit, cls).create(data, id_=id_) RecordsBuckets.create(record=deposit.model, bucket=bucket) recid = PersistentIdentifier.get('recid', str(data['_deposit']['id'])) depid = PersistentIdentifier.get('depid', str(data['_deposit']['id'])) p_depid = PersistentIdentifier.create('parent', 'parent:recid/{0}'.format( str(data['_deposit']['id'])), object_type='rec', object_uuid=uuid.uuid4(), status=PIDStatus.REGISTERED) PIDVersioning(parent=p_depid).insert_draft_child(child=recid) RecordDraft.link(recid, depid) return deposit
def create(cls, data, id_=None): """Create a deposit. Adds bucket creation immediately on deposit creation. """ bucket = Bucket.create(**cls._get_bucket_settings()) data['_buckets'] = {'deposit': str(bucket.id)} deposit = super(ZenodoDeposit, cls).create(data, id_=id_) RecordsBuckets.create(record=deposit.model, bucket=bucket) recid = PersistentIdentifier.get('recid', str(data['recid'])) conceptrecid = PersistentIdentifier.get('recid', str(data['conceptrecid'])) depid = PersistentIdentifier.get('depid', str(data['_deposit']['id'])) PIDVersioning(parent=conceptrecid).insert_draft_child(child=recid) RecordDraft.link(recid, depid) return deposit
def draft_child_deposit(self): """ Get the deposit of the draft child. Return `None` if no new-version deposit exists. """ from invenio_pidrelations.contrib.records import RecordDraft if self.draft_child: return RecordDraft.get_draft(self.draft_child) else: return None
def test_record_draft(app, db): """Test RecordDraft API.""" assert PersistentIdentifier.query.count() == 0 assert PIDRelation.query.count() == 0 d1 = PersistentIdentifier.create('depid', '1', object_type='rec') r1 = PersistentIdentifier.create('recid', '1', object_type='rec') assert PersistentIdentifier.query.count() == 2 RecordDraft.link(recid=r1, depid=d1) assert PIDRelation.query.count() == 1 pr = PIDRelation.query.one() RECORD_DRAFT = resolve_relation_type_config('record_draft').id assert pr.relation_type == RECORD_DRAFT assert pr.index is None assert pr.parent == r1 assert pr.child == d1 d2 = PersistentIdentifier.create('depid', '2', object_type='rec') r2 = PersistentIdentifier.create('recid', '2', object_type='rec') with pytest.raises(Exception) as excinfo: RecordDraft.link(recid=r1, depid=d2) assert 'already has a depid as a draft' in str(excinfo.value) with pytest.raises(Exception) as excinfo: RecordDraft.link(recid=r2, depid=d1) assert 'already is a draft of a recid' in str(excinfo.value)
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
def draft_child_deposit(self): from invenio_pidrelations.contrib.records import RecordDraft return RecordDraft.get_draft(self.draft_child)
def newversion(self, pid=None): """Create a new version deposit.""" deposit = None try: if not self.is_published(): raise PIDInvalidAction() # Check that there is not a newer draft version for this record # and this is the latest version pv = PIDVersioning(child=pid) if pv.exists and not pv.draft_child and pid == pv.last_child: last_pid = pv.last_child # Get copy of the latest record latest_record = WekoDeposit.get_record(last_pid.object_uuid) if latest_record is not None: data = latest_record.dumps() owners = data['_deposit']['owners'] 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(WekoDeposit, self).create(data) # Injecting owners is required in case of creating new # version this outside of request context deposit['_deposit']['owners'] = owners recid = PersistentIdentifier.get( 'recid', str(data['_deposit']['id'])) depid = PersistentIdentifier.get( 'depid', str(data['_deposit']['id'])) PIDVersioning(parent=pv.parent).insert_draft_child( child=recid) RecordDraft.link(recid, depid) # Create snapshot from the record's bucket and update data snapshot = latest_record.files.bucket.snapshot(lock=False) snapshot.locked = False deposit['_buckets'] = {'deposit': str(snapshot.id)} RecordsBuckets.create(record=deposit.model, bucket=snapshot) if 'extra_formats' in latest_record['_buckets']: extra_formats_snapshot = \ latest_record.extra_formats.bucket.snapshot( lock=False) deposit['_buckets']['extra_formats'] = \ str(extra_formats_snapshot.id) RecordsBuckets.create(record=deposit.model, bucket=extra_formats_snapshot) index = { 'index': self.get('path', []), 'actions': 'private' if self.get('publish_status', '1') == '1' else 'publish' } if 'activity_info' in session: del session['activity_info'] item_metadata = ItemsMetadata.get_record( last_pid.object_uuid).dumps() args = [index, item_metadata] deposit.update(*args) deposit.commit() return deposit except SQLAlchemyError as ex: current_app.logger.debug(ex) db.session.rollback() return None