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 + + +