Source code for app.portfolio.models.annotation.unique_annotation

# SPDX-License-Identifier: GPLv3-or-later
# Copyright © 2025 pygaindalf Rui Pinheiro

import weakref

from collections.abc import Mapping
from typing import Any, override

from ...util.uid import UID_SEPARATOR, Uid
from ..entity import Entity, EntityRecord
from .annotation import Annotation
from .annotation_journal import AnnotationJournal
from .annotation_record import AnnotationRecord


[docs] class UniqueAnnotation[ T_Record: AnnotationRecord, T_Journal: AnnotationJournal, ]( Annotation[T_Record, T_Journal], ): @classmethod def _calculate_parent_uid_from_dict(cls, data: Mapping[str, Any]) -> Uid: parent = data.get("instance_parent", data.get("instance_parent_weakref")) if parent is None: if (uid := data.get("uid")) is None or (entity := Entity.narrow_to_instance_or_none(uid)) is None: msg = "Either instance_parent or a uid for an existing entity must be provided." raise ValueError(msg) parent = entity.instance_parent if isinstance(parent, weakref.ref): parent = parent() if parent is None or not isinstance(parent, Entity): msg = "instance_parent must be provided and must be an Entity instance to use its UID." raise ValueError(msg) return parent.uid
[docs] @classmethod @override def calculate_instance_name_from_dict(cls, data: Mapping[str, Any]) -> str: parent_uid = cls._calculate_parent_uid_from_dict(data) return f"{cls.__name__}@{parent_uid!s}"
@classmethod @override def _calculate_uid(cls, data: Mapping[str, Any]) -> Uid: parent_uid = cls._calculate_parent_uid_from_dict(data) return Uid(namespace=cls.uid_namespace(), id=str(parent_uid).replace(UID_SEPARATOR, "-"))
[docs] @classmethod def get[T: UniqueAnnotation](cls: type[T], entity_or_uid: Entity | EntityRecord | Uid) -> T | None: entity = Entity.narrow_to_instance(entity_or_uid) return entity.get_annotation(cls)
[docs] @classmethod def get_or_create[T: UniqueAnnotation](cls: type[T], entity_or_uid: Entity | EntityRecord | Uid, /, **kwargs) -> T: if (annotation := cls.get(entity_or_uid)) is not None: annotation.journal.update(**kwargs) return annotation else: return cls.create(entity_or_uid, **kwargs)