All checks were successful
Build and Release .deb / build-deb (push) Successful in 21s
- filter_actionable_cves now marks all CVEs with 'fixable' boolean - cve_list in cache contains ALL CVEs (not just actionable ones) - CVEListScreen adds 'Corrigeable' column with 🟢/🔴 indicator - Sidebar counter still shows only actionable CVEs (cve_count)
124 lines
3.4 KiB
Python
124 lines
3.4 KiB
Python
from textual.screen import Screen
|
|
from textual.widgets import DataTable, Button
|
|
from textual.containers import Vertical, Horizontal
|
|
|
|
try:
|
|
import pyperclip
|
|
PYPERCLIP_OK = True
|
|
except Exception:
|
|
PYPERCLIP_OK = False
|
|
|
|
|
|
SCREEN_CSS = """
|
|
align: left top;
|
|
padding: 1 2;
|
|
#toolbar {
|
|
height: auto;
|
|
dock: top;
|
|
margin-bottom: 1;
|
|
}
|
|
DataTable {
|
|
height: 1fr;
|
|
border: solid $primary;
|
|
}
|
|
"""
|
|
|
|
|
|
class PackageListScreen(Screen):
|
|
BINDINGS = [("b", "back", "Retour")]
|
|
DEFAULT_CSS = """
|
|
PackageListScreen {
|
|
align: left top;
|
|
padding: 1 2;
|
|
}
|
|
PackageListScreen #toolbar {
|
|
height: auto;
|
|
margin-bottom: 1;
|
|
}
|
|
PackageListScreen DataTable {
|
|
height: 1fr;
|
|
border: solid $primary;
|
|
}
|
|
"""
|
|
|
|
def __init__(self, packages: list[dict]):
|
|
super().__init__()
|
|
self.packages = packages
|
|
|
|
def compose(self):
|
|
with Vertical():
|
|
with Horizontal(id="toolbar"):
|
|
yield Button("⬅ Retour", id="pkg-back", variant="default")
|
|
table = DataTable(id="pkg-table")
|
|
table.add_columns("Nom", "Version actuelle", "Nouvelle version", "Taille")
|
|
for pkg in self.packages:
|
|
table.add_row(pkg.get("name", "?"), pkg.get("current", "?"), pkg.get("new", "?"), pkg.get("size", "-"))
|
|
yield table
|
|
|
|
def on_button_pressed(self, event: Button.Pressed):
|
|
if event.button.id == "pkg-back":
|
|
self.app.pop_screen()
|
|
|
|
def action_back(self):
|
|
self.app.pop_screen()
|
|
|
|
|
|
class CVEListScreen(Screen):
|
|
BINDINGS = [("b", "back", "Retour")]
|
|
DEFAULT_CSS = """
|
|
CVEListScreen {
|
|
align: left top;
|
|
padding: 1 2;
|
|
}
|
|
CVEListScreen #toolbar {
|
|
height: auto;
|
|
margin-bottom: 1;
|
|
}
|
|
CVEListScreen DataTable {
|
|
height: 1fr;
|
|
border: solid $primary;
|
|
}
|
|
"""
|
|
|
|
def __init__(self, cves: list[dict]):
|
|
super().__init__()
|
|
self.cves = cves
|
|
self.urls = {}
|
|
|
|
def compose(self):
|
|
with Vertical():
|
|
with Horizontal(id="toolbar"):
|
|
yield Button("⬅ Retour", id="cve-back", variant="default")
|
|
table = DataTable(id="cve-table")
|
|
table.add_columns("CVE-ID", "Paquet", "Corrigeable", "Lien")
|
|
table.cursor_type = "row"
|
|
for i, cve in enumerate(self.cves):
|
|
cve_id = cve.get("id", "?")
|
|
pkg = cve.get("package", "?")
|
|
url = cve.get("url", "")
|
|
fixable = "🟢 Oui" if cve.get("fixable") else "🔴 Non"
|
|
self.urls[i] = url
|
|
table.add_row(cve_id, pkg, fixable, url)
|
|
yield table
|
|
|
|
def on_data_table_row_selected(self, event: DataTable.RowSelected):
|
|
row_key = event.row_key
|
|
row_index = list(self.query_one("#cve-table").rows.keys()).index(row_key)
|
|
url = self.urls.get(row_index, "")
|
|
if not url:
|
|
return
|
|
if PYPERCLIP_OK:
|
|
try:
|
|
pyperclip.copy(url)
|
|
self.notify(f"Lien copié : {url}", severity="information")
|
|
return
|
|
except Exception:
|
|
pass
|
|
self.notify(f"Lien (copie manuelle) : {url}", severity="warning")
|
|
|
|
def on_button_pressed(self, event: Button.Pressed):
|
|
if event.button.id == "cve-back":
|
|
self.app.pop_screen()
|
|
|
|
def action_back(self):
|
|
self.app.pop_screen()
|