85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
"""CSV export/import of the device list, including AES keys."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import csv
|
|
import time
|
|
from typing import Dict, Iterable, List
|
|
|
|
from .models import Device
|
|
|
|
FIELDNAMES = [
|
|
"id",
|
|
"manufacturer",
|
|
"manufacturer_name",
|
|
"media",
|
|
"driver",
|
|
"version",
|
|
"first_seen",
|
|
"last_seen",
|
|
"count",
|
|
"rssi",
|
|
"interval_s",
|
|
"interval_samples",
|
|
"encryption",
|
|
"security_mode",
|
|
"status",
|
|
"aes_key",
|
|
]
|
|
|
|
|
|
def _fmt_time(ts: float) -> str:
|
|
if not ts:
|
|
return ""
|
|
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts))
|
|
|
|
|
|
def export_devices(path: str, devices: Iterable[Device]) -> int:
|
|
n = 0
|
|
with open(path, "w", newline="") as f:
|
|
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
|
|
writer.writeheader()
|
|
for d in devices:
|
|
writer.writerow(
|
|
{
|
|
"id": d.id,
|
|
"manufacturer": d.manufacturer,
|
|
"manufacturer_name": d.manufacturer_name,
|
|
"media": d.media,
|
|
"driver": d.driver,
|
|
"version": d.version,
|
|
"first_seen": _fmt_time(d.first_seen),
|
|
"last_seen": _fmt_time(d.last_seen),
|
|
"count": d.count,
|
|
"rssi": "" if d.rssi is None else d.rssi,
|
|
"interval_s": (
|
|
"" if d.interval_estimate is None
|
|
else round(d.interval_estimate, 1)
|
|
),
|
|
"interval_samples": d.interval_samples,
|
|
"encryption": d.encryption,
|
|
"security_mode": d.sec_mode or "",
|
|
"status": d.status,
|
|
"aes_key": d.key or "",
|
|
}
|
|
)
|
|
n += 1
|
|
return n
|
|
|
|
|
|
def import_rows(path: str) -> List[Dict[str, str]]:
|
|
"""Read a previously exported CSV. Returns a list of row dicts.
|
|
|
|
Only ``id`` is required; ``aes_key`` and the metadata columns are optional,
|
|
so hand-written key files with just ``id,aes_key`` import fine too.
|
|
"""
|
|
rows: List[Dict[str, str]] = []
|
|
with open(path, newline="") as f:
|
|
reader = csv.DictReader(f)
|
|
for row in reader:
|
|
device_id = (row.get("id") or "").strip()
|
|
if not device_id:
|
|
continue
|
|
rows.append({k: (v or "").strip() for k, v in row.items()})
|
|
return rows
|