File size: 2,190 Bytes
db521fa | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
import uuid
def _uid() -> str:
return str(uuid.uuid4())
def _now() -> datetime:
return datetime.utcnow()
@dataclass
class User:
name: str
email: str
id: str = field(default_factory=_uid)
role: str = "user"
active: bool = True
created_at: datetime = field(default_factory=_now)
def deactivate(self) -> None:
self.active = False
def promote(self, role: str = "admin") -> None:
self.role = role
def to_dict(self) -> dict:
return {
"id": self.id, "name": self.name, "email": self.email,
"role": self.role, "active": self.active,
"created_at": self.created_at.isoformat(),
}
@classmethod
def from_dict(cls, d: dict) -> User:
return cls(
id=d.get("id", _uid()), name=d["name"], email=d["email"],
role=d.get("role", "user"), active=d.get("active", True),
)
@dataclass
class Record:
title: str
owner_id: str
id: str = field(default_factory=_uid)
tags: list[str] = field(default_factory=list)
active: bool = True
created_at: datetime = field(default_factory=_now)
updated_at: Optional[datetime] = None
def touch(self) -> None:
self.updated_at = _now()
def add_tag(self, tag: str) -> None:
if tag and tag not in self.tags:
self.tags.append(tag)
def remove_tag(self, tag: str) -> None:
self.tags = [t for t in self.tags if t != tag]
def update(self, **kw) -> None:
for k, v in kw.items():
if hasattr(self, k):
setattr(self, k, v)
self.touch()
def to_dict(self) -> dict:
return {
"id": self.id, "title": self.title, "owner_id": self.owner_id,
"tags": self.tags, "active": self.active,
"created_at": self.created_at.isoformat(),
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
}
|