"""Сравнение пакетов между серверами.""" import flet as ft from app.core import servers as servers_core from app.core.diff import diff_servers from app.core.ssh import SSHClient from app.ui.components import snack class DiffPage(ft.Column): def __init__(self, page: ft.Page, go): super().__init__(expand=True, scroll=ft.ScrollMode.AUTO, spacing=12) self._page = page servers = servers_core.list_servers() opts = [ft.dropdown.Option(str(s.id), s.name) for s in servers] self.dd_a = ft.Dropdown(label="Сервер A", options=opts, width=250) self.dd_b = ft.Dropdown(label="Сервер B", options=opts, width=250) self.user_only = ft.Checkbox(label="только пользовательские пакеты", value=True) self.result = ft.Column(spacing=8) self.controls = [ ft.Text("Сравнение серверов", size=28, weight=ft.FontWeight.BOLD), ft.Row([ self.dd_a, self.dd_b, self.user_only, ft.FilledButton("Сравнить", icon=ft.Icons.COMPARE_ARROWS, on_click=self._compare), ]), self.result, ] def _compare(self, e): if not self.dd_a.value or not self.dd_b.value or self.dd_a.value == self.dd_b.value: snack(self._page, "Выберите два разных сервера", error=True) return self.result.controls = [ft.ProgressBar()] self._page.update() async def _do(): a = servers_core.get_server(int(self.dd_a.value)) b = servers_core.get_server(int(self.dd_b.value)) async with SSHClient(a) as ca, SSHClient(b) as cb: diff = await diff_servers(ca, cb, self.user_only.value) self.result.controls = [ ft.Row([ self._section(f"Только на {a.name} ({len(diff.only_a)})", [f"{p.name} {p.version}" for p in diff.only_a], ft.Colors.BLUE_300), self._section(f"Только на {b.name} ({len(diff.only_b)})", [f"{p.name} {p.version}" for p in diff.only_b], ft.Colors.GREEN_300), ], vertical_alignment=ft.CrossAxisAlignment.START), ft.Text(f"Различаются версии ({len(diff.version_mismatch)})", weight=ft.FontWeight.BOLD, size=16), ft.DataTable(columns=[ ft.DataColumn(ft.Text("Пакет")), ft.DataColumn(ft.Text(a.name)), ft.DataColumn(ft.Text(b.name)), ], rows=[ ft.DataRow(cells=[ ft.DataCell(ft.Text(m.name)), ft.DataCell(ft.Text(m.version_a, size=12)), ft.DataCell(ft.Text(m.version_b, size=12, color=ft.Colors.ORANGE_300)), ]) for m in diff.version_mismatch[:100] ]) if diff.version_mismatch else ft.Text("версии совпадают", color=ft.Colors.GREY_500), ] self._page.update() self._page.run_task(_do) def _section(self, title, items, color): return ft.Container(expand=True, content=ft.Column([ ft.Text(title, weight=ft.FontWeight.BOLD, color=color), ft.Container( height=300, border=ft.Border.all(1, ft.Colors.GREY_800), border_radius=8, padding=8, content=ft.Column([ ft.Text(i, size=11, font_family="Consolas") for i in items ] or [ft.Text("—", color=ft.Colors.GREY_600)], scroll=ft.ScrollMode.AUTO, spacing=1), ), ]))