diff --git a/cli/onionshare_cli/settings.py b/cli/onionshare_cli/settings.py
index e36c1121..473d8379 100644
--- a/cli/onionshare_cli/settings.py
+++ b/cli/onionshare_cli/settings.py
@@ -115,7 +115,6 @@ class Settings(object):
"persistent_tabs": [],
"locale": None, # this gets defined in fill_in_defaults()
"theme": 0,
- "censorship_circumvention": False,
}
self._settings = {}
self.fill_in_defaults()
diff --git a/desktop/src/onionshare/connection_tab.py b/desktop/src/onionshare/connection_tab.py
index b7381926..7c97c54a 100644
--- a/desktop/src/onionshare/connection_tab.py
+++ b/desktop/src/onionshare/connection_tab.py
@@ -20,6 +20,7 @@ along with this program. If not, see .
import json
import os
+import random
from PySide2 import QtCore, QtWidgets, QtGui
from onionshare_cli.settings import Settings
@@ -75,13 +76,15 @@ class AutoConnectTab(QtWidgets.QWidget):
# First launch widget
self.first_launch_widget = AutoConnectFirstLaunchWidget(self.common)
self.first_launch_widget.toggle_auto_connect.connect(self.toggle_auto_connect)
- self.first_launch_widget.connect_clicked.connect(self.connect_clicked)
+ self.first_launch_widget.connect_clicked.connect(
+ self.first_launch_widget_connect_clicked
+ )
self.first_launch_widget.open_tor_settings.connect(self.open_tor_settings)
self.first_launch_widget.show()
# Use bridge widget
self.use_bridge_widget = AutoConnectUseBridgeWidget(self.common)
- self.use_bridge_widget.connect_clicked.connect(self.connect_clicked)
+ self.use_bridge_widget.connect_clicked.connect(self.use_bridge_connect_clicked)
self.use_bridge_widget.back_clicked.connect(self.back_clicked)
self.use_bridge_widget.open_tor_settings.connect(self.open_tor_settings)
self.use_bridge_widget.hide()
@@ -119,7 +122,7 @@ class AutoConnectTab(QtWidgets.QWidget):
self.first_launch_widget.enable_autoconnect_checkbox.setCheckState(
QtCore.Qt.Checked
)
- self.connect_clicked()
+ self.first_launch_widget_connect_clicked()
def toggle_auto_connect(self):
"""
@@ -135,17 +138,12 @@ class AutoConnectTab(QtWidgets.QWidget):
def open_tor_settings(self):
self.parent.open_tor_settings_tab()
- def connect_clicked(self):
+ def first_launch_widget_connect_clicked(self):
"""
- Connect button clicked. Try to connect to tor.
+ Connect button in first launch widget clicked. Try to connect to tor.
"""
- self.common.log("AutoConnectTab", "connect_clicked")
-
- # Hide the buttons
- if self.first_launch_widget.isVisible():
- self.first_launch_widget.hide_buttons()
- elif self.use_bridge_widget.isVisible():
- self.use_bridge_widget.hide_buttons()
+ self.common.log("AutoConnectTab", "first_launch_widget_connect_clicked")
+ self.first_launch_widget.hide_buttons()
if not self.common.gui.local_only:
self.tor_con.show()
@@ -153,6 +151,33 @@ class AutoConnectTab(QtWidgets.QWidget):
else:
self.close_this_tab.emit()
+ def use_bridge_connect_clicked(self):
+ """
+ Connect button in use bridge widget clicked.
+ """
+ self.common.log(
+ "AutoConnectTab",
+ "use_bridge_connect_clicked",
+ "Trying to automatically obtain bridges",
+ )
+ self.use_bridge_widget.hide_buttons()
+ self.use_bridge_widget.start_autodetecting_location()
+
+ # self.common.gui.meek.start()
+ # self.censorship_circumvention = CensorshipCircumvention(
+ # self.common, self.common.gui.meek
+ # )
+ # bridge_settings = self.censorship_circumvention.request_settings(country="tm")
+ # self.common.gui.meek.cleanup()
+
+ # if bridge_settings and self.censorship_circumvention.save_settings(
+ # self.settings, bridge_settings
+ # ):
+ # # Try and connect again
+ # self.start()
+ # else:
+ # self.fail.emit()
+
def back_clicked(self):
"""
Switch from use bridge widget back to first launch widget
@@ -174,7 +199,7 @@ class AutoConnectTab(QtWidgets.QWidget):
# Close the tab
self.close_this_tab.emit()
- def tor_con_fail(self, msg):
+ def tor_con_fail(self):
"""
Finished testing tor connection.
"""
@@ -312,6 +337,11 @@ class AutoConnectUseBridgeWidget(QtWidgets.QWidget):
for country_code in countries:
self.country_combobox.addItem(countries[country_code], country_code)
+ # Task label
+ self.task_label = QtWidgets.QLabel()
+ self.task_label.setStyleSheet(common.gui.css["enable_autoconnect"])
+ self.task_label.hide()
+
# Buttons
self.connect_button = QtWidgets.QPushButton(
strings._("gui_autoconnect_bridge_start")
@@ -346,6 +376,7 @@ class AutoConnectUseBridgeWidget(QtWidgets.QWidget):
layout.addWidget(description_label)
layout.addLayout(detect_layout)
layout.addWidget(self.country_combobox)
+ layout.addWidget(self.task_label)
layout.addWidget(cta_widget)
self.setLayout(layout)
@@ -353,12 +384,39 @@ class AutoConnectUseBridgeWidget(QtWidgets.QWidget):
def hide_buttons(self):
self.connect_button.hide()
+ self.back_button.hide()
self.configure_button.hide()
def show_buttons(self):
self.connect_button.show()
+ self.back_button.show()
self.configure_button.show()
+ def start_autodetecting_location(self):
+ self.detect_automatic_radio.setEnabled(False)
+ self.detect_manual_radio.setEnabled(False)
+
+ self.country_combobox.setEnabled(False)
+ self.country_combobox.show()
+
+ # If we're automatically detecting it, randomly switch up the country
+ # dropdown until we detect the location
+ if self.detect_automatic_radio.isChecked():
+ self.task_label.show()
+ self.task_label.setText(strings._("gui_autoconnect_task_detect_location"))
+
+ self.autodetecting_timer = QtCore.QTimer()
+ self.autodetecting_timer.timeout.connect(self._autodetecting_timer_callback)
+ self.autodetecting_timer.start(200)
+
+ def stop_autodetecting_location(self):
+ self.task_label.hide()
+ self.autodetecting_timer.stop()
+
+ def _autodetecting_timer_callback(self):
+ new_index = random.randrange(0, self.country_combobox.count())
+ self.country_combobox.setCurrentIndex(new_index)
+
def _detect_automatic_toggled(self):
self.country_combobox.setEnabled(False)
self.country_combobox.hide()
diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py
index 0e0ca9d3..7c97d238 100644
--- a/desktop/src/onionshare/gui_common.py
+++ b/desktop/src/onionshare/gui_common.py
@@ -40,6 +40,7 @@ from onionshare_cli.onion import (
TorTooOldStealth,
PortNotAvailable,
)
+from onionshare_cli.meek import Meek
class GuiCommon:
@@ -78,6 +79,9 @@ class GuiCommon:
os.makedirs(self.events_dir, 0o700, True)
self.events_filename = os.path.join(self.events_dir, "events")
+ # Instantiate Meek, which is used to bypass censorship
+ self.meek = Meek(self.common, get_tor_paths=self.get_tor_paths)
+
self.css = self.get_css(qtapp.color_mode)
self.color_mode = qtapp.color_mode
@@ -185,6 +189,11 @@ class GuiCommon:
color: #666666;
}
""",
+ "autoconnect_task_label": """
+ QLabel {
+ font-weight: bold;
+ }
+ """,
# Common styles between modes and their child widgets
"mode_settings_toggle_advanced": """
QPushButton {
diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py
index e36ec53b..c7f74e4d 100644
--- a/desktop/src/onionshare/main_window.py
+++ b/desktop/src/onionshare/main_window.py
@@ -26,10 +26,10 @@ from . import strings
from .widgets import Alert
from .update_checker import UpdateThread
from .tab_widget import TabWidget
+from .settings_tab import SettingsTab
from .gui_common import GuiCommon
from .threads import OnionCleanupThread
-from onionshare_cli.meek import Meek
class MainWindow(QtWidgets.QMainWindow):
"""
@@ -53,7 +53,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.settings_action = menu.addAction(strings._("gui_settings_window_title"))
self.settings_action.triggered.connect(self.open_settings)
self.help_action = menu.addAction(strings._("gui_settings_button_help"))
- self.help_action.triggered.connect(lambda: SettingsDialog.help_clicked(self))
+ self.help_action.triggered.connect(lambda: SettingsTab.open_help())
exit_action = menu.addAction(strings._("systray_menu_exit"))
exit_action.triggered.connect(self.close)
@@ -160,23 +160,6 @@ class MainWindow(QtWidgets.QMainWindow):
self.setCentralWidget(central_widget)
self.show()
-<<<<<<< HEAD
-=======
- # Instantiate Meek, which the TorConnectionDialog may use to resolve
- # connection issues by automatically obtaining bridges.
- self.meek = Meek(self.common, get_tor_paths=self.common.gui.get_tor_paths)
- # Start the "Connecting to Tor" dialog, which calls onion.connect()
- tor_con = TorConnectionDialog(self.common, self.meek)
- tor_con.canceled.connect(self.tor_connection_canceled)
- tor_con.open_tor_settings.connect(self.tor_connection_open_tor_settings)
- if not self.common.gui.local_only:
- tor_con.start()
- self.settings_have_changed()
-
- # After connecting to Tor, check for updates
- self.check_for_updates()
-
->>>>>>> mig5-censorship_automatically_attempt_and_reconnect
# Create the close warning dialog -- the dialog widget needs to be in the constructor
# in order to test it
self.close_dialog = QtWidgets.QMessageBox()
diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json
index eeb991f4..a4780230 100644
--- a/desktop/src/onionshare/resources/locale/en.json
+++ b/desktop/src/onionshare/resources/locale/en.json
@@ -45,12 +45,13 @@
"gui_autoconnect_description": "OnionShare relies on the Tor Network, run by thousands of volunteers around the world.",
"gui_enable_autoconnect_checkbox": "Enable automatically connecting to Tor",
"gui_autoconnect_bridge_description": "Failed connecting to Tor. This could be because your internet is being censored. You might be able to bypass this censorship by using a bridge.",
- "gui_autoconnect_bridge_detect_automatic": "Automatically determine my location to bypass country-specific censorship",
+ "gui_autoconnect_bridge_detect_automatic": "Automatically determine my country to bypass country-specific censorship",
"gui_autoconnect_bridge_detect_manual": "Manually select my country",
"gui_autoconnect_start": "Connect to Tor",
"gui_autoconnect_configure": "Network Settings",
"gui_autoconnect_bridge_start": "Use a Bridge",
"gui_autoconnect_bridge_back": "Back",
+ "gui_autoconnect_task_detect_location": "Automatically determining your country...",
"gui_settings_window_title": "Settings",
"gui_settings_autoupdate_label": "Check for new version",
"gui_settings_autoupdate_option": "Notify me when a new version is available",
@@ -243,4 +244,4 @@
"moat_captcha_error": "The solution is not correct. Please try again.",
"moat_solution_empty_error": "You must enter the characters from the image",
"mode_tor_not_connected_label": "OnionShare is not connected to the Tor network"
-}
+}
\ No newline at end of file
diff --git a/desktop/src/onionshare/tab_widget.py b/desktop/src/onionshare/tab_widget.py
index ae1fe651..db139ea8 100644
--- a/desktop/src/onionshare/tab_widget.py
+++ b/desktop/src/onionshare/tab_widget.py
@@ -168,7 +168,7 @@ class TabWidget(QtWidgets.QTabWidget):
self.add_tab()
else:
self.open_connection_tab()
-
+
def check_autoconnect_tab(self):
if type(self.tabs[0]) is AutoConnectTab:
self.tabs[0].check_autoconnect()
@@ -218,7 +218,9 @@ class TabWidget(QtWidgets.QTabWidget):
self.setCurrentIndex(self.indexOf(self.tabs[tab_id]))
return
- connection_tab = AutoConnectTab(self.common, self.current_tab_id, self.status_bar, parent=self)
+ connection_tab = AutoConnectTab(
+ self.common, self.current_tab_id, self.status_bar, parent=self
+ )
connection_tab.close_this_tab.connect(self.close_connection_tab)
self.tabs[self.current_tab_id] = connection_tab
self.current_tab_id += 1
diff --git a/desktop/src/onionshare/tor_connection.py b/desktop/src/onionshare/tor_connection.py
index cb825487..fe3274a6 100644
--- a/desktop/src/onionshare/tor_connection.py
+++ b/desktop/src/onionshare/tor_connection.py
@@ -39,153 +39,9 @@ from onionshare_cli.onion import (
)
from . import strings
-from .gui_common import GuiCommon
-from .widgets import Alert
from onionshare_cli.censorship import CensorshipCircumvention
-class TorConnectionDialog(QtWidgets.QProgressDialog):
- """
- Connecting to Tor dialog.
- """
-
- open_tor_settings = QtCore.Signal()
- success = QtCore.Signal()
-
- def __init__(
- self, common, meek, custom_settings=False, testing_settings=False, onion=None
- ):
- super(TorConnectionDialog, self).__init__(None)
-
- self.common = common
- self.testing_settings = testing_settings
-
- self.meek = meek
-
- if custom_settings:
- self.settings = custom_settings
- else:
- self.settings = self.common.settings
-
- self.common.log("TorConnectionDialog", "__init__")
-
- if self.testing_settings:
- self.title = strings._("gui_settings_connection_type_test_button")
- self.onion = onion
- else:
- self.title = "OnionShare"
- self.onion = self.common.gui.onion
-
- self.setWindowTitle(self.title)
-
- self.setWindowIcon(QtGui.QIcon(GuiCommon.get_resource_path("images/logo.png")))
- self.setModal(True)
- self.setFixedSize(400, 150)
-
- # Label
- self.setLabelText(strings._("connecting_to_tor"))
-
- # Progress bar ticks from 0 to 100
- self.setRange(0, 100)
- # Don't show if connection takes less than 100ms (for non-bundled tor)
- self.setMinimumDuration(100)
-
- # Start displaying the status at 0
- self._tor_status_update(0, "")
-
- def start(self):
- self.common.log("TorConnectionDialog", "start")
-
- 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 _tor_status_update(self, progress, summary):
- self.setValue(int(progress))
- self.setLabelText(
- f"{strings._('connecting_to_tor')}
{summary}"
- )
-
- def _connected_to_tor(self):
- self.common.log("TorConnectionDialog", "_connected_to_tor")
- self.active = False
- # Close the dialog after connecting
- self.setValue(self.maximum())
-
- def _canceled_connecting_to_tor(self):
- self.common.log("TorConnectionDialog", "_canceled_connecting_to_tor")
- self.active = False
- self.onion.cleanup()
-
- # Cancel connecting to Tor
- QtCore.QTimer.singleShot(1, self.cancel)
-
- def _error_connecting_to_tor(self, msg):
- self.common.log("TorConnectionDialog", "_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)
-
- # If we are allowed to try automatically resolving connection issues
- # (e.g possible censorship) by obtaining bridges for the user, do so
- elif self.settings.get("censorship_circumvention"):
-
- def alert():
- return
-
- # Automatically try to obtain bridges from the Censorship Circumvention API
- self.common.log(
- "TorConnectionDialog",
- "_error_connecting_to_tor",
- "Trying to automatically obtain bridges",
- )
- self.meek.start()
- self.censorship_circumvention = CensorshipCircumvention(
- self.common, self.meek
- )
- bridge_settings = self.censorship_circumvention.request_settings(
- country="tm"
- )
- self.meek.cleanup()
-
- if bridge_settings and self.censorship_circumvention.save_settings(
- self.settings, bridge_settings
- ):
- # Try and connect again
- self.start()
- 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)
-
- # Cancel connecting to Tor
- QtCore.QTimer.singleShot(1, self.cancel)
-
-
class TorConnectionWidget(QtWidgets.QWidget):
"""
Connecting to Tor widget, with a progress bar
@@ -193,9 +49,9 @@ class TorConnectionWidget(QtWidgets.QWidget):
open_tor_settings = QtCore.Signal()
success = QtCore.Signal()
- fail = QtCore.Signal(str)
+ fail = QtCore.Signal()
- def __init__(self, common, status_bar, meek):
+ def __init__(self, common, status_bar):
super(TorConnectionWidget, self).__init__(None)
self.common = common
self.common.log("TorConnectionWidget", "__init__")
@@ -211,8 +67,6 @@ class TorConnectionWidget(QtWidgets.QWidget):
)
self.cancel_button.clicked.connect(self.cancel_clicked)
- self.meek = meek
-
progress_layout = QtWidgets.QHBoxLayout()
progress_layout.addWidget(self.progress)
progress_layout.addWidget(self.cancel_button)
@@ -259,7 +113,7 @@ class TorConnectionWidget(QtWidgets.QWidget):
def cancel_clicked(self):
self.was_canceled = True
- self.fail.emit("")
+ self.fail.emit()
def wasCanceled(self):
return self.was_canceled
@@ -288,44 +142,17 @@ class TorConnectionWidget(QtWidgets.QWidget):
# Cancel connecting to Tor
QtCore.QTimer.singleShot(1, self.cancel_clicked)
- def _error_connecting_to_tor(self, msg):
+ def _error_connecting_to_tor(self):
self.common.log("TorConnectionWidget", "_error_connecting_to_tor")
self.active = False
-
- # If we are allowed to try automatically resolving connection issues
- # (e.g possible censorship) by obtaining bridges for the user, do so
- if self.settings.get("censorship_circumvention"):
- # Automatically try to obtain bridges from the Censorship Circumvention API
- self.common.log(
- "TorConnectionWidget",
- "_error_connecting_to_tor",
- "Trying to automatically obtain bridges",
- )
- self.meek.start()
- self.censorship_circumvention = CensorshipCircumvention(
- self.common, self.meek
- )
- bridge_settings = self.censorship_circumvention.request_settings(
- country="tm"
- )
- self.meek.cleanup()
-
- if bridge_settings and self.censorship_circumvention.save_settings(
- self.settings, bridge_settings
- ):
- # Try and connect again
- self.start()
- else:
- self.fail.emit()
- else:
- self.fail.emit()
+ self.fail.emit()
class TorConnectionThread(QtCore.QThread):
tor_status_update = QtCore.Signal(str, str)
connected_to_tor = QtCore.Signal()
canceled_connecting_to_tor = QtCore.Signal()
- error_connecting_to_tor = QtCore.Signal(str)
+ error_connecting_to_tor = QtCore.Signal()
def __init__(self, common, settings, parent):
super(TorConnectionThread, self).__init__()
@@ -370,7 +197,7 @@ class TorConnectionThread(QtCore.QThread):
self.common.log(
"TorConnectionThread", "run", f"caught exception: {message}"
)
- self.error_connecting_to_tor.emit(message)
+ self.error_connecting_to_tor.emit()
def _tor_status_update(self, progress, summary):
self.tor_status_update.emit(progress, summary)