60 lines
2.5 KiB
Python
60 lines
2.5 KiB
Python
from __future__ import annotations
|
||
|
||
import logging
|
||
from dataclasses import dataclass, field
|
||
from datetime import datetime
|
||
from typing import Optional
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class NFTLicense:
|
||
"""
|
||
Модель NFT лицензии на доступ к контенту.
|
||
|
||
Важно:
|
||
- license_id: уникальный идентификатор записи лицензии в нашей системе (может совпадать с nft_address или быть внутренним UUID)
|
||
- content_id: идентификатор контента (из ContentCipher, sha256 от шифроданных/метаданных)
|
||
- owner_address: адрес кошелька TON владельца NFT (user)
|
||
- nft_address: адрес NFT-токена лицензии (TON)
|
||
- created_at: когда лицензия была создана/закуплена (по данным блокчейна/системы)
|
||
- expires_at: необязательное поле срока действия (если лицензия не бессрочная)
|
||
"""
|
||
license_id: str
|
||
content_id: str
|
||
owner_address: str
|
||
nft_address: str
|
||
created_at: datetime = field(default_factory=lambda: datetime.utcnow())
|
||
expires_at: Optional[datetime] = None
|
||
|
||
def is_active(self, now: Optional[datetime] = None) -> bool:
|
||
now = now or datetime.utcnow()
|
||
if self.expires_at is None:
|
||
return True
|
||
return now < self.expires_at
|
||
|
||
def to_dict(self) -> dict:
|
||
return {
|
||
"license_id": self.license_id,
|
||
"content_id": self.content_id,
|
||
"owner_address": self.owner_address,
|
||
"nft_address": self.nft_address,
|
||
"created_at": self.created_at.isoformat(),
|
||
"expires_at": self.expires_at.isoformat() if self.expires_at else None,
|
||
}
|
||
|
||
@staticmethod
|
||
def from_dict(data: dict) -> "NFTLicense":
|
||
try:
|
||
return NFTLicense(
|
||
license_id=data["license_id"],
|
||
content_id=data["content_id"],
|
||
owner_address=data["owner_address"],
|
||
nft_address=data["nft_address"],
|
||
created_at=datetime.fromisoformat(data["created_at"]) if data.get("created_at") else datetime.utcnow(),
|
||
expires_at=datetime.fromisoformat(data["expires_at"]) if data.get("expires_at") else None,
|
||
)
|
||
except Exception as e:
|
||
logger.error("Failed to parse NFTLicense from dict: %s", e)
|
||
raise |