From 435dffc0a154fd9988731ebdd18510adc70eba53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20I=C3=B1iguez=20Goia?= Date: Mon, 8 Jan 2024 19:26:17 +0100 Subject: [PATCH] ui: allow to configure refresh interval Up until now, the GUI was refreshed if: - it was not minimized or hidden. - if there were new events (even if we received events from the daemon, they were filtered out if they were duplicated). But still, there were scenarios where refreshing the views every second (more or less) was too much, like when monitoring multiple machines. Now it's possible to configure the views' refresh interval, regardless of what the daemon sends. Asked here: #1073 (cherry picked from commit 6006717b8651c2efa4108877fb74390264c72859) --- ui/opensnitch/config.py | 1 + ui/opensnitch/dialogs/preferences.py | 8 + ui/opensnitch/dialogs/stats.py | 13 +- ui/opensnitch/res/preferences.ui | 226 +++++++++++++++++++++++---- 4 files changed, 219 insertions(+), 29 deletions(-) diff --git a/ui/opensnitch/config.py b/ui/opensnitch/config.py index 168c680b8b..f5cc1f9cd0 100644 --- a/ui/opensnitch/config.py +++ b/ui/opensnitch/config.py @@ -119,6 +119,7 @@ class Config: NOTIFICATION_TYPE_SYSTEM = 0 NOTIFICATION_TYPE_QT = 1 + STATS_UPDATE_INTERVAL = "statsDialog/update_interval" STATS_GEOMETRY = "statsDialog/geometry" STATS_LAST_TAB = "statsDialog/last_tab" STATS_FILTER_TEXT = "statsDialog/general_filter_text" diff --git a/ui/opensnitch/dialogs/preferences.py b/ui/opensnitch/dialogs/preferences.py index 94f1d2dd2f..0e1b5a1eb1 100644 --- a/ui/opensnitch/dialogs/preferences.py +++ b/ui/opensnitch/dialogs/preferences.py @@ -88,6 +88,8 @@ def __init__(self, parent=None, appicon=None): self.comboUITheme.currentIndexChanged.connect(self._cb_combo_themes_changed) self.cmdTimeoutUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.SUM)) self.cmdTimeoutDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUITimeout, self.REST)) + self.cmdRefreshUIUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUIRefresh, self.SUM)) + self.cmdRefreshUIDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinUIRefresh, self.REST)) self.cmdDBMaxDaysUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.SUM)) self.cmdDBMaxDaysDown.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBMaxDays, self.REST)) self.cmdDBPurgesUp.clicked.connect(lambda: self._cb_cmd_spin_clicked(self.spinDBPurgeInterval, self.SUM)) @@ -133,6 +135,8 @@ def __init__(self, parent=None, appicon=None): self.cmdTimeoutUp.setIcon(addIcon) self.cmdTimeoutDown.setIcon(delIcon) + self.cmdRefreshUIUp.setIcon(addIcon) + self.cmdRefreshUIDown.setIcon(delIcon) self.cmdDBMaxDaysUp.setIcon(addIcon) self.cmdDBMaxDaysDown.setIcon(delIcon) self.cmdDBPurgesUp.setIcon(addIcon) @@ -260,6 +264,9 @@ def _load_settings(self): self.comboUIDuration.setCurrentIndex(self._default_duration) self.comboUIDialogPos.setCurrentIndex(self._cfg.getInt(self._cfg.DEFAULT_POPUP_POSITION)) + self._ui_refresh_interval = self._cfg.getInt(self._cfg.STATS_REFRESH_INTERVAL, 0) + self.spinUIRefresh.setValue(self._ui_refresh_interval) + self.checkAutostart.setChecked(self._autostart.isEnabled()) maxmsgsize = self._cfg.getSettings(Config.DEFAULT_SERVER_MAX_MESSAGE_LENGTH) @@ -581,6 +588,7 @@ def _save_ui_config(self): if self.checkUIRules.isChecked(): self._nodes.delete_rule_by_field(Config.DURATION_FIELD, Config.RULES_DURATION_FILTER) + self._cfg.setSettings(self._cfg.STATS_REFRESH_INTERVAL, int(self.spinUIRefresh.value())) self._cfg.setSettings(self._cfg.DEFAULT_ACTION_KEY, self.comboUIAction.currentIndex()) self._cfg.setSettings(self._cfg.DEFAULT_DURATION_KEY, int(self.comboUIDuration.currentIndex())) self._cfg.setSettings(self._cfg.DEFAULT_TARGET_KEY, self.comboUITarget.currentIndex()) diff --git a/ui/opensnitch/dialogs/stats.py b/ui/opensnitch/dialogs/stats.py index 83e04e2c4f..69b2c24025 100644 --- a/ui/opensnitch/dialogs/stats.py +++ b/ui/opensnitch/dialogs/stats.py @@ -339,6 +339,7 @@ def __init__(self, parent=None, address=None, db=None, dbname="db", appicon=None self._rules.updated.connect(self._cb_app_rules_updated) self._actions = Actions().instance() self._actions.loadAll() + self._last_update = datetime.datetime.now() # TODO: allow to display multiples dialogs self._proc_details_dialog = ProcessDetailsDialog(appicon=appicon) @@ -718,6 +719,7 @@ def _configure_buttons_icons(self): self.TABLES[idx]['cmdCleanStats'].setIcon(clearIcon) def _load_settings(self): + self._ui_refresh_interval = self._cfg.getInt(Config.STATS_REFRESH_INTERVAL, 0) dialog_geometry = self._cfg.getSettings(Config.STATS_GEOMETRY) dialog_last_tab = self._cfg.getSettings(Config.STATS_LAST_TAB) dialog_general_filter_text = self._cfg.getSettings(Config.STATS_FILTER_TEXT) @@ -2517,6 +2519,7 @@ def _get_indetail_filter_query(self, lastQuery, text): @QtCore.pyqtSlot() def _on_settings_saved(self): + self._ui_refresh_interval = self._cfg.getInt(Config.STATS_REFRESH_INTERVAL, 0) self._show_columns() self.settings_saved.emit() @@ -2699,6 +2702,13 @@ def update_interception_status(self, enabled): else: self._update_status_label(running=False, text=self.FIREWALL_DISABLED) + def _needs_refresh(self): + diff = datetime.datetime.now() - self._last_update + if diff.seconds < self._ui_refresh_interval: + return False + + return True + # launched from a thread def update(self, is_local=True, stats=None, need_query_update=True): # lock mandatory when there're multiple clients @@ -2706,8 +2716,9 @@ def update(self, is_local=True, stats=None, need_query_update=True): if stats is not None: self._stats = stats # do not update any tab if the window is not visible - if self.isVisible() and self.isMinimized() == False: + if self.isVisible() and self.isMinimized() == False and self._needs_refresh(): self._trigger.emit(is_local, need_query_update) + self._last_update = datetime.datetime.now() def update_status(self): self.startButton.setDown(self.daemon_connected) diff --git a/ui/opensnitch/res/preferences.ui b/ui/opensnitch/res/preferences.ui index a2577e8ce7..74ea72e818 100644 --- a/ui/opensnitch/res/preferences.ui +++ b/ui/opensnitch/res/preferences.ui @@ -14,13 +14,6 @@ Preferences - - - - true - - - @@ -564,7 +557,7 @@ UI - + 0 @@ -581,37 +574,37 @@ General - - - + + + - + 0 0 - Language + Refresh interval (seconds) + + + true - - + + - + 0 0 - + Theme - - - - + @@ -620,8 +613,21 @@ - - + + + + + 0 + 0 + + + + + + + + + 0 @@ -629,11 +635,14 @@ - Theme + Language - + + + + By default the GUI is started when login @@ -646,6 +655,78 @@ + + + + 0 + + + + + + 0 + 0 + + + + + + + + ../../../../../../../../../../../../../../.designer/backup../../../../../../../../../../../../../../.designer/backup + + + true + + + + + + + + 0 + 0 + + + + Qt::AlignCenter + + + QAbstractSpinBox::NoButtons + + + true + + + 100 + + + 1 + + + + + + + + 0 + 0 + + + + + + + + ../../../../../../../../../../../../../../.designer/backup../../../../../../../../../../../../../../.designer/backup + + + true + + + + + @@ -737,7 +818,9 @@ - <p>Simple: no authentication, TLS simple/mutual: use SSL certificates to authenticate nodes.</p><p>Visit the wiki for more information.</p> + <p>Simple: no authentication</p> +<p>TLS simple/mutual: use SSL certificates to authenticate nodes.</p> +<p>Visit the wiki for more information.</p> Authentication type @@ -759,7 +842,7 @@ 0 0 586 - 209 + 264 @@ -855,7 +938,7 @@ 0 0 586 - 209 + 264 @@ -1602,6 +1685,86 @@ Temporary rules will still be valid, and you can use them when prompted to allow + + + true + + + + 0 + 0 + 226 + 101 + + + + Rules + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + false + + + + 0 + 0 + + + + sha1 + + + + + + + false + + + + 0 + 0 + + + + md5 + + + true + + + + + + + + + Compute and verify binaries checksums when they try to establish new connections + + + Enable checksums verification + + + + + @@ -1932,6 +2095,13 @@ Temporary rules will still be valid, and you can use them when prompted to allow + + + + true + + +