diff options
Diffstat (limited to 'onionshare_gui/settings_dialog.py')
-rw-r--r-- | onionshare_gui/settings_dialog.py | 918 |
1 files changed, 650 insertions, 268 deletions
diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 3c0b83f4..503e53a0 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -18,7 +18,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ from PyQt5 import QtCore, QtWidgets, QtGui -import sys, platform, datetime, re +import sys +import platform +import datetime +import re +import os from onionshare import strings, common from onionshare.settings import Settings @@ -28,10 +32,12 @@ from .widgets import Alert from .update_checker import * from .tor_connection_dialog import TorConnectionDialog + class SettingsDialog(QtWidgets.QDialog): """ Settings dialog. """ + settings_saved = QtCore.pyqtSignal() def __init__(self, common, onion, qtapp, config=False, local_only=False): @@ -39,7 +45,7 @@ class SettingsDialog(QtWidgets.QDialog): self.common = common - self.common.log('SettingsDialog', '__init__') + self.common.log("SettingsDialog", "__init__") self.onion = onion self.qtapp = qtapp @@ -47,19 +53,30 @@ class SettingsDialog(QtWidgets.QDialog): self.local_only = local_only self.setModal(True) - self.setWindowTitle(strings._('gui_settings_window_title')) - self.setWindowIcon(QtGui.QIcon(self.common.get_resource_path('images/logo.png'))) + self.setWindowTitle(strings._("gui_settings_window_title")) + self.setWindowIcon( + QtGui.QIcon(self.common.get_resource_path("images/logo.png")) + ) self.system = platform.system() + # If ONIONSHARE_HIDE_TOR_SETTINGS=1, hide Tor settings in the dialog + self.hide_tor_settings = os.environ.get("ONIONSHARE_HIDE_TOR_SETTINGS") == "1" + # General settings - # Use a slug or not ('public mode') + # Use a password or not ('public mode') self.public_mode_checkbox = QtWidgets.QCheckBox() self.public_mode_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.public_mode_checkbox.setText(strings._("gui_settings_public_mode_checkbox")) - public_mode_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Public-Mode")) - public_mode_label.setStyleSheet(self.common.css['settings_whats_this']) + self.public_mode_checkbox.setText( + strings._("gui_settings_public_mode_checkbox") + ) + public_mode_label = QtWidgets.QLabel( + strings._("gui_settings_whats_this").format( + "https://github.com/micahflee/onionshare/wiki/Public-Mode" + ) + ) + public_mode_label.setStyleSheet(self.common.css["settings_whats_this"]) public_mode_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) public_mode_label.setOpenExternalLinks(True) public_mode_label.setMinimumSize(public_mode_label.sizeHint()) @@ -67,16 +84,22 @@ class SettingsDialog(QtWidgets.QDialog): public_mode_layout.addWidget(self.public_mode_checkbox) public_mode_layout.addWidget(public_mode_label) public_mode_layout.addStretch() - public_mode_layout.setContentsMargins(0,0,0,0) + public_mode_layout.setContentsMargins(0, 0, 0, 0) self.public_mode_widget = QtWidgets.QWidget() self.public_mode_widget.setLayout(public_mode_layout) # Whether or not to use an auto-start timer self.autostart_timer_checkbox = QtWidgets.QCheckBox() self.autostart_timer_checkbox.setCheckState(QtCore.Qt.Checked) - self.autostart_timer_checkbox.setText(strings._("gui_settings_autostart_timer_checkbox")) - autostart_timer_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Start-Timer")) - autostart_timer_label.setStyleSheet(self.common.css['settings_whats_this']) + self.autostart_timer_checkbox.setText( + strings._("gui_settings_autostart_timer_checkbox") + ) + autostart_timer_label = QtWidgets.QLabel( + strings._("gui_settings_whats_this").format( + "https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Start-Timer" + ) + ) + autostart_timer_label.setStyleSheet(self.common.css["settings_whats_this"]) autostart_timer_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) autostart_timer_label.setOpenExternalLinks(True) autostart_timer_label.setMinimumSize(public_mode_label.sizeHint()) @@ -84,16 +107,22 @@ class SettingsDialog(QtWidgets.QDialog): autostart_timer_layout.addWidget(self.autostart_timer_checkbox) autostart_timer_layout.addWidget(autostart_timer_label) autostart_timer_layout.addStretch() - autostart_timer_layout.setContentsMargins(0,0,0,0) + autostart_timer_layout.setContentsMargins(0, 0, 0, 0) self.autostart_timer_widget = QtWidgets.QWidget() self.autostart_timer_widget.setLayout(autostart_timer_layout) # Whether or not to use an auto-stop timer self.autostop_timer_checkbox = QtWidgets.QCheckBox() self.autostop_timer_checkbox.setCheckState(QtCore.Qt.Checked) - self.autostop_timer_checkbox.setText(strings._("gui_settings_autostop_timer_checkbox")) - autostop_timer_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Stop-Timer")) - autostop_timer_label.setStyleSheet(self.common.css['settings_whats_this']) + self.autostop_timer_checkbox.setText( + strings._("gui_settings_autostop_timer_checkbox") + ) + autostop_timer_label = QtWidgets.QLabel( + strings._("gui_settings_whats_this").format( + "https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Stop-Timer" + ) + ) + autostop_timer_label.setStyleSheet(self.common.css["settings_whats_this"]) autostop_timer_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) autostop_timer_label.setOpenExternalLinks(True) autostop_timer_label.setMinimumSize(public_mode_label.sizeHint()) @@ -101,7 +130,7 @@ class SettingsDialog(QtWidgets.QDialog): autostop_timer_layout.addWidget(self.autostop_timer_checkbox) autostop_timer_layout.addWidget(autostop_timer_label) autostop_timer_layout.addStretch() - autostop_timer_layout.setContentsMargins(0,0,0,0) + autostop_timer_layout.setContentsMargins(0, 0, 0, 0) self.autostop_timer_widget = QtWidgets.QWidget() self.autostop_timer_widget.setLayout(autostop_timer_layout) @@ -116,39 +145,59 @@ class SettingsDialog(QtWidgets.QDialog): # Onion settings # Label telling user to connect to Tor for onion service settings - self.connect_to_tor_label = QtWidgets.QLabel(strings._("gui_connect_to_tor_for_onion_settings")) - self.connect_to_tor_label.setStyleSheet(self.common.css['settings_connect_to_tor']) + self.connect_to_tor_label = QtWidgets.QLabel( + strings._("gui_connect_to_tor_for_onion_settings") + ) + self.connect_to_tor_label.setStyleSheet( + self.common.css["settings_connect_to_tor"] + ) # Whether or not to save the Onion private key for reuse (persistent URL mode) self.save_private_key_checkbox = QtWidgets.QCheckBox() self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.save_private_key_checkbox.setText(strings._("gui_save_private_key_checkbox")) - save_private_key_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Using-a-Persistent-URL")) - save_private_key_label.setStyleSheet(self.common.css['settings_whats_this']) + self.save_private_key_checkbox.setText( + strings._("gui_save_private_key_checkbox") + ) + save_private_key_label = QtWidgets.QLabel( + strings._("gui_settings_whats_this").format( + "https://github.com/micahflee/onionshare/wiki/Using-a-Persistent-URL" + ) + ) + save_private_key_label.setStyleSheet(self.common.css["settings_whats_this"]) save_private_key_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) save_private_key_label.setOpenExternalLinks(True) save_private_key_layout = QtWidgets.QHBoxLayout() save_private_key_layout.addWidget(self.save_private_key_checkbox) save_private_key_layout.addWidget(save_private_key_label) save_private_key_layout.addStretch() - save_private_key_layout.setContentsMargins(0,0,0,0) + save_private_key_layout.setContentsMargins(0, 0, 0, 0) self.save_private_key_widget = QtWidgets.QWidget() self.save_private_key_widget.setLayout(save_private_key_layout) # Whether or not to use legacy v2 onions self.use_legacy_v2_onions_checkbox = QtWidgets.QCheckBox() self.use_legacy_v2_onions_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.use_legacy_v2_onions_checkbox.setText(strings._("gui_use_legacy_v2_onions_checkbox")) - self.use_legacy_v2_onions_checkbox.clicked.connect(self.use_legacy_v2_onions_checkbox_clicked) - use_legacy_v2_onions_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Legacy-Addresses")) - use_legacy_v2_onions_label.setStyleSheet(self.common.css['settings_whats_this']) - use_legacy_v2_onions_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) + self.use_legacy_v2_onions_checkbox.setText( + strings._("gui_use_legacy_v2_onions_checkbox") + ) + self.use_legacy_v2_onions_checkbox.clicked.connect( + self.use_legacy_v2_onions_checkbox_clicked + ) + use_legacy_v2_onions_label = QtWidgets.QLabel( + strings._("gui_settings_whats_this").format( + "https://github.com/micahflee/onionshare/wiki/Legacy-Addresses" + ) + ) + use_legacy_v2_onions_label.setStyleSheet(self.common.css["settings_whats_this"]) + use_legacy_v2_onions_label.setTextInteractionFlags( + QtCore.Qt.TextBrowserInteraction + ) use_legacy_v2_onions_label.setOpenExternalLinks(True) use_legacy_v2_onions_layout = QtWidgets.QHBoxLayout() use_legacy_v2_onions_layout.addWidget(self.use_legacy_v2_onions_checkbox) use_legacy_v2_onions_layout.addWidget(use_legacy_v2_onions_label) use_legacy_v2_onions_layout.addStretch() - use_legacy_v2_onions_layout.setContentsMargins(0,0,0,0) + use_legacy_v2_onions_layout.setContentsMargins(0, 0, 0, 0) self.use_legacy_v2_onions_widget = QtWidgets.QWidget() self.use_legacy_v2_onions_widget.setLayout(use_legacy_v2_onions_layout) @@ -157,8 +206,12 @@ class SettingsDialog(QtWidgets.QDialog): self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) self.stealth_checkbox.setText(strings._("gui_settings_stealth_option")) self.stealth_checkbox.clicked.connect(self.stealth_checkbox_clicked_connect) - use_stealth_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Stealth-Onion-Services")) - use_stealth_label.setStyleSheet(self.common.css['settings_whats_this']) + use_stealth_label = QtWidgets.QLabel( + strings._("gui_settings_whats_this").format( + "https://github.com/micahflee/onionshare/wiki/Stealth-Onion-Services" + ) + ) + use_stealth_label.setStyleSheet(self.common.css["settings_whats_this"]) use_stealth_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) use_stealth_label.setOpenExternalLinks(True) use_stealth_label.setMinimumSize(use_stealth_label.sizeHint()) @@ -166,17 +219,23 @@ class SettingsDialog(QtWidgets.QDialog): use_stealth_layout.addWidget(self.stealth_checkbox) use_stealth_layout.addWidget(use_stealth_label) use_stealth_layout.addStretch() - use_stealth_layout.setContentsMargins(0,0,0,0) + use_stealth_layout.setContentsMargins(0, 0, 0, 0) self.use_stealth_widget = QtWidgets.QWidget() self.use_stealth_widget.setLayout(use_stealth_layout) - self.hidservauth_details = QtWidgets.QLabel(strings._('gui_settings_stealth_hidservauth_string')) + self.hidservauth_details = QtWidgets.QLabel( + strings._("gui_settings_stealth_hidservauth_string") + ) self.hidservauth_details.setWordWrap(True) self.hidservauth_details.setMinimumSize(self.hidservauth_details.sizeHint()) self.hidservauth_details.hide() - self.hidservauth_copy_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth')) - self.hidservauth_copy_button.clicked.connect(self.hidservauth_copy_button_clicked) + self.hidservauth_copy_button = QtWidgets.QPushButton( + strings._("gui_copy_hidservauth") + ) + self.hidservauth_copy_button.clicked.connect( + self.hidservauth_copy_button_clicked + ) self.hidservauth_copy_button.hide() # Onion settings widget @@ -197,25 +256,32 @@ class SettingsDialog(QtWidgets.QDialog): onion_group = QtWidgets.QGroupBox(strings._("gui_settings_onion_label")) onion_group.setLayout(onion_group_layout) - # Sharing options # Close after first download self.close_after_first_download_checkbox = QtWidgets.QCheckBox() self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) - self.close_after_first_download_checkbox.setText(strings._("gui_settings_close_after_first_download_option")) + self.close_after_first_download_checkbox.setText( + strings._("gui_settings_close_after_first_download_option") + ) + individual_downloads_label = QtWidgets.QLabel( + strings._("gui_settings_individual_downloads_label") + ) # Sharing options layout sharing_group_layout = QtWidgets.QVBoxLayout() sharing_group_layout.addWidget(self.close_after_first_download_checkbox) + sharing_group_layout.addWidget(individual_downloads_label) sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label")) sharing_group.setLayout(sharing_group_layout) # OnionShare data dir - data_dir_label = QtWidgets.QLabel(strings._('gui_settings_data_dir_label')); + data_dir_label = QtWidgets.QLabel(strings._("gui_settings_data_dir_label")) self.data_dir_lineedit = QtWidgets.QLineEdit() self.data_dir_lineedit.setReadOnly(True) - data_dir_button = QtWidgets.QPushButton(strings._('gui_settings_data_dir_browse_button')) + data_dir_button = QtWidgets.QPushButton( + strings._("gui_settings_data_dir_browse_button") + ) data_dir_button.clicked.connect(self.data_dir_button_clicked) data_dir_layout = QtWidgets.QHBoxLayout() data_dir_layout.addWidget(data_dir_label) @@ -228,6 +294,42 @@ class SettingsDialog(QtWidgets.QDialog): receiving_group = QtWidgets.QGroupBox(strings._("gui_settings_receiving_label")) receiving_group.setLayout(receiving_group_layout) + # Option to disable Content Security Policy (for website sharing) + self.csp_header_disabled_checkbox = QtWidgets.QCheckBox() + self.csp_header_disabled_checkbox.setCheckState(QtCore.Qt.Unchecked) + self.csp_header_disabled_checkbox.setText( + strings._("gui_settings_csp_header_disabled_option") + ) + csp_header_label = QtWidgets.QLabel( + strings._("gui_settings_whats_this").format( + "https://github.com/micahflee/onionshare/wiki/Content-Security-Policy" + ) + ) + csp_header_label.setStyleSheet(self.common.css["settings_whats_this"]) + csp_header_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) + csp_header_label.setOpenExternalLinks(True) + csp_header_label.setMinimumSize(csp_header_label.sizeHint()) + csp_header_layout = QtWidgets.QHBoxLayout() + csp_header_layout.addWidget(self.csp_header_disabled_checkbox) + csp_header_layout.addWidget(csp_header_label) + csp_header_layout.addStretch() + csp_header_layout.setContentsMargins(0, 0, 0, 0) + self.csp_header_widget = QtWidgets.QWidget() + self.csp_header_widget.setLayout(csp_header_layout) + + # Website settings widget + website_settings_layout = QtWidgets.QVBoxLayout() + website_settings_layout.setContentsMargins(0, 0, 0, 0) + website_settings_layout.addWidget(self.csp_header_widget) + self.website_settings_widget = QtWidgets.QWidget() + self.website_settings_widget.setLayout(website_settings_layout) + + # Website mode options layout + website_group_layout = QtWidgets.QVBoxLayout() + website_group_layout.addWidget(self.website_settings_widget) + website_group = QtWidgets.QGroupBox(strings._("gui_settings_website_label")) + website_group.setLayout(website_group_layout) + # Automatic updates options # Autoupdate @@ -239,7 +341,9 @@ class SettingsDialog(QtWidgets.QDialog): self.autoupdate_timestamp = QtWidgets.QLabel() # Check for updates button - self.check_for_updates_button = QtWidgets.QPushButton(strings._('gui_settings_autoupdate_check_button')) + self.check_for_updates_button = QtWidgets.QPushButton( + strings._("gui_settings_autoupdate_check_button") + ) self.check_for_updates_button.clicked.connect(self.check_for_updates) # We can't check for updates if not connected to Tor if not self.onion.connected_to_tor: @@ -250,18 +354,22 @@ class SettingsDialog(QtWidgets.QDialog): autoupdate_group_layout.addWidget(self.autoupdate_checkbox) autoupdate_group_layout.addWidget(self.autoupdate_timestamp) autoupdate_group_layout.addWidget(self.check_for_updates_button) - autoupdate_group = QtWidgets.QGroupBox(strings._("gui_settings_autoupdate_label")) + autoupdate_group = QtWidgets.QGroupBox( + strings._("gui_settings_autoupdate_label") + ) autoupdate_group.setLayout(autoupdate_group_layout) # Autoupdate is only available for Windows and Mac (Linux updates using package manager) - if self.system != 'Windows' and self.system != 'Darwin': + if self.system != "Windows" and self.system != "Darwin": autoupdate_group.hide() # Language settings language_label = QtWidgets.QLabel(strings._("gui_settings_language_label")) self.language_combobox = QtWidgets.QComboBox() # Populate the dropdown with all of OnionShare's available languages - language_names_to_locales = {v: k for k, v in self.common.settings.available_locales.items()} + language_names_to_locales = { + v: k for k, v in self.common.settings.available_locales.items() + } language_names = list(language_names_to_locales) language_names.sort() for language_name in language_names: @@ -275,56 +383,106 @@ class SettingsDialog(QtWidgets.QDialog): # Connection type: either automatic, control port, or socket file # Bundled Tor - self.connection_type_bundled_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_bundled_option')) - self.connection_type_bundled_radio.toggled.connect(self.connection_type_bundled_toggled) + self.connection_type_bundled_radio = QtWidgets.QRadioButton( + strings._("gui_settings_connection_type_bundled_option") + ) + self.connection_type_bundled_radio.toggled.connect( + self.connection_type_bundled_toggled + ) # Bundled Tor doesn't work on dev mode in Windows or Mac - if (self.system == 'Windows' or self.system == 'Darwin') and getattr(sys, 'onionshare_dev_mode', False): + if (self.system == "Windows" or self.system == "Darwin") and getattr( + sys, "onionshare_dev_mode", False + ): self.connection_type_bundled_radio.setEnabled(False) # Bridge options for bundled tor # No bridges option radio - self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_no_bridges_radio_option')) - self.tor_bridges_no_bridges_radio.toggled.connect(self.tor_bridges_no_bridges_radio_toggled) + self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton( + strings._("gui_settings_tor_bridges_no_bridges_radio_option") + ) + self.tor_bridges_no_bridges_radio.toggled.connect( + self.tor_bridges_no_bridges_radio_toggled + ) # obfs4 option radio # if the obfs4proxy binary is missing, we can't use obfs4 transports - (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = self.common.get_tor_paths() + ( + self.tor_path, + self.tor_geo_ip_file_path, + self.tor_geo_ipv6_file_path, + self.obfs4proxy_file_path, + ) = self.common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): - self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy')) + self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton( + strings._("gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy") + ) self.tor_bridges_use_obfs4_radio.setEnabled(False) else: - self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option')) - self.tor_bridges_use_obfs4_radio.toggled.connect(self.tor_bridges_use_obfs4_radio_toggled) + self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton( + strings._("gui_settings_tor_bridges_obfs4_radio_option") + ) + self.tor_bridges_use_obfs4_radio.toggled.connect( + self.tor_bridges_use_obfs4_radio_toggled + ) # meek_lite-azure option radio # if the obfs4proxy binary is missing, we can't use meek_lite-azure transports - (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = self.common.get_tor_paths() + ( + self.tor_path, + self.tor_geo_ip_file_path, + self.tor_geo_ipv6_file_path, + self.obfs4proxy_file_path, + ) = self.common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): - self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy')) + self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton( + strings._( + "gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy" + ) + ) self.tor_bridges_use_meek_lite_azure_radio.setEnabled(False) else: - self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option')) - self.tor_bridges_use_meek_lite_azure_radio.toggled.connect(self.tor_bridges_use_meek_lite_azure_radio_toggled) + self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton( + strings._("gui_settings_tor_bridges_meek_lite_azure_radio_option") + ) + self.tor_bridges_use_meek_lite_azure_radio.toggled.connect( + self.tor_bridges_use_meek_lite_azure_radio_toggled + ) # Custom bridges radio and textbox - self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_custom_radio_option')) - self.tor_bridges_use_custom_radio.toggled.connect(self.tor_bridges_use_custom_radio_toggled) - - self.tor_bridges_use_custom_label = QtWidgets.QLabel(strings._('gui_settings_tor_bridges_custom_label')) - self.tor_bridges_use_custom_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) + self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton( + strings._("gui_settings_tor_bridges_custom_radio_option") + ) + self.tor_bridges_use_custom_radio.toggled.connect( + self.tor_bridges_use_custom_radio_toggled + ) + + self.tor_bridges_use_custom_label = QtWidgets.QLabel( + strings._("gui_settings_tor_bridges_custom_label") + ) + self.tor_bridges_use_custom_label.setTextInteractionFlags( + QtCore.Qt.TextBrowserInteraction + ) self.tor_bridges_use_custom_label.setOpenExternalLinks(True) self.tor_bridges_use_custom_textbox = QtWidgets.QPlainTextEdit() self.tor_bridges_use_custom_textbox.setMaximumHeight(200) - self.tor_bridges_use_custom_textbox.setPlaceholderText('[address:port] [identifier]') + self.tor_bridges_use_custom_textbox.setPlaceholderText( + "[address:port] [identifier]" + ) tor_bridges_use_custom_textbox_options_layout = QtWidgets.QVBoxLayout() - tor_bridges_use_custom_textbox_options_layout.addWidget(self.tor_bridges_use_custom_label) - tor_bridges_use_custom_textbox_options_layout.addWidget(self.tor_bridges_use_custom_textbox) + tor_bridges_use_custom_textbox_options_layout.addWidget( + self.tor_bridges_use_custom_label + ) + tor_bridges_use_custom_textbox_options_layout.addWidget( + self.tor_bridges_use_custom_textbox + ) self.tor_bridges_use_custom_textbox_options = QtWidgets.QWidget() - self.tor_bridges_use_custom_textbox_options.setLayout(tor_bridges_use_custom_textbox_options_layout) + self.tor_bridges_use_custom_textbox_options.setLayout( + tor_bridges_use_custom_textbox_options_layout + ) self.tor_bridges_use_custom_textbox_options.hide() # Bridges layout/widget @@ -339,41 +497,73 @@ class SettingsDialog(QtWidgets.QDialog): self.bridges.setLayout(bridges_layout) # Automatic - self.connection_type_automatic_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_automatic_option')) - self.connection_type_automatic_radio.toggled.connect(self.connection_type_automatic_toggled) + self.connection_type_automatic_radio = QtWidgets.QRadioButton( + strings._("gui_settings_connection_type_automatic_option") + ) + self.connection_type_automatic_radio.toggled.connect( + self.connection_type_automatic_toggled + ) # Control port - self.connection_type_control_port_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_control_port_option')) - self.connection_type_control_port_radio.toggled.connect(self.connection_type_control_port_toggled) - - connection_type_control_port_extras_label = QtWidgets.QLabel(strings._('gui_settings_control_port_label')) + self.connection_type_control_port_radio = QtWidgets.QRadioButton( + strings._("gui_settings_connection_type_control_port_option") + ) + self.connection_type_control_port_radio.toggled.connect( + self.connection_type_control_port_toggled + ) + + connection_type_control_port_extras_label = QtWidgets.QLabel( + strings._("gui_settings_control_port_label") + ) self.connection_type_control_port_extras_address = QtWidgets.QLineEdit() self.connection_type_control_port_extras_port = QtWidgets.QLineEdit() connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout() - connection_type_control_port_extras_layout.addWidget(connection_type_control_port_extras_label) - connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_address) - connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_port) + connection_type_control_port_extras_layout.addWidget( + connection_type_control_port_extras_label + ) + connection_type_control_port_extras_layout.addWidget( + self.connection_type_control_port_extras_address + ) + connection_type_control_port_extras_layout.addWidget( + self.connection_type_control_port_extras_port + ) self.connection_type_control_port_extras = QtWidgets.QWidget() - self.connection_type_control_port_extras.setLayout(connection_type_control_port_extras_layout) + self.connection_type_control_port_extras.setLayout( + connection_type_control_port_extras_layout + ) self.connection_type_control_port_extras.hide() # Socket file - self.connection_type_socket_file_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_socket_file_option')) - self.connection_type_socket_file_radio.toggled.connect(self.connection_type_socket_file_toggled) - - connection_type_socket_file_extras_label = QtWidgets.QLabel(strings._('gui_settings_socket_file_label')) + self.connection_type_socket_file_radio = QtWidgets.QRadioButton( + strings._("gui_settings_connection_type_socket_file_option") + ) + self.connection_type_socket_file_radio.toggled.connect( + self.connection_type_socket_file_toggled + ) + + connection_type_socket_file_extras_label = QtWidgets.QLabel( + strings._("gui_settings_socket_file_label") + ) self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit() connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout() - connection_type_socket_file_extras_layout.addWidget(connection_type_socket_file_extras_label) - connection_type_socket_file_extras_layout.addWidget(self.connection_type_socket_file_extras_path) + connection_type_socket_file_extras_layout.addWidget( + connection_type_socket_file_extras_label + ) + connection_type_socket_file_extras_layout.addWidget( + self.connection_type_socket_file_extras_path + ) self.connection_type_socket_file_extras = QtWidgets.QWidget() - self.connection_type_socket_file_extras.setLayout(connection_type_socket_file_extras_layout) + self.connection_type_socket_file_extras.setLayout( + connection_type_socket_file_extras_layout + ) self.connection_type_socket_file_extras.hide() # Tor SOCKS address and port - gui_settings_socks_label = QtWidgets.QLabel(strings._('gui_settings_socks_label')) + gui_settings_socks_label = QtWidgets.QLabel( + strings._("gui_settings_socks_label") + ) self.connection_type_socks_address = QtWidgets.QLineEdit() self.connection_type_socks_port = QtWidgets.QLineEdit() connection_type_socks_layout = QtWidgets.QHBoxLayout() @@ -388,18 +578,32 @@ class SettingsDialog(QtWidgets.QDialog): # Authentication options # No authentication - self.authenticate_no_auth_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_no_auth_option')) - self.authenticate_no_auth_radio.toggled.connect(self.authenticate_no_auth_toggled) + self.authenticate_no_auth_radio = QtWidgets.QRadioButton( + strings._("gui_settings_authenticate_no_auth_option") + ) + self.authenticate_no_auth_radio.toggled.connect( + self.authenticate_no_auth_toggled + ) # Password - self.authenticate_password_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_password_option')) - self.authenticate_password_radio.toggled.connect(self.authenticate_password_toggled) - - authenticate_password_extras_label = QtWidgets.QLabel(strings._('gui_settings_password_label')) - self.authenticate_password_extras_password = QtWidgets.QLineEdit('') + self.authenticate_password_radio = QtWidgets.QRadioButton( + strings._("gui_settings_authenticate_password_option") + ) + self.authenticate_password_radio.toggled.connect( + self.authenticate_password_toggled + ) + + authenticate_password_extras_label = QtWidgets.QLabel( + strings._("gui_settings_password_label") + ) + self.authenticate_password_extras_password = QtWidgets.QLineEdit("") authenticate_password_extras_layout = QtWidgets.QHBoxLayout() - authenticate_password_extras_layout.addWidget(authenticate_password_extras_label) - authenticate_password_extras_layout.addWidget(self.authenticate_password_extras_password) + authenticate_password_extras_layout.addWidget( + authenticate_password_extras_label + ) + authenticate_password_extras_layout.addWidget( + self.authenticate_password_extras_password + ) self.authenticate_password_extras = QtWidgets.QWidget() self.authenticate_password_extras.setLayout(authenticate_password_extras_layout) @@ -410,27 +614,43 @@ class SettingsDialog(QtWidgets.QDialog): authenticate_group_layout.addWidget(self.authenticate_no_auth_radio) authenticate_group_layout.addWidget(self.authenticate_password_radio) authenticate_group_layout.addWidget(self.authenticate_password_extras) - self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label")) + self.authenticate_group = QtWidgets.QGroupBox( + strings._("gui_settings_authenticate_label") + ) self.authenticate_group.setLayout(authenticate_group_layout) # Put the radios into their own group so they are exclusive connection_type_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_radio_group_layout.addWidget(self.connection_type_bundled_radio) - connection_type_radio_group_layout.addWidget(self.connection_type_automatic_radio) - connection_type_radio_group_layout.addWidget(self.connection_type_control_port_radio) - connection_type_radio_group_layout.addWidget(self.connection_type_socket_file_radio) - connection_type_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_connection_type_label")) + connection_type_radio_group_layout.addWidget( + self.connection_type_automatic_radio + ) + connection_type_radio_group_layout.addWidget( + self.connection_type_control_port_radio + ) + connection_type_radio_group_layout.addWidget( + self.connection_type_socket_file_radio + ) + connection_type_radio_group = QtWidgets.QGroupBox( + strings._("gui_settings_connection_type_label") + ) connection_type_radio_group.setLayout(connection_type_radio_group_layout) # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges) connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_bridges_radio_group_layout.addWidget(self.bridges) - self.connection_type_bridges_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_tor_bridges")) - self.connection_type_bridges_radio_group.setLayout(connection_type_bridges_radio_group_layout) + self.connection_type_bridges_radio_group = QtWidgets.QGroupBox( + strings._("gui_settings_tor_bridges") + ) + self.connection_type_bridges_radio_group.setLayout( + connection_type_bridges_radio_group_layout + ) self.connection_type_bridges_radio_group.hide() # Test tor settings button - self.connection_type_test_button = QtWidgets.QPushButton(strings._('gui_settings_connection_type_test_button')) + self.connection_type_test_button = QtWidgets.QPushButton( + strings._("gui_settings_connection_type_test_button") + ) self.connection_type_test_button.clicked.connect(self.test_tor_clicked) connection_type_test_button_layout = QtWidgets.QHBoxLayout() connection_type_test_button_layout.addWidget(self.connection_type_test_button) @@ -446,13 +666,15 @@ class SettingsDialog(QtWidgets.QDialog): connection_type_layout.addLayout(connection_type_test_button_layout) # Buttons - self.save_button = QtWidgets.QPushButton(strings._('gui_settings_button_save')) + self.save_button = QtWidgets.QPushButton(strings._("gui_settings_button_save")) self.save_button.clicked.connect(self.save_clicked) - self.cancel_button = QtWidgets.QPushButton(strings._('gui_settings_button_cancel')) + self.cancel_button = QtWidgets.QPushButton( + strings._("gui_settings_button_cancel") + ) self.cancel_button.clicked.connect(self.cancel_clicked) - version_label = QtWidgets.QLabel('OnionShare {0:s}'.format(self.common.version)) - version_label.setStyleSheet(self.common.css['settings_version']) - self.help_button = QtWidgets.QPushButton(strings._('gui_settings_button_help')) + version_label = QtWidgets.QLabel("OnionShare {0:s}".format(self.common.version)) + version_label.setStyleSheet(self.common.css["settings_version"]) + self.help_button = QtWidgets.QPushButton(strings._("gui_settings_button_help")) self.help_button.clicked.connect(self.help_clicked) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(version_label) @@ -463,7 +685,7 @@ class SettingsDialog(QtWidgets.QDialog): # Tor network connection status self.tor_status = QtWidgets.QLabel() - self.tor_status.setStyleSheet(self.common.css['settings_tor_status']) + self.tor_status.setStyleSheet(self.common.css["settings_tor_status"]) self.tor_status.hide() # Layout @@ -472,6 +694,7 @@ class SettingsDialog(QtWidgets.QDialog): left_col_layout.addWidget(onion_group) left_col_layout.addWidget(sharing_group) left_col_layout.addWidget(receiving_group) + left_col_layout.addWidget(website_group) left_col_layout.addWidget(autoupdate_group) left_col_layout.addLayout(language_layout) left_col_layout.addStretch() @@ -484,7 +707,8 @@ class SettingsDialog(QtWidgets.QDialog): col_layout = QtWidgets.QHBoxLayout() col_layout.addLayout(left_col_layout) - col_layout.addLayout(right_col_layout) + if not self.hide_tor_settings: + col_layout.addLayout(right_col_layout) layout = QtWidgets.QVBoxLayout() layout.addLayout(col_layout) @@ -500,31 +724,37 @@ class SettingsDialog(QtWidgets.QDialog): self.old_settings = Settings(self.common, self.config) self.old_settings.load() - close_after_first_download = self.old_settings.get('close_after_first_download') + close_after_first_download = self.old_settings.get("close_after_first_download") if close_after_first_download: self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) else: self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Unchecked) - autostart_timer = self.old_settings.get('autostart_timer') + csp_header_disabled = self.old_settings.get("csp_header_disabled") + if csp_header_disabled: + self.csp_header_disabled_checkbox.setCheckState(QtCore.Qt.Checked) + else: + self.csp_header_disabled_checkbox.setCheckState(QtCore.Qt.Unchecked) + + autostart_timer = self.old_settings.get("autostart_timer") if autostart_timer: self.autostart_timer_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autostart_timer_checkbox.setCheckState(QtCore.Qt.Unchecked) - autostop_timer = self.old_settings.get('autostop_timer') + autostop_timer = self.old_settings.get("autostop_timer") if autostop_timer: self.autostop_timer_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autostop_timer_checkbox.setCheckState(QtCore.Qt.Unchecked) - save_private_key = self.old_settings.get('save_private_key') + save_private_key = self.old_settings.get("save_private_key") if save_private_key: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Checked) else: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) - use_legacy_v2_onions = self.old_settings.get('use_legacy_v2_onions') + use_legacy_v2_onions = self.old_settings.get("use_legacy_v2_onions") if use_legacy_v2_onions: self.use_legacy_v2_onions_checkbox.setCheckState(QtCore.Qt.Checked) @@ -532,84 +762,102 @@ class SettingsDialog(QtWidgets.QDialog): else: self.use_stealth_widget.hide() - data_dir = self.old_settings.get('data_dir') + data_dir = self.old_settings.get("data_dir") self.data_dir_lineedit.setText(data_dir) - public_mode = self.old_settings.get('public_mode') + public_mode = self.old_settings.get("public_mode") if public_mode: self.public_mode_checkbox.setCheckState(QtCore.Qt.Checked) else: self.public_mode_checkbox.setCheckState(QtCore.Qt.Unchecked) - use_stealth = self.old_settings.get('use_stealth') + use_stealth = self.old_settings.get("use_stealth") if use_stealth: self.stealth_checkbox.setCheckState(QtCore.Qt.Checked) # Legacy v2 mode is forced on if Stealth is enabled self.use_legacy_v2_onions_checkbox.setEnabled(False) - if save_private_key and self.old_settings.get('hidservauth_string') != "": + if save_private_key and self.old_settings.get("hidservauth_string") != "": self.hidservauth_details.show() self.hidservauth_copy_button.show() else: self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) - use_autoupdate = self.old_settings.get('use_autoupdate') + use_autoupdate = self.old_settings.get("use_autoupdate") if use_autoupdate: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) - autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp') + autoupdate_timestamp = self.old_settings.get("autoupdate_timestamp") self._update_autoupdate_timestamp(autoupdate_timestamp) - locale = self.old_settings.get('locale') + locale = self.old_settings.get("locale") locale_index = self.language_combobox.findData(QtCore.QVariant(locale)) self.language_combobox.setCurrentIndex(locale_index) - connection_type = self.old_settings.get('connection_type') - if connection_type == 'bundled': + connection_type = self.old_settings.get("connection_type") + if connection_type == "bundled": if self.connection_type_bundled_radio.isEnabled(): self.connection_type_bundled_radio.setChecked(True) else: # If bundled tor is disabled, fallback to automatic self.connection_type_automatic_radio.setChecked(True) - elif connection_type == 'automatic': + elif connection_type == "automatic": self.connection_type_automatic_radio.setChecked(True) - elif connection_type == 'control_port': + elif connection_type == "control_port": self.connection_type_control_port_radio.setChecked(True) - elif connection_type == 'socket_file': + elif connection_type == "socket_file": self.connection_type_socket_file_radio.setChecked(True) - self.connection_type_control_port_extras_address.setText(self.old_settings.get('control_port_address')) - self.connection_type_control_port_extras_port.setText(str(self.old_settings.get('control_port_port'))) - self.connection_type_socket_file_extras_path.setText(self.old_settings.get('socket_file_path')) - self.connection_type_socks_address.setText(self.old_settings.get('socks_address')) - self.connection_type_socks_port.setText(str(self.old_settings.get('socks_port'))) - auth_type = self.old_settings.get('auth_type') - if auth_type == 'no_auth': + self.connection_type_control_port_extras_address.setText( + self.old_settings.get("control_port_address") + ) + self.connection_type_control_port_extras_port.setText( + str(self.old_settings.get("control_port_port")) + ) + self.connection_type_socket_file_extras_path.setText( + self.old_settings.get("socket_file_path") + ) + self.connection_type_socks_address.setText( + self.old_settings.get("socks_address") + ) + self.connection_type_socks_port.setText( + str(self.old_settings.get("socks_port")) + ) + auth_type = self.old_settings.get("auth_type") + if auth_type == "no_auth": self.authenticate_no_auth_radio.setChecked(True) - elif auth_type == 'password': + elif auth_type == "password": self.authenticate_password_radio.setChecked(True) - self.authenticate_password_extras_password.setText(self.old_settings.get('auth_password')) + self.authenticate_password_extras_password.setText( + self.old_settings.get("auth_password") + ) - if self.old_settings.get('no_bridges'): + if self.old_settings.get("no_bridges"): self.tor_bridges_no_bridges_radio.setChecked(True) self.tor_bridges_use_obfs4_radio.setChecked(False) self.tor_bridges_use_meek_lite_azure_radio.setChecked(False) self.tor_bridges_use_custom_radio.setChecked(False) else: self.tor_bridges_no_bridges_radio.setChecked(False) - self.tor_bridges_use_obfs4_radio.setChecked(self.old_settings.get('tor_bridges_use_obfs4')) - self.tor_bridges_use_meek_lite_azure_radio.setChecked(self.old_settings.get('tor_bridges_use_meek_lite_azure')) - - if self.old_settings.get('tor_bridges_use_custom_bridges'): + self.tor_bridges_use_obfs4_radio.setChecked( + self.old_settings.get("tor_bridges_use_obfs4") + ) + self.tor_bridges_use_meek_lite_azure_radio.setChecked( + self.old_settings.get("tor_bridges_use_meek_lite_azure") + ) + + if self.old_settings.get("tor_bridges_use_custom_bridges"): self.tor_bridges_use_custom_radio.setChecked(True) # Remove the 'Bridge' lines at the start of each bridge. # They are added automatically to provide compatibility with # copying/pasting bridges provided from https://bridges.torproject.org new_bridges = [] - bridges = self.old_settings.get('tor_bridges_use_custom_bridges').split('Bridge ') + bridges = self.old_settings.get("tor_bridges_use_custom_bridges").split( + "Bridge " + ) for bridge in bridges: new_bridges.append(bridge) - new_bridges = ''.join(new_bridges) + new_bridges = "".join(new_bridges) self.tor_bridges_use_custom_textbox.setPlainText(new_bridges) # If we're connected to Tor, show onion service settings, show label if not @@ -619,22 +867,25 @@ class SettingsDialog(QtWidgets.QDialog): # If v3 onion services are supported, allow using legacy mode if self.onion.supports_v3_onions: - self.common.log('SettingsDialog', '__init__', 'v3 onions are supported') + self.common.log("SettingsDialog", "__init__", "v3 onions are supported") self.use_legacy_v2_onions_checkbox.show() else: - self.common.log('SettingsDialog', '__init__', 'v3 onions are not supported') + self.common.log( + "SettingsDialog", "__init__", "v3 onions are not supported" + ) self.use_legacy_v2_onions_widget.hide() self.use_legacy_v2_onions_checkbox_clicked(True) else: self.connect_to_tor_label.show() self.onion_settings_widget.hide() - def connection_type_bundled_toggled(self, checked): """ Connection type bundled was toggled. If checked, hide authentication fields. """ - self.common.log('SettingsDialog', 'connection_type_bundled_toggled') + self.common.log("SettingsDialog", "connection_type_bundled_toggled") + if self.hide_tor_settings: + return if checked: self.authenticate_group.hide() self.connection_type_socks.hide() @@ -644,6 +895,8 @@ class SettingsDialog(QtWidgets.QDialog): """ 'No bridges' option was toggled. If checked, enable other bridge options. """ + if self.hide_tor_settings: + return if checked: self.tor_bridges_use_custom_textbox_options.hide() @@ -651,6 +904,8 @@ class SettingsDialog(QtWidgets.QDialog): """ obfs4 bridges option was toggled. If checked, disable custom bridge options. """ + if self.hide_tor_settings: + return if checked: self.tor_bridges_use_custom_textbox_options.hide() @@ -658,16 +913,24 @@ class SettingsDialog(QtWidgets.QDialog): """ meek_lite_azure bridges option was toggled. If checked, disable custom bridge options. """ + if self.hide_tor_settings: + return if checked: self.tor_bridges_use_custom_textbox_options.hide() # Alert the user about meek's costliness if it looks like they're turning it on - if not self.old_settings.get('tor_bridges_use_meek_lite_azure'): - Alert(self.common, strings._('gui_settings_meek_lite_expensive_warning'), QtWidgets.QMessageBox.Warning) + if not self.old_settings.get("tor_bridges_use_meek_lite_azure"): + Alert( + self.common, + strings._("gui_settings_meek_lite_expensive_warning"), + QtWidgets.QMessageBox.Warning, + ) def tor_bridges_use_custom_radio_toggled(self, checked): """ Custom bridges option was toggled. If checked, show custom bridge options. """ + if self.hide_tor_settings: + return if checked: self.tor_bridges_use_custom_textbox_options.show() @@ -675,7 +938,9 @@ class SettingsDialog(QtWidgets.QDialog): """ Connection type automatic was toggled. If checked, hide authentication fields. """ - self.common.log('SettingsDialog', 'connection_type_automatic_toggled') + self.common.log("SettingsDialog", "connection_type_automatic_toggled") + if self.hide_tor_settings: + return if checked: self.authenticate_group.hide() self.connection_type_socks.hide() @@ -686,7 +951,9 @@ class SettingsDialog(QtWidgets.QDialog): Connection type control port was toggled. If checked, show extra fields for Tor control address and port. If unchecked, hide those extra fields. """ - self.common.log('SettingsDialog', 'connection_type_control_port_toggled') + self.common.log("SettingsDialog", "connection_type_control_port_toggled") + if self.hide_tor_settings: + return if checked: self.authenticate_group.show() self.connection_type_control_port_extras.show() @@ -695,13 +962,14 @@ class SettingsDialog(QtWidgets.QDialog): else: self.connection_type_control_port_extras.hide() - def connection_type_socket_file_toggled(self, checked): """ Connection type socket file was toggled. If checked, show extra fields for socket file. If unchecked, hide those extra fields. """ - self.common.log('SettingsDialog', 'connection_type_socket_file_toggled') + self.common.log("SettingsDialog", "connection_type_socket_file_toggled") + if self.hide_tor_settings: + return if checked: self.authenticate_group.show() self.connection_type_socket_file_extras.show() @@ -714,14 +982,14 @@ class SettingsDialog(QtWidgets.QDialog): """ Authentication option no authentication was toggled. """ - self.common.log('SettingsDialog', 'authenticate_no_auth_toggled') + self.common.log("SettingsDialog", "authenticate_no_auth_toggled") def authenticate_password_toggled(self, checked): """ Authentication option password was toggled. If checked, show extra fields for password auth. If unchecked, hide those extra fields. """ - self.common.log('SettingsDialog', 'authenticate_password_toggled') + self.common.log("SettingsDialog", "authenticate_password_toggled") if checked: self.authenticate_password_extras.show() else: @@ -732,9 +1000,13 @@ class SettingsDialog(QtWidgets.QDialog): Toggle the 'Copy HidServAuth' button to copy the saved HidServAuth to clipboard. """ - self.common.log('SettingsDialog', 'hidservauth_copy_button_clicked', 'HidServAuth was copied to clipboard') + self.common.log( + "SettingsDialog", + "hidservauth_copy_button_clicked", + "HidServAuth was copied to clipboard", + ) clipboard = self.qtapp.clipboard() - clipboard.setText(self.old_settings.get('hidservauth_string')) + clipboard.setText(self.old_settings.get("hidservauth_string")) def use_legacy_v2_onions_checkbox_clicked(self, checked): """ @@ -760,11 +1032,16 @@ class SettingsDialog(QtWidgets.QDialog): Browse for a new OnionShare data directory """ data_dir = self.data_dir_lineedit.text() - selected_dir = QtWidgets.QFileDialog.getExistingDirectory(self, - strings._('gui_settings_data_dir_label'), data_dir) + selected_dir = QtWidgets.QFileDialog.getExistingDirectory( + self, strings._("gui_settings_data_dir_label"), data_dir + ) if selected_dir: - self.common.log('SettingsDialog', 'data_dir_button_clicked', 'selected dir: {}'.format(selected_dir)) + self.common.log( + "SettingsDialog", + "data_dir_button_clicked", + "selected dir: {}".format(selected_dir), + ) self.data_dir_lineedit.setText(selected_dir) def test_tor_clicked(self): @@ -772,33 +1049,57 @@ class SettingsDialog(QtWidgets.QDialog): Test Tor Settings button clicked. With the given settings, see if we can successfully connect and authenticate to Tor. """ - self.common.log('SettingsDialog', 'test_tor_clicked') + self.common.log("SettingsDialog", "test_tor_clicked") settings = self.settings_from_fields() try: # Show Tor connection status if connection type is bundled tor - if settings.get('connection_type') == 'bundled': + if settings.get("connection_type") == "bundled": self.tor_status.show() self._disable_buttons() def tor_status_update_func(progress, summary): self._tor_status_update(progress, summary) return True + else: tor_status_update_func = None onion = Onion(self.common) - onion.connect(custom_settings=settings, config=self.config, tor_status_update_func=tor_status_update_func) + onion.connect( + custom_settings=settings, + config=self.config, + tor_status_update_func=tor_status_update_func, + ) # If an exception hasn't been raised yet, the Tor settings work - Alert(self.common, strings._('settings_test_success').format(onion.tor_version, onion.supports_ephemeral, onion.supports_stealth, onion.supports_v3_onions)) + Alert( + self.common, + strings._("settings_test_success").format( + onion.tor_version, + onion.supports_ephemeral, + onion.supports_stealth, + onion.supports_v3_onions, + ), + ) # Clean up onion.cleanup() - except (TorErrorInvalidSetting, TorErrorAutomatic, TorErrorSocketPort, TorErrorSocketFile, TorErrorMissingPassword, TorErrorUnreadableCookieFile, TorErrorAuthError, TorErrorProtocolError, BundledTorNotSupported, BundledTorTimeout) as e: + except ( + TorErrorInvalidSetting, + TorErrorAutomatic, + TorErrorSocketPort, + TorErrorSocketFile, + TorErrorMissingPassword, + TorErrorUnreadableCookieFile, + TorErrorAuthError, + TorErrorProtocolError, + BundledTorNotSupported, + BundledTorTimeout, + ) as e: Alert(self.common, e.args[0], QtWidgets.QMessageBox.Warning) - if settings.get('connection_type') == 'bundled': + if settings.get("connection_type") == "bundled": self.tor_status.hide() self._enable_buttons() @@ -806,7 +1107,7 @@ class SettingsDialog(QtWidgets.QDialog): """ Check for Updates button clicked. Manually force an update check. """ - self.common.log('SettingsDialog', 'check_for_updates') + self.common.log("SettingsDialog", "check_for_updates") # Disable buttons self._disable_buttons() self.qtapp.processEvents() @@ -815,7 +1116,7 @@ class SettingsDialog(QtWidgets.QDialog): # Update the last checked label settings = Settings(self.common, self.config) settings.load() - autoupdate_timestamp = settings.get('autoupdate_timestamp') + autoupdate_timestamp = settings.get("autoupdate_timestamp") self._update_autoupdate_timestamp(autoupdate_timestamp) def close_forced_update_thread(): @@ -827,22 +1128,37 @@ class SettingsDialog(QtWidgets.QDialog): # Check for updates def update_available(update_url, installed_version, latest_version): - Alert(self.common, strings._("update_available").format(update_url, installed_version, latest_version)) + Alert( + self.common, + strings._("update_available").format( + update_url, installed_version, latest_version + ), + ) close_forced_update_thread() def update_not_available(): - Alert(self.common, strings._('update_not_available')) + Alert(self.common, strings._("update_not_available")) close_forced_update_thread() def update_error(): - Alert(self.common, strings._('update_error_check_error'), QtWidgets.QMessageBox.Warning) + Alert( + self.common, + strings._("update_error_check_error"), + QtWidgets.QMessageBox.Warning, + ) close_forced_update_thread() def update_invalid_version(latest_version): - Alert(self.common, strings._('update_error_invalid_latest_version').format(latest_version), QtWidgets.QMessageBox.Warning) + Alert( + self.common, + strings._("update_error_invalid_latest_version").format(latest_version), + QtWidgets.QMessageBox.Warning, + ) close_forced_update_thread() - forced_update_thread = UpdateThread(self.common, self.onion, self.config, force=True) + forced_update_thread = UpdateThread( + self.common, self.onion, self.config, force=True + ) forced_update_thread.update_available.connect(update_available) forced_update_thread.update_not_available.connect(update_not_available) forced_update_thread.update_error.connect(update_error) @@ -853,7 +1169,7 @@ class SettingsDialog(QtWidgets.QDialog): """ Save button clicked. Save current settings to disk. """ - self.common.log('SettingsDialog', 'save_clicked') + self.common.log("SettingsDialog", "save_clicked") def changed(s1, s2, keys): """ @@ -868,13 +1184,19 @@ class SettingsDialog(QtWidgets.QDialog): settings = self.settings_from_fields() if settings: # If language changed, inform user they need to restart OnionShare - if changed(settings, self.old_settings, ['locale']): + if changed(settings, self.old_settings, ["locale"]): # Look up error message in different locale - new_locale = settings.get('locale') - if new_locale in strings.translations and 'gui_settings_language_changed_notice' in strings.translations[new_locale]: - notice = strings.translations[new_locale]['gui_settings_language_changed_notice'] + new_locale = settings.get("locale") + if ( + new_locale in strings.translations + and "gui_settings_language_changed_notice" + in strings.translations[new_locale] + ): + notice = strings.translations[new_locale][ + "gui_settings_language_changed_notice" + ] else: - notice = strings._('gui_settings_language_changed_notice') + notice = strings._("gui_settings_language_changed_notice") Alert(self.common, notice, QtWidgets.QMessageBox.Information) # Save the new settings @@ -885,33 +1207,58 @@ class SettingsDialog(QtWidgets.QDialog): reboot_onion = False if not self.local_only: if self.onion.is_authenticated(): - self.common.log('SettingsDialog', 'save_clicked', 'Connected to Tor') - - if changed(settings, self.old_settings, [ - 'connection_type', 'control_port_address', - 'control_port_port', 'socks_address', 'socks_port', - 'socket_file_path', 'auth_type', 'auth_password', - 'no_bridges', 'tor_bridges_use_obfs4', - 'tor_bridges_use_meek_lite_azure', - 'tor_bridges_use_custom_bridges']): + self.common.log( + "SettingsDialog", "save_clicked", "Connected to Tor" + ) + + if changed( + settings, + self.old_settings, + [ + "connection_type", + "control_port_address", + "control_port_port", + "socks_address", + "socks_port", + "socket_file_path", + "auth_type", + "auth_password", + "no_bridges", + "tor_bridges_use_obfs4", + "tor_bridges_use_meek_lite_azure", + "tor_bridges_use_custom_bridges", + ], + ): reboot_onion = True else: - self.common.log('SettingsDialog', 'save_clicked', 'Not connected to Tor') + self.common.log( + "SettingsDialog", "save_clicked", "Not connected to Tor" + ) # Tor isn't connected, so try connecting reboot_onion = True # Do we need to reinitialize Tor? if reboot_onion: # Reinitialize the Onion object - self.common.log('SettingsDialog', 'save_clicked', 'rebooting the Onion') + self.common.log( + "SettingsDialog", "save_clicked", "rebooting the Onion" + ) self.onion.cleanup() - tor_con = TorConnectionDialog(self.common, self.qtapp, self.onion, settings) + tor_con = TorConnectionDialog( + self.common, self.qtapp, self.onion, settings + ) tor_con.start() - self.common.log('SettingsDialog', 'save_clicked', 'Onion done rebooting, connected to Tor: {}'.format(self.onion.connected_to_tor)) + self.common.log( + "SettingsDialog", + "save_clicked", + "Onion done rebooting, connected to Tor: {}".format( + self.onion.connected_to_tor + ), + ) if self.onion.is_authenticated() and not tor_con.wasCanceled(): self.settings_saved.emit() @@ -928,9 +1275,13 @@ class SettingsDialog(QtWidgets.QDialog): """ Cancel button clicked. """ - self.common.log('SettingsDialog', 'cancel_clicked') + self.common.log("SettingsDialog", "cancel_clicked") if not self.local_only and not self.onion.is_authenticated(): - Alert(self.common, strings._('gui_tor_connection_canceled'), QtWidgets.QMessageBox.Warning) + Alert( + self.common, + strings._("gui_tor_connection_canceled"), + QtWidgets.QMessageBox.Warning, + ) sys.exit() else: self.close() @@ -939,25 +1290,31 @@ class SettingsDialog(QtWidgets.QDialog): """ Help button clicked. """ - self.common.log('SettingsDialog', 'help_clicked') + self.common.log("SettingsDialog", "help_clicked") SettingsDialog.open_help() @staticmethod def open_help(): - help_url = 'https://github.com/micahflee/onionshare/wiki' + help_url = "https://github.com/micahflee/onionshare/wiki" QtGui.QDesktopServices.openUrl(QtCore.QUrl(help_url)) def settings_from_fields(self): """ Return a Settings object that's full of values from the settings dialog. """ - self.common.log('SettingsDialog', 'settings_from_fields') + self.common.log("SettingsDialog", "settings_from_fields") settings = Settings(self.common, self.config) - settings.load() # To get the last update timestamp - - settings.set('close_after_first_download', self.close_after_first_download_checkbox.isChecked()) - settings.set('autostart_timer', self.autostart_timer_checkbox.isChecked()) - settings.set('autostop_timer', self.autostop_timer_checkbox.isChecked()) + settings.load() # To get the last update timestamp + + settings.set( + "close_after_first_download", + self.close_after_first_download_checkbox.isChecked(), + ) + settings.set( + "csp_header_disabled", self.csp_header_disabled_checkbox.isChecked() + ) + settings.set("autostart_timer", self.autostart_timer_checkbox.isChecked()) + settings.set("autostop_timer", self.autostop_timer_checkbox.isChecked()) # Complicated logic here to force v2 onion mode on or off depending on other settings if self.use_legacy_v2_onions_checkbox.isChecked(): @@ -966,142 +1323,167 @@ class SettingsDialog(QtWidgets.QDialog): use_legacy_v2_onions = False if self.save_private_key_checkbox.isChecked(): - settings.set('save_private_key', True) - settings.set('private_key', self.old_settings.get('private_key')) - settings.set('slug', self.old_settings.get('slug')) - settings.set('hidservauth_string', self.old_settings.get('hidservauth_string')) + settings.set("save_private_key", True) + settings.set("private_key", self.old_settings.get("private_key")) + settings.set("password", self.old_settings.get("password")) + settings.set( + "hidservauth_string", self.old_settings.get("hidservauth_string") + ) else: - settings.set('save_private_key', False) - settings.set('private_key', '') - settings.set('slug', '') + settings.set("save_private_key", False) + settings.set("private_key", "") + settings.set("password", "") # Also unset the HidServAuth if we are removing our reusable private key - settings.set('hidservauth_string', '') + settings.set("hidservauth_string", "") if use_legacy_v2_onions: - settings.set('use_legacy_v2_onions', True) + settings.set("use_legacy_v2_onions", True) else: - settings.set('use_legacy_v2_onions', False) + settings.set("use_legacy_v2_onions", False) - settings.set('data_dir', self.data_dir_lineedit.text()) - settings.set('public_mode', self.public_mode_checkbox.isChecked()) - settings.set('use_stealth', self.stealth_checkbox.isChecked()) + settings.set("data_dir", self.data_dir_lineedit.text()) + settings.set("public_mode", self.public_mode_checkbox.isChecked()) + settings.set("use_stealth", self.stealth_checkbox.isChecked()) # Always unset the HidServAuth if Stealth mode is unset if not self.stealth_checkbox.isChecked(): - settings.set('hidservauth_string', '') + settings.set("hidservauth_string", "") # Language locale_index = self.language_combobox.currentIndex() locale = self.language_combobox.itemData(locale_index) - settings.set('locale', locale) + settings.set("locale", locale) # Tor connection if self.connection_type_bundled_radio.isChecked(): - settings.set('connection_type', 'bundled') + settings.set("connection_type", "bundled") if self.connection_type_automatic_radio.isChecked(): - settings.set('connection_type', 'automatic') + settings.set("connection_type", "automatic") if self.connection_type_control_port_radio.isChecked(): - settings.set('connection_type', 'control_port') + settings.set("connection_type", "control_port") if self.connection_type_socket_file_radio.isChecked(): - settings.set('connection_type', 'socket_file') + settings.set("connection_type", "socket_file") if self.autoupdate_checkbox.isChecked(): - settings.set('use_autoupdate', True) + settings.set("use_autoupdate", True) else: - settings.set('use_autoupdate', False) - - settings.set('control_port_address', self.connection_type_control_port_extras_address.text()) - settings.set('control_port_port', self.connection_type_control_port_extras_port.text()) - settings.set('socket_file_path', self.connection_type_socket_file_extras_path.text()) - - settings.set('socks_address', self.connection_type_socks_address.text()) - settings.set('socks_port', self.connection_type_socks_port.text()) + settings.set("use_autoupdate", False) + + settings.set( + "control_port_address", + self.connection_type_control_port_extras_address.text(), + ) + settings.set( + "control_port_port", self.connection_type_control_port_extras_port.text() + ) + settings.set( + "socket_file_path", self.connection_type_socket_file_extras_path.text() + ) + + settings.set("socks_address", self.connection_type_socks_address.text()) + settings.set("socks_port", self.connection_type_socks_port.text()) if self.authenticate_no_auth_radio.isChecked(): - settings.set('auth_type', 'no_auth') + settings.set("auth_type", "no_auth") if self.authenticate_password_radio.isChecked(): - settings.set('auth_type', 'password') + settings.set("auth_type", "password") - settings.set('auth_password', self.authenticate_password_extras_password.text()) + settings.set("auth_password", self.authenticate_password_extras_password.text()) # Whether we use bridges if self.tor_bridges_no_bridges_radio.isChecked(): - settings.set('no_bridges', True) - settings.set('tor_bridges_use_obfs4', False) - settings.set('tor_bridges_use_meek_lite_azure', False) - settings.set('tor_bridges_use_custom_bridges', '') + settings.set("no_bridges", True) + settings.set("tor_bridges_use_obfs4", False) + settings.set("tor_bridges_use_meek_lite_azure", False) + settings.set("tor_bridges_use_custom_bridges", "") if self.tor_bridges_use_obfs4_radio.isChecked(): - settings.set('no_bridges', False) - settings.set('tor_bridges_use_obfs4', True) - settings.set('tor_bridges_use_meek_lite_azure', False) - settings.set('tor_bridges_use_custom_bridges', '') + settings.set("no_bridges", False) + settings.set("tor_bridges_use_obfs4", True) + settings.set("tor_bridges_use_meek_lite_azure", False) + settings.set("tor_bridges_use_custom_bridges", "") if self.tor_bridges_use_meek_lite_azure_radio.isChecked(): - settings.set('no_bridges', False) - settings.set('tor_bridges_use_obfs4', False) - settings.set('tor_bridges_use_meek_lite_azure', True) - settings.set('tor_bridges_use_custom_bridges', '') + settings.set("no_bridges", False) + settings.set("tor_bridges_use_obfs4", False) + settings.set("tor_bridges_use_meek_lite_azure", True) + settings.set("tor_bridges_use_custom_bridges", "") if self.tor_bridges_use_custom_radio.isChecked(): - settings.set('no_bridges', False) - settings.set('tor_bridges_use_obfs4', False) - settings.set('tor_bridges_use_meek_lite_azure', False) + settings.set("no_bridges", False) + settings.set("tor_bridges_use_obfs4", False) + settings.set("tor_bridges_use_meek_lite_azure", False) # Insert a 'Bridge' line at the start of each bridge. # This makes it easier to copy/paste a set of bridges # provided from https://bridges.torproject.org new_bridges = [] - bridges = self.tor_bridges_use_custom_textbox.toPlainText().split('\n') + bridges = self.tor_bridges_use_custom_textbox.toPlainText().split("\n") bridges_valid = False for bridge in bridges: - if bridge != '': + if bridge != "": # Check the syntax of the custom bridge to make sure it looks legitimate - ipv4_pattern = re.compile("(obfs4\s+)?(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):([0-9]+)(\s+)([A-Z0-9]+)(.+)$") - ipv6_pattern = re.compile("(obfs4\s+)?\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+\s+[A-Z0-9]+(.+)$") - meek_lite_pattern = re.compile("(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)") - if ipv4_pattern.match(bridge) or \ - ipv6_pattern.match(bridge) or \ - meek_lite_pattern.match(bridge): - new_bridges.append(''.join(['Bridge ', bridge, '\n'])) + ipv4_pattern = re.compile( + "(obfs4\s+)?(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):([0-9]+)(\s+)([A-Z0-9]+)(.+)$" + ) + ipv6_pattern = re.compile( + "(obfs4\s+)?\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+\s+[A-Z0-9]+(.+)$" + ) + meek_lite_pattern = re.compile( + "(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)" + ) + if ( + ipv4_pattern.match(bridge) + or ipv6_pattern.match(bridge) + or meek_lite_pattern.match(bridge) + ): + new_bridges.append("".join(["Bridge ", bridge, "\n"])) bridges_valid = True if bridges_valid: - new_bridges = ''.join(new_bridges) - settings.set('tor_bridges_use_custom_bridges', new_bridges) + new_bridges = "".join(new_bridges) + settings.set("tor_bridges_use_custom_bridges", new_bridges) else: - Alert(self.common, strings._('gui_settings_tor_bridges_invalid')) - settings.set('no_bridges', True) + Alert(self.common, strings._("gui_settings_tor_bridges_invalid")) + settings.set("no_bridges", True) return False return settings def closeEvent(self, e): - self.common.log('SettingsDialog', 'closeEvent') + self.common.log("SettingsDialog", "closeEvent") # On close, if Tor isn't connected, then quit OnionShare altogether if not self.local_only: if not self.onion.is_authenticated(): - self.common.log('SettingsDialog', 'closeEvent', 'Closing while not connected to Tor') + self.common.log( + "SettingsDialog", "closeEvent", "Closing while not connected to Tor" + ) # Wait 1ms for the event loop to finish, then quit QtCore.QTimer.singleShot(1, self.qtapp.quit) def _update_autoupdate_timestamp(self, autoupdate_timestamp): - self.common.log('SettingsDialog', '_update_autoupdate_timestamp') + self.common.log("SettingsDialog", "_update_autoupdate_timestamp") if autoupdate_timestamp: dt = datetime.datetime.fromtimestamp(autoupdate_timestamp) - last_checked = dt.strftime('%B %d, %Y %H:%M') + last_checked = dt.strftime("%B %d, %Y %H:%M") else: - last_checked = strings._('gui_settings_autoupdate_timestamp_never') - self.autoupdate_timestamp.setText(strings._('gui_settings_autoupdate_timestamp').format(last_checked)) + last_checked = strings._("gui_settings_autoupdate_timestamp_never") + self.autoupdate_timestamp.setText( + strings._("gui_settings_autoupdate_timestamp").format(last_checked) + ) def _tor_status_update(self, progress, summary): - self.tor_status.setText('<strong>{}</strong><br>{}% {}'.format(strings._('connecting_to_tor'), progress, summary)) + self.tor_status.setText( + "<strong>{}</strong><br>{}% {}".format( + strings._("connecting_to_tor"), progress, summary + ) + ) self.qtapp.processEvents() - if 'Done' in summary: + if "Done" in summary: self.tor_status.hide() self._enable_buttons() def _disable_buttons(self): - self.common.log('SettingsDialog', '_disable_buttons') + self.common.log("SettingsDialog", "_disable_buttons") self.check_for_updates_button.setEnabled(False) self.connection_type_test_button.setEnabled(False) @@ -1109,7 +1491,7 @@ class SettingsDialog(QtWidgets.QDialog): self.cancel_button.setEnabled(False) def _enable_buttons(self): - self.common.log('SettingsDialog', '_enable_buttons') + self.common.log("SettingsDialog", "_enable_buttons") # We can't check for updates if we're still not connected to Tor if not self.onion.connected_to_tor: self.check_for_updates_button.setEnabled(False) |