Bugs Correction
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import curses
|
||||
import re
|
||||
import textwrap
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
@@ -333,10 +334,17 @@ class SecureCheckTUI:
|
||||
|
||||
|
||||
class RunSummaryTUI:
|
||||
ANSI_RE = re.compile(r"\x1b\[[0-?]*[ -/]*[@-~]")
|
||||
|
||||
def __init__(self, results: list[TaskResult], status_items: list[StatusItem], run_log_path: str) -> None:
|
||||
self.results = results
|
||||
self.status_items = status_items
|
||||
self.run_log_path = run_log_path
|
||||
self.scroll_offset = 0
|
||||
|
||||
@classmethod
|
||||
def _clean(cls, text: str) -> str:
|
||||
return cls.ANSI_RE.sub("", text)
|
||||
|
||||
def run(self) -> None:
|
||||
curses.wrapper(self._main)
|
||||
@@ -344,48 +352,73 @@ class RunSummaryTUI:
|
||||
def _main(self, stdscr: curses.window) -> None:
|
||||
curses.curs_set(0)
|
||||
stdscr.keypad(True)
|
||||
stdscr.timeout(5000)
|
||||
_setup_colors()
|
||||
while True:
|
||||
self._draw(stdscr)
|
||||
key = stdscr.getch()
|
||||
if key == -1 or key in (ord("q"), 27, 10, 13, ord("m"), ord(" ")):
|
||||
if key in (ord("q"), 27, 10, 13, ord("m"), ord(" ")):
|
||||
return
|
||||
if key == curses.KEY_UP and self.scroll_offset > 0:
|
||||
self.scroll_offset -= 1
|
||||
elif key == curses.KEY_DOWN:
|
||||
self.scroll_offset += 1
|
||||
|
||||
def _draw(self, stdscr: curses.window) -> None:
|
||||
stdscr.erase()
|
||||
height, width = stdscr.getmaxyx()
|
||||
ok_count = sum(1 for result in self.results if result.success)
|
||||
ko_count = len(self.results) - ok_count
|
||||
self._draw_box(stdscr, 0, 1, height - 1, width - 2, "Résumé d'exécution")
|
||||
stdscr.addnstr(1, 3, f"OK: {ok_count} | ECHEC: {ko_count} | Retour menu auto dans 5s", width - 6, curses.color_pair(Palette.HEADER) | curses.A_BOLD)
|
||||
row = 3
|
||||
score_lines: list[str] = []
|
||||
notif_lines: list[str] = []
|
||||
entries: list[tuple[str, int]] = []
|
||||
entries.append((f"OK: {ok_count} | ECHEC: {ko_count} | Appuie sur une touche pour revenir", curses.color_pair(Palette.HEADER) | curses.A_BOLD))
|
||||
for result in self.results:
|
||||
if row >= height - 6:
|
||||
break
|
||||
color = curses.color_pair(Palette.SUCCESS if result.success else Palette.ERROR)
|
||||
status = "OK" if result.success else "ECHEC"
|
||||
line = f"{status:<5} {result.label} ({result.duration_seconds:.1f}s)"
|
||||
stdscr.addnstr(row, 3, line, width - 6, color | curses.A_BOLD)
|
||||
row += 1
|
||||
for detail in result.details[:2]:
|
||||
if row >= height - 6:
|
||||
break
|
||||
stdscr.addnstr(row, 6, f"- {detail}", width - 9)
|
||||
row += 1
|
||||
if result.error and row < height - 6:
|
||||
stdscr.addnstr(row, 6, f"- {result.error}", width - 9, curses.color_pair(Palette.ERROR))
|
||||
row += 1
|
||||
row += 1
|
||||
stdscr.addnstr(row, 3, "Etat synthétique:", width - 6, curses.color_pair(Palette.CATEGORY) | curses.A_BOLD)
|
||||
row += 1
|
||||
for item in self.status_items[: max(0, height - row - 2)]:
|
||||
color = curses.color_pair(Palette.SUCCESS if item.ok else Palette.ERROR)
|
||||
stdscr.addnstr(row, 3, "●", 1, color | curses.A_BOLD)
|
||||
stdscr.addnstr(row, 5, f"[{item.category}] {item.label}: {item.detail}", width - 8)
|
||||
row += 1
|
||||
stdscr.addnstr(height - 2, 3, f"Log: {self.run_log_path}", width - 6, curses.color_pair(Palette.MUTED))
|
||||
color = curses.color_pair(Palette.SUCCESS if result.success else Palette.ERROR)
|
||||
entries.append((f"{status:<4} {result.label} ({result.duration_seconds:.1f}s)", color | curses.A_BOLD))
|
||||
for detail in result.details:
|
||||
clean = self._clean(detail)
|
||||
if clean.startswith("Score Lynis") or clean.startswith("Hardening index"):
|
||||
score_lines.append(clean)
|
||||
continue
|
||||
if clean.startswith("Modifications") or clean.strip().startswith("•"):
|
||||
notif_lines.append(clean)
|
||||
continue
|
||||
wrapped = textwrap.wrap(clean, width - 9) or [""]
|
||||
for line in wrapped:
|
||||
entries.append((f" - {line}", 0))
|
||||
if result.error:
|
||||
entries.append((f" - {result.error}", curses.color_pair(Palette.ERROR)))
|
||||
if score_lines:
|
||||
entries.insert(1, ("Lynis", curses.color_pair(Palette.CATEGORY) | curses.A_BOLD))
|
||||
for idx, line in enumerate(score_lines, start=2):
|
||||
entries.insert(idx, (f" {line}", curses.color_pair(Palette.SUCCESS)))
|
||||
entries.append((("", 0)))
|
||||
entries.append(("Etat synthétique:", curses.color_pair(Palette.CATEGORY) | curses.A_BOLD))
|
||||
for item in self.status_items:
|
||||
attr = curses.color_pair(Palette.SUCCESS if item.ok else Palette.ERROR) | curses.A_BOLD
|
||||
entries.append((f"● [{item.category}] {item.label}: {item.detail}", attr))
|
||||
if notif_lines:
|
||||
entries.append((("", 0)))
|
||||
entries.append(("Modifications recommandées:", curses.color_pair(Palette.ERROR) | curses.A_BOLD))
|
||||
for line in notif_lines:
|
||||
clean = self._clean(line)
|
||||
bullet = "•" if clean.strip().startswith("•") else "-"
|
||||
entries.append((f" {bullet} {clean.lstrip('• ').strip()}", curses.color_pair(Palette.MUTED)))
|
||||
entries.append(("", 0))
|
||||
entries.append((f"Log: {self.run_log_path}", curses.color_pair(Palette.MUTED)))
|
||||
|
||||
available = height - 4
|
||||
max_offset = max(0, len(entries) - available)
|
||||
self.scroll_offset = min(max(self.scroll_offset, 0), max_offset)
|
||||
visible = entries[self.scroll_offset : self.scroll_offset + available]
|
||||
|
||||
self._draw_box(stdscr, 0, 1, height - 1, width - 2, "Résumé d'exécution")
|
||||
for idx, (line, attr) in enumerate(visible):
|
||||
stdscr.addnstr(2 + idx, 3, line, width - 6, attr)
|
||||
if max_offset:
|
||||
bar_pos = int((self.scroll_offset / max_offset) * (available - 1)) if max_offset else 0
|
||||
stdscr.addch(2 + min(bar_pos, available - 1), width - 3, curses.ACS_CKBOARD)
|
||||
def _draw_box(self, stdscr: curses.window, top: int, left: int, height: int, width: int, title: str) -> None:
|
||||
stdscr.attron(curses.color_pair(Palette.PANEL))
|
||||
stdscr.addch(top, left, curses.ACS_ULCORNER)
|
||||
|
||||
Reference in New Issue
Block a user