def create(cls, data, id_=None, *args, **kwargs): record_class = cls.get_class_for_record(data) if record_class != cls: return record_class.create(data, id_=id_, *args, **kwargs) data = cls.strip_empty_values(data) deleted = data.get("deleted", False) with db.session.begin_nested(): if not id_: id_ = uuid.uuid4() if not deleted: cls.delete_records_from_deleted_records(data) cls.pidstore_handler.mint(id_, data) if deleted: cls.pidstore_handler.delete(id_, data) kwargs.pop("disable_external_push", None) kwargs.pop("disable_relations_update", None) data["self"] = get_ref_from_pid(cls.pid_type, data["control_number"]) record = cls(data) record.validate(**kwargs) if not record.get("deleted") and record.get("deleted_records"): record.redirect_pids(record["deleted_records"]) record.model = cls.model_cls(id=id_, json=record) record.update_model_created_with_legacy_creation_date() db.session.add(record.model) return record
def redirected_record_ref(self): """Returns redirected PID if PID was redirected, otherwise returns None""" pid = self.control_number_pid if self.get("deleted") and pid.status == PIDStatus.REDIRECTED: redirection = InspireRedirect.get_redirect(pid) return get_ref_from_pid(redirection.pid_type, redirection.pid_value)
def update_refs_to_conferences(data): """Assign $ref to every publication_info which cnum we have in PIDStore""" for conference in data.get("publication_info", []): cnum = conference.get("cnum") if not cnum: continue pid = get_pid_for_pid("cnum", cnum, "recid") if not pid: LOGGER.info(f"CNUM: {cnum} is missing in PIDStore") continue conference["conference_record"] = get_ref_from_pid("con", pid)
def do(record, logger, state): for advisor in record["advisors"]: if not advisor_has_inspire_id_but_no_record(advisor): continue inspire_id = get_values_for_schema(advisor["ids"], "INSPIRE ID")[0] hits = ( AuthorsSearch().query_from_iq(f"ids.value:{inspire_id}").execute().hits ) recids = [hit.control_number for hit in hits] if not len(recids) == 1: logger.warning( "No unique match for INSPIRE ID, skipping.", inspire_id=inspire_id, recids=recids, ) continue recid = recids[0] advisor["record"] = get_ref_from_pid("aut", recid)
def update(self, data, force_undelete=False, *args, **kwargs): if not self.get("deleted", False): if "control_number" not in data: raise ValueError("Missing control number in record update.") # Currently Invenio is clearing record in put method in invenio_records_rest/views.py # this is called just before `record.update()` so here record is already empty # it means that it's not possible to verify if control_number is correct in here. if data["control_number"] != self.control_number: data["self"] = get_ref_from_pid(self.pid_type, data["control_number"]) pid = PersistentIdentifier.query.filter_by( pid_type=self.pid_type, pid_value=str(data["control_number"]) ).one_or_none() if not data.get("deleted") and pid and pid.status == PIDStatus.REDIRECTED: # To be sure that when someone edits redirected record by mistake tries to undelete record as this is not supported for now raise CannotUndeleteRedirectedRecord(self.pid_type, data["control_number"]) if ( not force_undelete # Check deleted status of current version ad new version and self.model.json.get("deleted") and not data.get("deleted") ): raise ValidationError("Deleted record can't be undeleted!") with db.session.begin_nested(): with db.session.no_autoflush: self.clear() super().update(data) self.validate() self.model.json = dict(self) if data.get("deleted"): self.pidstore_handler.delete(self.id, self) else: self.delete_records_from_deleted_records(data) self.pidstore_handler.update(self.id, self) if self.get("deleted_records"): self.redirect_pids(self["deleted_records"]) self.update_model_created_with_legacy_creation_date() flag_modified(self.model, "json") db.session.merge(self.model)
def create(cls, data, id_=None, *args, **kwargs): record_class = cls.get_class_for_record(data) if record_class != cls: return record_class.create(data, *args, **kwargs) data = cls.strip_empty_values(data) with db.session.begin_nested(): if not id_: id_ = uuid.uuid4() deleted = data.get("deleted", False) if not deleted: cls.pidstore_handler.mint(id_, data) kwargs.pop("disable_orcid_push", None) kwargs.pop("disable_relations_update", None) data["self"] = get_ref_from_pid(cls.pid_type, data["control_number"]) record = super().create(data, id_=id_, **kwargs) record.update_model_created_with_legacy_creation_date() return record
def redirect_pid(self, pid_type, pid_value): try: old_pid = PersistentIdentifier.get(pid_type, pid_value) except PIDDoesNotExistError: LOGGER.warning( "Cannot redirect non existent PID", pid_to_redirect=pid_value, redirecting_pid=self.control_number, pid_type=self.pid_type, ) return old_pid_object_uuid = str(old_pid.object_uuid) new_pid = self.control_number_pid InspireRedirect.redirect(old_pid, new_pid) old_record = self.get_record(old_pid_object_uuid, with_deleted=True) old_record["new_record"] = get_ref_from_pid(self.pid_type, self.control_number) if not old_record.get("deleted"): old_record.delete() else: old_record.update(dict(old_record))
def update(self, data, *args, **kwargs): if not self.get("deleted", False): if "control_number" not in data: raise ValueError("Missing control number in record update.") # Currently Invenio is clearing record in put method in invenio_records_rest/views.py # this is called just before `record.update()` so here record is already empty # it means that it's not possible to verify if control_number is correct in here. if ("control_number" in self and data["control_number"] != self["control_number"]): data["self"] = get_ref_from_pid(self.pid_type, data["control_number"]) with db.session.begin_nested(): self.clear() super().update(data) self.model.json = dict(self) self.validate() if data.get("deleted"): self.pidstore_handler.delete(self.id, self) else: self.pidstore_handler.update(self.id, self) self.update_model_created_with_legacy_creation_date() flag_modified(self.model, "json") db.session.add(self.model)