45 lines
1.3 KiB
Python
45 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from app.persistence import atomic_write_bytes
|
|
|
|
OTA_STATE_SCHEMA_VERSION = 1
|
|
|
|
|
|
def utc_now() -> str:
|
|
return datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")
|
|
|
|
|
|
def read_json(path: Path) -> dict[str, Any] | None:
|
|
try:
|
|
value = json.loads(Path(path).read_text(encoding="utf-8"))
|
|
except (OSError, UnicodeError, json.JSONDecodeError):
|
|
return None
|
|
return value if isinstance(value, dict) else None
|
|
|
|
|
|
def write_json(path: Path, document: dict[str, Any]) -> None:
|
|
atomic_write_bytes(
|
|
Path(path),
|
|
(json.dumps(document, ensure_ascii=False, indent=2, sort_keys=True) + "\n").encode("utf-8"),
|
|
)
|
|
|
|
|
|
def read_last_result(data_root: Path) -> dict[str, Any] | None:
|
|
document = read_json(Path(data_root) / "ota" / "state.json")
|
|
if not document or document.get("schema_version") != OTA_STATE_SCHEMA_VERSION:
|
|
return None
|
|
result = document.get("last_result")
|
|
return dict(result) if isinstance(result, dict) else None
|
|
|
|
|
|
def write_last_result(data_root: Path, result: dict[str, Any]) -> None:
|
|
write_json(
|
|
Path(data_root) / "ota" / "state.json",
|
|
{"schema_version": OTA_STATE_SCHEMA_VERSION, "last_result": dict(result)},
|
|
)
|