diff options
Diffstat (limited to 'src/netmonitor/front/scanner_profiles_tab_pushscreens.py')
| -rw-r--r-- | src/netmonitor/front/scanner_profiles_tab_pushscreens.py | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/netmonitor/front/scanner_profiles_tab_pushscreens.py b/src/netmonitor/front/scanner_profiles_tab_pushscreens.py new file mode 100644 index 0000000..5be9941 --- /dev/null +++ b/src/netmonitor/front/scanner_profiles_tab_pushscreens.py @@ -0,0 +1,180 @@ +from textual.app import ComposeResult +from textual import on +from textual.screen import ModalScreen +from textual.widgets import Input, Button, Label, Pretty, Select, Switch +from textual.containers import Vertical, Horizontal, VerticalScroll, Container + +from ..back.scanner_profiles_manager import ScannerProfilesManager + +class ScanNowPushScreen(ModalScreen[str]): + def __init__(self, manager: ScannerProfilesManager, profile_name:str, *args, **kwargs): + super().__init__(*args, **kwargs) + self.manager = manager + self.profile_name = profile_name + + def compose(self) -> ComposeResult: + with Container(classes="modal-window large-modal"): + yield Label(f"Scanning: {self.profile_name}", classes="modal-header") + with VerticalScroll(classes="info-box"): + yield Pretty(self.manager.get_profile(self.profile_name).scan()) + with Horizontal(classes="modal-footer"): + yield Button("Close", variant="primary") + + @on(Button.Pressed) + async def on_button_pressed(self, event: Button.Pressed) -> None: + self.dismiss(None) + +class ShowProfilePushScreen(ModalScreen[str]): + def __init__(self, manager: ScannerProfilesManager, profile_name:str, *args, **kwargs): + super().__init__(*args, **kwargs) + self.manager = manager + self.profile_name = profile_name + + def compose(self) -> ComposeResult: + with Container(classes="modal-window medium-modal"): + yield Label(f"Profile: {self.profile_name}", classes="modal-header") + with VerticalScroll(classes="info-box"): + yield Pretty(self.manager.get_profile(self.profile_name).to_dict()) + with Horizontal(classes="modal-footer"): + yield Button("Close", id="cancel-button", variant="primary") + + @on(Button.Pressed) + async def on_button_pressed(self, event: Button.Pressed) -> None: + self.dismiss(None) + + +class SetSchedulerPushScreen(ModalScreen[str]): + def __init__(self, manager: ScannerProfilesManager, profile_name:str, *args, **kwargs): + super().__init__(*args, **kwargs) + self.manager = manager + self.profile_name = profile_name + + def compose(self) -> ComposeResult: + with Container(classes="modal-window small-modal"): + yield Label("Set CRON Scheduler", classes="modal-header") + yield Label("Format: min hour day month day_of_week", classes="label") + yield Input(placeholder="* * * * * ", id="cron-input", classes="input") + + with Horizontal(classes="modal-footer"): + yield Button("Confirm", id="confirm-button", variant="success") + yield Button("Cancel", id="cancel-button", variant="error") + + @on(Button.Pressed) + async def on_button_pressed(self, event: Button.Pressed): + if event.button.id == "confirm-button": + cron_input = self.query_one("#cron-input", Input).value.strip() + if cron_input: + self.manager.set_validated_scheduler(self.profile_name, cron_input) + self.dismiss(None) + else: + self.dismiss(None) + +class SetNotifacationOptionsPushScreen(ModalScreen[str]): + def __init__(self, manager: ScannerProfilesManager, profile_name:str, *args, **kwargs): + super().__init__(*args, **kwargs) + self.manager = manager + self.profile_name = profile_name + self.profile = self.manager.get_profile(profile_name) + + def compose(self) -> ComposeResult: + current_enabled = getattr(self.profile, 'notify_enabled', False) + current_cve_only = getattr(self.profile, 'notify_only_cve', False) + + with Container(classes="modal-window small-modal"): + yield Label(f"Notifications: {self.profile_name}", classes="modal-header") + + with Vertical(classes="section-card"): + yield Label("Enable notifications (Discord):") + yield Switch(value=current_enabled, id="switch-enable") + + yield Label("Notify only when scanner finds CVE") + yield Switch(value=current_cve_only, id="switch-cve-only") + + with Horizontal(classes="modal-footer"): + yield Button("Close", id="close-button", variant="primary") + + @on(Switch.Changed) + def on_switch_changed(self, event: Switch.Changed): + if event.switch.id == "switch-enable": + self.profile.notify_enabled = event.value + elif event.switch.id == "switch-cve-only": + self.profile.notify_only_cve = event.value + + self.manager.try_save_profiles(notify=False) + + @on(Button.Pressed) + async def on_button_pressed(self, event: Button.Pressed): + self.dismiss(None) + +class ShowLogsPushScreen(ModalScreen[str]): + def __init__(self, manager: ScannerProfilesManager, profile_name:str, *args, **kwargs): + super().__init__(*args, **kwargs) + self.manager = manager + self.profile_name = profile_name + self.logs = [] + + def compose(self) -> ComposeResult: + with Container(classes="modal-window large-modal"): + yield Label(f"Logs: {self.profile_name}", classes="modal-header") + + yield Select([], prompt="Select date", id="scan-date-select") + + with VerticalScroll(classes="info-box"): + yield Pretty({}, id="log-content") + + with Horizontal(classes="modal-footer"): + yield Button("Close", id="cancel-button", variant="primary") + + def on_mount(self): + self.logs = self.manager.get_profile_logs(self.profile_name) + select = self.query_one("#scan-date-select", Select) + options = [] + + if self.logs: + for index, log in enumerate(reversed(self.logs)): + real_index = len(self.logs) - 1 - index + label = log.get('_timestamp', f"Scan #{real_index + 1} (no date)") + + options.append((str(label), real_index)) + + select.set_options(options) + + if options: + select.value = options[0][1] + + @on(Select.Changed, "#scan-date-select") + def on_date_selected(self, event: Select.Changed): + if event.value is not None: + index = event.value + if index == Select.BLANK: + self.query_one("#log-content", Pretty).update({}) + return + if 0 <= index < len(self.logs): + log_entry = self.logs[index] + self.query_one("#log-content", Pretty).update(log_entry) + + @on(Button.Pressed) + async def on_button_pressed(self, event: Button.Pressed) -> None: + self.dismiss(None) + + +class ConfirmDeletePushScreen(ModalScreen[str]): + def __init__(self, manager: ScannerProfilesManager, profile_name:str, *args, **kwargs): + super().__init__(*args, **kwargs) + self.manager = manager + self.profile_name = profile_name + + def compose(self) -> ComposeResult: + with Container(classes="modal-window small-modal"): + yield Label("Are you sure?",classes="modal-header") + with Horizontal(classes="modal-footer"): + yield Button("Delete", id="confirm-button", variant="error") + yield Button("Cancel", id="cancel-button", variant="default") + + @on(Button.Pressed) + async def on_button_pressed(self, event: Button.Pressed): + if event.button.id == "confirm-button": + self.manager.delete_profile(self.profile_name) + self.dismiss(None) + else: + self.dismiss(None) |