"""ownership cache model. Ownership cache models are stored in AWS ElastiCache Redis (For reducing ows_product or ows_track loadout) """ import json import time from typing import Any from assets.connectors import redis_connector from assets.constants import error from assets.exceptions import InvalidEntityType ENTITY_TYPE_PRODUCT = "product" ENTITY_TYPE_TRACK = "track" ENTITY_TYPE_ARTIST = "artist" CACHE_TTL = 24 * 60 * 60 # 24 hours def _get_key( entity_type: str, entity_id: int, account_type: str | None, account_id: int | str | None, ) -> str: """Get generated key for cache. Args: entity_type (str): Entity type (product or track). entity_id (int): Entity unique id. account_type (str | None): Account type. account_id (int | str | None): Account ID. Returns: string: Key for cache record identifier. """ return "ownership:{entity_type}:{account_type}:{account_id}:{entity_id}".format( account_type=str(account_type), account_id=str(account_id), entity_type=entity_type, entity_id=entity_id, ) def _get_created_time() -> str: """Get cache record creation time in specified format. Returns: string: Formatted current time. """ return time.strftime("%Y%m%d%H%M%S", time.localtime()) def _check_entity_type(entity_type: str) -> bool: """Validate entity type. Args: entity_type (str): Entity type (product or track). Return: bool: True if entity_type is valid, False otherwise. """ return entity_type in [ENTITY_TYPE_PRODUCT, ENTITY_TYPE_TRACK, ENTITY_TYPE_ARTIST] def save( entity_type: str, entity_id: int, account_type: str | None, account_id: int | str | None, ownership: bool, ) -> None: """Save ownership information to cache. Args: entity_type (str): Entity type (product or track). entity_id (int): Entity unique id. account_type (str): Account type. account_id (int | str): Account ID. ownership (bool) TRUE if account is owner of the entity, FALSE otherwise. """ if not _check_entity_type(entity_type): raise InvalidEntityType(error.ERROR_MESSAGE_INVALID_ENTITY_TYPE) data = {"ownership": ownership, "created": _get_created_time()} try: redis_connector.client.set( _get_key(entity_type, entity_id, account_type, account_id), json.dumps(data), CACHE_TTL, ) except Exception: pass def get( entity_type: str, entity_id: int, account_type: str | None, account_id: int | str | None, ) -> dict[str, Any] | None: """Get ownership information from cache. Args: entity_type (str): Entity type (product or track). entity_id (int): Entity unique id. account_type (str | None): Account type. account_id (int | str | None): Account ID. Returns: str | None: Ownership data. """ if not _check_entity_type(entity_type): raise InvalidEntityType(error.ERROR_MESSAGE_INVALID_ENTITY_TYPE) key = _get_key(entity_type, entity_id, account_type, account_id) try: result = redis_connector.client.get(key) if result and redis_connector.client.ttl(key) > 0: return json.loads(result.decode("utf8")) # type: ignore[no-any-return] except Exception: pass return None