uploader-bot/app/core/network/dht/keys.py

73 lines
2.1 KiB
Python

from __future__ import annotations
import json
from dataclasses import dataclass
from datetime import datetime, timezone
from typing import Dict, Any
from .config import dht_config
from .crypto import digest_hex
def _json_dumps(data: Dict[str, Any]) -> bytes:
return json.dumps(data, sort_keys=True, separators=(",", ":")).encode()
@dataclass(frozen=True)
class MetaKey:
content_id: str
schema_version: str = dht_config.schema_version
def fingerprint(self) -> str:
return digest_hex(self.serialize())
def serialize(self) -> bytes:
return _json_dumps({"schema_version": self.schema_version, "content_id": self.content_id, "type": "meta"})
def __str__(self) -> str:
return f"meta:{self.schema_version}:{self.content_id}"
@dataclass(frozen=True)
class MembershipKey:
node_id: str
schema_version: str = dht_config.schema_version
def fingerprint(self) -> str:
return digest_hex(self.serialize())
def serialize(self) -> bytes:
return _json_dumps({"schema_version": self.schema_version, "node_id": self.node_id, "type": "membership"})
def __str__(self) -> str:
return f"membership:{self.schema_version}:{self.node_id}"
@dataclass(frozen=True)
class MetricKey:
content_id: str
window_id: str
schema_version: str = dht_config.schema_version
@classmethod
def window_for(cls, timestamp: float, window_size: int | None = None) -> str:
win = int(timestamp // (window_size or dht_config.window_size))
return datetime.fromtimestamp(win * (window_size or dht_config.window_size), tz=timezone.utc).strftime("%Y%m%d%H")
def fingerprint(self) -> str:
return digest_hex(self.serialize())
def serialize(self) -> bytes:
return _json_dumps(
{
"schema_version": self.schema_version,
"content_id": self.content_id,
"window_id": self.window_id,
"type": "metric",
}
)
def __str__(self) -> str:
return f"metric:{self.schema_version}:{self.content_id}:{self.window_id}"