Пример #1
0
    def get(self):
        """Get all relations of this record, adding any relations metadata."""
        relations = {}

        for relation_type in current_app.config["PARENT_CHILD_RELATION_TYPES"]:
            pcr = ParentChildRelation(relation_type)
            name = relation_type.name

            # self.record is a child
            for parent_pid in pcr.parents_of(self.record.pid):
                child_pid = self.record.pid
                r = self._build_child(parent_pid, child_pid, name)
                relations.setdefault(name, [])
                relations[name].append(r)

        for relation_type in current_app.config["SIBLINGS_RELATION_TYPES"]:
            sr = SiblingsRelation(relation_type)
            name = relation_type.name

            for related_pid in sr.all(self.record.pid):
                r = self._build_sibling(related_pid, name)
                relations.setdefault(name, [])
                relations[name].append(r)

        for relation_type in current_app.config["SEQUENCE_RELATION_TYPES"]:
            sqr = SequenceRelation(relation_type)
            name = relation_type.name

            for next_pid in sqr.next_relations(self.record.pid):
                relations.setdefault("next", [])
                r = self._build_sequence(next_pid, name)
                relations["next"].append(r)

            for previous_pid in sqr.previous_relations(self.record.pid):
                relations.setdefault("previous", [])
                r = self._build_sequence(previous_pid, name)
                relations["previous"].append(r)

        return relations
Пример #2
0
    def _validate_relation_between_records(self, parent, child, relation_type):
        """Validate relation between type of records."""
        from invenio_app_ils.documents.api import Document
        from invenio_app_ils.series.api import Series

        if relation_type.name == "multipart_monograph":
            pcr = ParentChildRelation(relation_type)
            relations = pcr.get_relations_by_child(child.pid)
            if len(relations) > 0:
                raise RecordRelationsError(
                    "Cannot create a relation `{}` between PID `{}` as parent"
                    " and PID `{}` as child. Record `{}` has already a"
                    " multipart monograph.".format(
                        relation_type.name,
                        parent.pid.pid_value,
                        child.pid.pid_value,
                        child.pid.pid_value,
                    ))

        # when child is Document, parent is any type of Series
        is_series_doc = isinstance(child, Document) and isinstance(
            parent, Series)
        # when child is Multipart Monograph, parent is only Serials
        is_serial_mm = (isinstance(child, Series)
                        and isinstance(parent, Series)
                        and child["mode_of_issuance"] == "MULTIPART_MONOGRAPH"
                        and parent["mode_of_issuance"] == "SERIAL")

        if not (is_series_doc or is_serial_mm):
            raise RecordRelationsError(
                "Cannot create a relation `{}` between PID `{}` as parent and "
                "PID `{}` as child.".format(
                    relation_type.name,
                    parent.pid.pid_value,
                    child.pid.pid_value,
                ))
        return True
Пример #3
0
    def add(self, parent, child, relation_type, **kwargs):
        """Add a new relation between given parent and child records."""
        self._validate_relation_type(relation_type)
        self._validate_relation_between_records(
            parent=parent, child=child, relation_name=relation_type.name
        )

        pcr = ParentChildRelation(relation_type)
        pcr.add(parent_pid=parent.pid, child_pid=child.pid)

        # relation metadata is allowed only for MULTIPART_MONOGRAPH
        relation_allows_metadata = relation_type in (
            MULTIPART_MONOGRAPH_RELATION,
            SERIAL_RELATION,
        )
        # check for allowed relation metadata (e.g. `volume`)
        has_allowed_metadata = any(
            [kwargs.get(metadata) for metadata in self.allowed_metadata]
        )

        if relation_allows_metadata and has_allowed_metadata:
            # filter and keep only allowed metadata
            allowed = {
                k: v for k, v in kwargs.items() if k in self.allowed_metadata
            }
            # store relation metadata in the child record
            RecordRelationsExtraMetadata.add_extra_metadata_to(
                child,
                relation_type.name,
                parent.pid.pid_value,
                parent.pid.pid_type,
                **allowed,
            )

        # return the allegedly modified record
        return child