53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from collections import deque
|
|
from dataclasses import dataclass
|
|
from typing import Deque, List, Sequence
|
|
|
|
from ameba_control_panel import config
|
|
from ameba_control_panel.utils.timeutils import timestamp_ms
|
|
|
|
|
|
@dataclass
|
|
class LogLine:
|
|
text: str
|
|
direction: str # "rx", "tx", "info"
|
|
timestamp: str
|
|
|
|
def as_display(self) -> str:
|
|
return f"{self.timestamp} {self.text}"
|
|
|
|
|
|
class LogBuffer:
|
|
"""Keeps a full archive plus a bounded UI tail."""
|
|
|
|
def __init__(self, max_tail: int = config.UI_LOG_TAIL_LINES) -> None:
|
|
self._max_tail = max_tail
|
|
self._tail: Deque[LogLine] = deque(maxlen=max_tail)
|
|
self._archive: List[LogLine] = []
|
|
|
|
def append(self, text: str, direction: str) -> LogLine:
|
|
line = LogLine(text=text.rstrip("\n"), direction=direction, timestamp=timestamp_ms())
|
|
self._tail.append(line)
|
|
self._archive.append(line)
|
|
return line
|
|
|
|
def extend(self, items: Sequence[LogLine]) -> None:
|
|
for line in items:
|
|
self._tail.append(line)
|
|
self._archive.append(line)
|
|
|
|
def tail(self) -> Deque[LogLine]:
|
|
return self._tail
|
|
|
|
def archive(self) -> List[LogLine]:
|
|
return self._archive
|
|
|
|
def clear(self) -> None:
|
|
self._tail.clear()
|
|
self._archive.clear()
|
|
|
|
def as_text(self, full: bool = False) -> str:
|
|
source = self._archive if full else self._tail
|
|
return "\n".join(line.as_display() for line in source)
|