Create a TorConnectionWidget, and use that when testing settings

This commit is contained in:
Micah Lee 2021-10-20 20:33:16 -07:00
parent 0fb7d7d761
commit 3b9cc80160
No known key found for this signature in database
GPG key ID: 403C2657CD994F73
2 changed files with 160 additions and 6 deletions

View file

@ -157,6 +157,134 @@ class TorConnectionDialog(QtWidgets.QProgressDialog):
QtCore.QTimer.singleShot(1, self.cancel)
class TorConnectionWidget(QtWidgets.QWidget):
"""
Connecting to Tor widget, with a progress bar
"""
open_tor_settings = QtCore.Signal()
success = QtCore.Signal()
fail = QtCore.Signal()
def __init__(self, common):
super(TorConnectionWidget, self).__init__(None)
self.common = common
self.common.log("TorConnectionWidget", "__init__")
self.label = QtWidgets.QLabel(strings._("connecting_to_tor"))
self.label.setAlignment(QtCore.Qt.AlignHCenter)
self.progress = QtWidgets.QProgressBar()
self.progress.setRange(0, 100)
self.cancel_button = QtWidgets.QPushButton(
strings._("gui_settings_button_cancel")
)
self.cancel_button.clicked.connect(self.cancel_clicked)
progress_layout = QtWidgets.QHBoxLayout()
progress_layout.addWidget(self.progress)
progress_layout.addWidget(self.cancel_button)
inner_layout = QtWidgets.QVBoxLayout()
inner_layout.addWidget(self.label)
inner_layout.addLayout(progress_layout)
layout = QtWidgets.QHBoxLayout()
layout.addStretch()
layout.addLayout(inner_layout)
layout.addStretch()
self.setLayout(layout)
# Start displaying the status at 0
self._tor_status_update(0, "")
def start(self, custom_settings=False, testing_settings=False, onion=None):
self.common.log("TorConnectionWidget", "start")
self.was_canceled = False
self.testing_settings = testing_settings
if custom_settings:
self.settings = custom_settings
else:
self.settings = self.common.settings
if self.testing_settings:
self.onion = onion
else:
self.onion = self.common.gui.onion
t = TorConnectionThread(self.common, self.settings, self)
t.tor_status_update.connect(self._tor_status_update)
t.connected_to_tor.connect(self._connected_to_tor)
t.canceled_connecting_to_tor.connect(self._canceled_connecting_to_tor)
t.error_connecting_to_tor.connect(self._error_connecting_to_tor)
t.start()
# The main thread needs to remain active, and checking for Qt events,
# until the thread is finished. Otherwise it won't be able to handle
# accepting signals.
self.active = True
while self.active:
time.sleep(0.1)
self.common.gui.qtapp.processEvents()
def cancel_clicked(self):
self.was_canceled = True
self.fail.emit()
def wasCanceled(self):
return self.was_canceled
def _tor_status_update(self, progress, summary):
self.progress.setValue(int(progress))
self.label.setText(
f"<strong>{strings._('connecting_to_tor')}</strong><br>{summary}"
)
def _connected_to_tor(self):
self.common.log("TorConnectionWidget", "_connected_to_tor")
self.active = False
# Close the dialog after connecting
self.progress.setValue(self.progress.maximum())
self.success.emit()
def _canceled_connecting_to_tor(self):
self.common.log("TorConnectionWidget", "_canceled_connecting_to_tor")
self.active = False
self.onion.cleanup()
# Cancel connecting to Tor
QtCore.QTimer.singleShot(1, self.cancel_clicked)
def _error_connecting_to_tor(self, msg):
self.common.log("TorConnectionWidget", "_error_connecting_to_tor")
self.active = False
if self.testing_settings:
# If testing, just display the error but don't open settings
def alert():
Alert(self.common, msg, QtWidgets.QMessageBox.Warning, title=self.title)
else:
# If not testing, open settings after displaying the error
def alert():
Alert(
self.common,
f"{msg}\n\n{strings._('gui_tor_connection_error_settings')}",
QtWidgets.QMessageBox.Warning,
title=self.title,
)
# Open settings
self.open_tor_settings.emit()
QtCore.QTimer.singleShot(1, alert)
self.fail.emit()
class TorConnectionThread(QtCore.QThread):
tor_status_update = QtCore.Signal(str, str)
connected_to_tor = QtCore.Signal()

View file

@ -29,7 +29,7 @@ from onionshare_cli.onion import Onion
from . import strings
from .widgets import Alert
from .tor_connection_dialog import TorConnectionDialog
from .tor_connection_dialog import TorConnectionDialog, TorConnectionWidget
from .moat_dialog import MoatDialog
from .gui_common import GuiCommon
@ -291,6 +291,7 @@ class TorSettingsTab(QtWidgets.QWidget):
connection_type_radio_group_layout.addWidget(
self.connection_type_socket_file_radio
)
connection_type_radio_group_layout.addStretch()
connection_type_radio_group = QtWidgets.QGroupBox(
strings._("gui_settings_connection_type_label")
)
@ -311,6 +312,17 @@ class TorSettingsTab(QtWidgets.QWidget):
connection_type_layout = QtWidgets.QVBoxLayout()
connection_type_layout.addWidget(self.tor_settings_group)
connection_type_layout.addWidget(self.connection_type_bridges_radio_group)
connection_type_layout.addStretch()
# Settings are in columns
columns_layout = QtWidgets.QHBoxLayout()
columns_layout.addWidget(connection_type_radio_group)
columns_layout.addSpacing(20)
columns_layout.addLayout(connection_type_layout, stretch=1)
# Tor connection widget
self.tor_con = TorConnectionWidget(self.common)
self.tor_con.hide()
# Buttons
self.test_tor_button = QtWidgets.QPushButton(
@ -320,16 +332,19 @@ class TorSettingsTab(QtWidgets.QWidget):
self.save_button = QtWidgets.QPushButton(strings._("gui_settings_button_save"))
self.save_button.clicked.connect(self.save_clicked)
buttons_layout = QtWidgets.QHBoxLayout()
buttons_layout.addWidget(self.test_tor_button)
buttons_layout.addStretch()
buttons_layout.addWidget(self.test_tor_button)
buttons_layout.addWidget(self.save_button)
buttons_layout.addStretch()
# Layout
layout = QtWidgets.QVBoxLayout()
layout.addWidget(connection_type_radio_group)
layout.addLayout(connection_type_layout)
layout.addStretch()
layout.addLayout(columns_layout)
layout.addWidget(self.tor_con)
layout.addStretch()
layout.addLayout(buttons_layout)
layout.addStretch()
self.setLayout(layout)
@ -566,14 +581,18 @@ class TorSettingsTab(QtWidgets.QWidget):
if not settings:
return
self.test_tor_button.hide()
onion = Onion(
self.common,
use_tmp_dir=True,
get_tor_paths=self.common.gui.get_tor_paths,
)
tor_con = TorConnectionDialog(self.common, settings, True, onion)
tor_con.start()
self.tor_con.show()
self.tor_con.success.connect(self.test_tor_button_finished)
self.tor_con.fail.connect(self.test_tor_button_finished)
self.tor_con.start(settings, True, onion)
# If Tor settings worked, show results
if onion.connected_to_tor:
@ -591,6 +610,13 @@ class TorSettingsTab(QtWidgets.QWidget):
# Clean up
onion.cleanup()
def test_tor_button_finished(self):
"""
Finished testing tor connection.
"""
self.tor_con.hide()
self.test_tor_button.show()
def save_clicked(self):
"""
Save button clicked. Save current settings to disk.