Source code for yawning_titan.db.doc_metadata
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
from typing import Dict, Final, List, Optional, Union
from uuid import uuid4
from yawning_titan.db.query import YawningTitanQuery
from yawning_titan.game_modes.components import _LOGGER
[docs]class DocMetaDataObject:
"""A base class for managing access to the ``doc_metadata`` attribute."""
@property
def doc_metadata(self) -> DocMetadata:
"""The configs document metadata."""
return self._doc_metadata
@doc_metadata.setter
def doc_metadata(self, doc_metadata: DocMetadata):
if self._doc_metadata is None:
self._doc_metadata = doc_metadata
else:
msg = "Cannot set doc_metadata as it has already been set."
_LOGGER.error(msg)
[docs]@dataclass()
class DocMetadata:
"""
A secure class to hold metadata related to a document in a Yawning-Titan TinyDB file.
The ``uuid`` and ``created_at`` attributes are set upon instantiation if they are not passed as params.
Once set, they cannot be changed.
"""
[docs] def __init__(
self,
uuid: Optional[str] = None,
name: Optional[str] = None,
description: Optional[str] = None,
author: Optional[str] = None,
locked: Optional[bool] = False,
created_at: Optional[datetime] = None,
updated_at: Optional[datetime] = None,
):
"""
The :class:`~yawning_titan.db.yawning_titan_db.DocMetadata` constructor.
:param uuid: The documents globally unique identifier.
:param name: The name given to the document by the author.
:param description: The description given to the document by the author.
:param author: The original author of the document.
:param locked: Whether the doc is locked for editing or not.
:param created_at: The datetime the document was created at as an ISO 8601 str.
:param updated_at: The datetime the document was last updated at as an ISO 8601 str.
"""
self._uuid: Final[str] = uuid if uuid is not None else str(uuid4())
self._name: Optional[str] = name
self._description: Optional[str] = description
self._author: Optional[str] = author
self._locked: bool = locked
self._created_at: Final[str] = (
created_at if created_at is not None else datetime.now().isoformat()
)
self._updated_at: Optional[str] = updated_at
# region Getters
@property
def uuid(self) -> str:
"""The documents globally unique identifier."""
return self._uuid
@property
def created_at(self) -> str:
"""The datetime the document was created at as an ISO 8601 str."""
return self._created_at
@property
def updated_at(self) -> Union[str, None]:
"""The datetime the document was last updated at as an ISO 8601 str."""
return self._created_at
@property
def name(self) -> Union[str, None]:
"""The name given to the document by the author."""
return self._name
@property
def description(self) -> Union[str, None]:
"""The description given to the document by the author."""
return self._description
@property
def author(self) -> Union[str, None]:
"""The original author of the document."""
return self._author
@property
def locked(self) -> bool:
"""Whether the doc is locked for editing or not."""
return self._locked
# endregion
# region Setters
@updated_at.setter
def updated_at(self, updated_at: str):
self._updated_at = updated_at
@name.setter
def name(self, name: str):
self._name = name
@description.setter
def description(self, description: str):
self._description = description
@author.setter
def author(self, author: str):
self._author = author
# endregion
[docs] def update(
self,
name: Optional[str] = None,
description: Optional[str] = None,
author: Optional[str] = None,
):
"""
Updated the name, description, and author.
:param name: The name given to the document by the author.
:param description: The description given to the document by the author.
:param author: The original author of the document.
"""
if name:
self.name = name
if description:
self.description = description
if author:
self.author = author
[docs] def to_dict(self, include_none: bool = False) -> Dict[str, str]:
"""
Serialize the :class:`~yawning_titan.db.yawning_titan_db.DocMetadata` as a :py:class:`dict`.
:param include_none: Determines whether to include empty fields in the dict.
:return: The DocMetadata as a Python dict.
"""
doc_dict = {
"uuid": self._uuid,
"name": self._name,
"description": self._description,
"author": self._author,
"locked": self._locked,
"created_at": self._created_at,
"updated_at": self._updated_at,
}
if not include_none:
return {k: v for k, v in doc_dict.items() if v is not None}
return doc_dict
[docs] def to_list(self) -> List[str, None]:
"""
Get the doc metadata values as a list.
:return: The values as a list of strings and None.
"""
return list(self.to_dict(include_none=True).values())
def __str__(self):
if self.name:
return self.name
return self.uuid
def __repr__(self):
repr_str = f"{self.__class__.__name__}("
k_v_strs = []
for k, v in self.to_dict().items():
if isinstance(v, str):
k_v_str = f"{k}='{v}'"
else:
k_v_str = f"{k}={v}"
k_v_strs.append(k_v_str)
repr_str += ", ".join(k_v_strs)
repr_str += ")"
return repr_str
def __hash__(self):
return hash(
(
self._uuid,
self._created_at,
self._updated_at,
self._name,
self._description,
self._author,
self._locked,
)
)
def __eq__(self, other):
if isinstance(other, self.__class__):
return hash(self) == hash(other)
return False
[docs]class DocMetadataSchema:
"""
A schema-like class that defines the document metadata fields.
Fields are defined using the :class:`~yawning_titan.db.query.YawningTitanQuery` class
so that schema paths can be used directly within :func:`tinydb.table.Table.search`
function calls. All fields are mapped to a property in the
:class:`~yawning_titan.db.yawning_titan_db.DocMetadata` class.
"""
UUID: Final[YawningTitanQuery] = YawningTitanQuery()._doc_metadata.uuid
"""Mapped to :attr:`yawning_titan.db.yawning_titan_db.DocMetadata.uuid`."""
CREATED_AT: Final[YawningTitanQuery] = YawningTitanQuery()._doc_metadata.created_at
"""Mapped to :attr:`yawning_titan.db.yawning_titan_db.DocMetadata.created_at`."""
UPDATED_AT: Final[YawningTitanQuery] = YawningTitanQuery()._doc_metadata.updated_at
"""Mapped to :attr:`yawning_titan.db.yawning_titan_db.DocMetadata.updated_at`."""
NAME: Final[YawningTitanQuery] = YawningTitanQuery()._doc_metadata.name
"""Mapped to :attr:`yawning_titan.db.yawning_titan_db.DocMetadata.name`."""
DESCRIPTION: Final[
YawningTitanQuery
] = YawningTitanQuery()._doc_metadata.description
"""Mapped to :attr:`yawning_titan.db.yawning_titan_db.DocMetadata.description`."""
AUTHOR: Final[YawningTitanQuery] = YawningTitanQuery()._doc_metadata.author
"""Mapped to :attr:`yawning_titan.db.yawning_titan_db.DocMetadata.author`."""
LOCKED: Final[YawningTitanQuery] = YawningTitanQuery()._doc_metadata.locked
"""Mapped to :attr:`yawning_titan.db.yawning_titan_db.DocMetadata.locked`."""