Move all of the normal onionshare logic into Tab, and make a new placeholder GUI for the main window

This commit is contained in:
Micah Lee 2019-10-20 22:08:47 -07:00
parent b8dc0551d3
commit c77db82e67
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
14 changed files with 634 additions and 574 deletions

View File

@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from onionshare import strings from onionshare import strings
from onionshare.onion import Onion
class GuiCommon: class GuiCommon:
@ -44,6 +45,9 @@ class GuiCommon:
# Load strings # Load strings
strings.load_strings(self.common) strings.load_strings(self.common)
# Start the Onion
self.onion = Onion(common)
self.css = { self.css = {
# OnionShareGui styles # OnionShareGui styles
"mode_switcher_selected_style": """ "mode_switcher_selected_style": """

View File

@ -23,18 +23,10 @@ from PyQt5 import QtCore, QtWidgets, QtGui
from onionshare import strings from onionshare import strings
from onionshare.web import Web from onionshare.web import Web
from onionshare.onion import Onion
from onionshare.onionshare import OnionShare
from .mode.share_mode import ShareMode
from .mode.receive_mode import ReceiveMode
from .mode.website_mode import WebsiteMode
from .tor_connection_dialog import TorConnectionDialog from .tor_connection_dialog import TorConnectionDialog
from .settings_dialog import SettingsDialog from .settings_dialog import SettingsDialog
from .widgets import Alert from .widgets import Alert
from .update_checker import UpdateThread from .update_checker import UpdateThread
from .server_status import ServerStatus
class MainWindow(QtWidgets.QMainWindow): class MainWindow(QtWidgets.QMainWindow):
@ -48,18 +40,9 @@ class MainWindow(QtWidgets.QMainWindow):
self.common = common self.common = common
self.common.log("MainWindow", "__init__") self.common.log("MainWindow", "__init__")
self.mode = self.common.gui.MODE_SHARE
# Start the Onion
self.onion = Onion(common)
# Start the OnionShare app
self.app = OnionShare(common, self.onion, self.common.gui.local_only)
# Initialize the window # Initialize the window
self.setMinimumWidth(820) self.setMinimumWidth(820)
self.setMinimumHeight(660) self.setMinimumHeight(660)
self.setWindowTitle("OnionShare") self.setWindowTitle("OnionShare")
self.setWindowIcon( self.setWindowIcon(
QtGui.QIcon(self.common.get_resource_path("images/logo.png")) QtGui.QIcon(self.common.get_resource_path("images/logo.png"))
@ -88,48 +71,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.system_tray.setContextMenu(menu) self.system_tray.setContextMenu(menu)
self.system_tray.show() self.system_tray.show()
# Mode switcher, to switch between share files and receive files
self.share_mode_button = QtWidgets.QPushButton(
strings._("gui_mode_share_button")
)
self.share_mode_button.setFixedHeight(50)
self.share_mode_button.clicked.connect(self.share_mode_clicked)
self.receive_mode_button = QtWidgets.QPushButton(
strings._("gui_mode_receive_button")
)
self.receive_mode_button.setFixedHeight(50)
self.receive_mode_button.clicked.connect(self.receive_mode_clicked)
self.website_mode_button = QtWidgets.QPushButton(
strings._("gui_mode_website_button")
)
self.website_mode_button.setFixedHeight(50)
self.website_mode_button.clicked.connect(self.website_mode_clicked)
self.settings_button = QtWidgets.QPushButton()
self.settings_button.setDefault(False)
self.settings_button.setFixedWidth(40)
self.settings_button.setFixedHeight(50)
self.settings_button.setIcon(
QtGui.QIcon(self.common.get_resource_path("images/settings.png"))
)
self.settings_button.clicked.connect(self.open_settings)
self.settings_button.setStyleSheet(self.common.gui.css["settings_button"])
mode_switcher_layout = QtWidgets.QHBoxLayout()
mode_switcher_layout.setSpacing(0)
mode_switcher_layout.addWidget(self.share_mode_button)
mode_switcher_layout.addWidget(self.receive_mode_button)
mode_switcher_layout.addWidget(self.website_mode_button)
mode_switcher_layout.addWidget(self.settings_button)
# Server status indicator on the status bar # Server status indicator on the status bar
self.server_status_image_stopped = QtGui.QImage(
self.common.get_resource_path("images/server_stopped.png")
)
self.server_status_image_working = QtGui.QImage(
self.common.get_resource_path("images/server_working.png")
)
self.server_status_image_started = QtGui.QImage(
self.common.get_resource_path("images/server_started.png")
)
self.server_status_image_label = QtWidgets.QLabel() self.server_status_image_label = QtWidgets.QLabel()
self.server_status_image_label.setFixedWidth(20) self.server_status_image_label.setFixedWidth(20)
self.server_status_label = QtWidgets.QLabel("") self.server_status_label = QtWidgets.QLabel("")
@ -149,300 +91,35 @@ class MainWindow(QtWidgets.QMainWindow):
self.status_bar.addPermanentWidget(self.server_status_indicator) self.status_bar.addPermanentWidget(self.server_status_indicator)
self.setStatusBar(self.status_bar) self.setStatusBar(self.status_bar)
# Share mode # Placeholder label
self.share_mode = ShareMode( label = QtWidgets.QLabel("coming soon...")
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.server_status_label,
self.system_tray,
filenames,
self.common.gui.local_only,
)
self.share_mode.init()
self.share_mode.server_status.server_started.connect(
self.update_server_status_indicator
)
self.share_mode.server_status.server_stopped.connect(
self.update_server_status_indicator
)
self.share_mode.start_server_finished.connect(
self.update_server_status_indicator
)
self.share_mode.stop_server_finished.connect(
self.update_server_status_indicator
)
self.share_mode.stop_server_finished.connect(self.stop_server_finished)
self.share_mode.start_server_finished.connect(self.clear_message)
self.share_mode.server_status.button_clicked.connect(self.clear_message)
self.share_mode.server_status.url_copied.connect(self.copy_url)
self.share_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth)
self.share_mode.set_server_active.connect(self.set_server_active)
# Receive mode
self.receive_mode = ReceiveMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.server_status_label,
self.system_tray,
None,
self.common.gui.local_only,
)
self.receive_mode.init()
self.receive_mode.server_status.server_started.connect(
self.update_server_status_indicator
)
self.receive_mode.server_status.server_stopped.connect(
self.update_server_status_indicator
)
self.receive_mode.start_server_finished.connect(
self.update_server_status_indicator
)
self.receive_mode.stop_server_finished.connect(
self.update_server_status_indicator
)
self.receive_mode.stop_server_finished.connect(self.stop_server_finished)
self.receive_mode.start_server_finished.connect(self.clear_message)
self.receive_mode.server_status.button_clicked.connect(self.clear_message)
self.receive_mode.server_status.url_copied.connect(self.copy_url)
self.receive_mode.server_status.hidservauth_copied.connect(
self.copy_hidservauth
)
self.receive_mode.set_server_active.connect(self.set_server_active)
# Website mode
self.website_mode = WebsiteMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.server_status_label,
self.system_tray,
filenames,
)
self.website_mode.init()
self.website_mode.server_status.server_started.connect(
self.update_server_status_indicator
)
self.website_mode.server_status.server_stopped.connect(
self.update_server_status_indicator
)
self.website_mode.start_server_finished.connect(
self.update_server_status_indicator
)
self.website_mode.stop_server_finished.connect(
self.update_server_status_indicator
)
self.website_mode.stop_server_finished.connect(self.stop_server_finished)
self.website_mode.start_server_finished.connect(self.clear_message)
self.website_mode.server_status.button_clicked.connect(self.clear_message)
self.website_mode.server_status.url_copied.connect(self.copy_url)
self.website_mode.server_status.hidservauth_copied.connect(
self.copy_hidservauth
)
self.website_mode.set_server_active.connect(self.set_server_active)
self.update_mode_switcher()
self.update_server_status_indicator()
# Layouts
contents_layout = QtWidgets.QVBoxLayout()
contents_layout.setContentsMargins(10, 0, 10, 0)
contents_layout.addWidget(self.receive_mode)
contents_layout.addWidget(self.share_mode)
contents_layout.addWidget(self.website_mode)
# Layout
layout = QtWidgets.QVBoxLayout() layout = QtWidgets.QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
layout.addLayout(mode_switcher_layout) layout.addWidget(label)
layout.addLayout(contents_layout)
central_widget = QtWidgets.QWidget() central_widget = QtWidgets.QWidget()
central_widget.setLayout(layout) central_widget.setLayout(layout)
self.setCentralWidget(central_widget) self.setCentralWidget(central_widget)
self.show() self.show()
# The server isn't active yet
self.set_server_active(False)
# Create the timer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.timer_callback)
# Start the "Connecting to Tor" dialog, which calls onion.connect() # Start the "Connecting to Tor" dialog, which calls onion.connect()
tor_con = TorConnectionDialog(self.common, self.common.gui.qtapp, self.onion) tor_con = TorConnectionDialog(self.common)
tor_con.canceled.connect(self._tor_connection_canceled) tor_con.canceled.connect(self.tor_connection_canceled)
tor_con.open_settings.connect(self._tor_connection_open_settings) tor_con.open_settings.connect(self.tor_connection_open_settings)
if not self.common.gui.local_only: if not self.common.gui.local_only:
tor_con.start() tor_con.start()
# Start the timer
self.timer.start(500)
# After connecting to Tor, check for updates # After connecting to Tor, check for updates
self.check_for_updates() self.check_for_updates()
def update_mode_switcher(self): def tor_connection_canceled(self):
# Based on the current mode, switch the mode switcher button styles,
# and show and hide widgets to switch modes
if self.mode == self.common.gui.MODE_SHARE:
self.share_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_selected_style"]
)
self.receive_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.website_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.receive_mode.hide()
self.share_mode.show()
self.website_mode.hide()
elif self.mode == self.common.gui.MODE_WEBSITE:
self.share_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.receive_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.website_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_selected_style"]
)
self.receive_mode.hide()
self.share_mode.hide()
self.website_mode.show()
else:
self.share_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.receive_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_selected_style"]
)
self.website_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.share_mode.hide()
self.receive_mode.show()
self.website_mode.hide()
self.update_server_status_indicator()
def share_mode_clicked(self):
if self.mode != self.common.gui.MODE_SHARE:
self.common.log("MainWindow", "share_mode_clicked")
self.mode = self.common.gui.MODE_SHARE
self.update_mode_switcher()
def receive_mode_clicked(self):
if self.mode != self.common.gui.MODE_RECEIVE:
self.common.log("MainWindow", "receive_mode_clicked")
self.mode = self.common.gui.MODE_RECEIVE
self.update_mode_switcher()
def website_mode_clicked(self):
if self.mode != self.common.gui.MODE_WEBSITE:
self.common.log("MainWindow", "website_mode_clicked")
self.mode = self.common.gui.MODE_WEBSITE
self.update_mode_switcher()
def update_server_status_indicator(self):
# Set the status image
if self.mode == self.common.gui.MODE_SHARE:
# Share mode
if self.share_mode.server_status.status == ServerStatus.STATUS_STOPPED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_stopped)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_stopped")
)
elif self.share_mode.server_status.status == ServerStatus.STATUS_WORKING:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_working)
)
if self.share_mode.server_status.autostart_timer_datetime:
self.server_status_label.setText(
strings._("gui_status_indicator_share_scheduled")
)
else:
self.server_status_label.setText(
strings._("gui_status_indicator_share_working")
)
elif self.share_mode.server_status.status == ServerStatus.STATUS_STARTED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_started)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_started")
)
elif self.mode == self.common.gui.MODE_WEBSITE:
# Website mode
if self.website_mode.server_status.status == ServerStatus.STATUS_STOPPED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_stopped)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_stopped")
)
elif self.website_mode.server_status.status == ServerStatus.STATUS_WORKING:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_working)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_working")
)
elif self.website_mode.server_status.status == ServerStatus.STATUS_STARTED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_started)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_started")
)
else:
# Receive mode
if self.receive_mode.server_status.status == ServerStatus.STATUS_STOPPED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_stopped)
)
self.server_status_label.setText(
strings._("gui_status_indicator_receive_stopped")
)
elif self.receive_mode.server_status.status == ServerStatus.STATUS_WORKING:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_working)
)
if self.receive_mode.server_status.autostart_timer_datetime:
self.server_status_label.setText(
strings._("gui_status_indicator_receive_scheduled")
)
else:
self.server_status_label.setText(
strings._("gui_status_indicator_receive_working")
)
elif self.receive_mode.server_status.status == ServerStatus.STATUS_STARTED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_started)
)
self.server_status_label.setText(
strings._("gui_status_indicator_receive_started")
)
def stop_server_finished(self):
# When the server stopped, cleanup the ephemeral onion service
self.onion.cleanup(stop_tor=False)
def _tor_connection_canceled(self):
""" """
If the user cancels before Tor finishes connecting, ask if they want to If the user cancels before Tor finishes connecting, ask if they want to
quit, or open settings. quit, or open settings.
""" """
self.common.log("MainWindow", "_tor_connection_canceled") self.common.log("MainWindow", "tor_connection_canceled")
def ask(): def ask():
a = Alert( a = Alert(
@ -484,11 +161,11 @@ class MainWindow(QtWidgets.QMainWindow):
# Wait 100ms before asking # Wait 100ms before asking
QtCore.QTimer.singleShot(100, ask) QtCore.QTimer.singleShot(100, ask)
def _tor_connection_open_settings(self): def tor_connection_open_settings(self):
""" """
The TorConnectionDialog wants to open the Settings dialog The TorConnectionDialog wants to open the Settings dialog
""" """
self.common.log("MainWindow", "_tor_connection_open_settings") self.common.log("MainWindow", "tor_connection_open_settings")
# Wait 1ms for the event loop to finish closing the TorConnectionDialog # Wait 1ms for the event loop to finish closing the TorConnectionDialog
QtCore.QTimer.singleShot(1, self.open_settings) QtCore.QTimer.singleShot(1, self.open_settings)
@ -509,7 +186,7 @@ class MainWindow(QtWidgets.QMainWindow):
# If we've reloaded settings, we probably succeeded in obtaining a new # If we've reloaded settings, we probably succeeded in obtaining a new
# connection. If so, restart the timer. # connection. If so, restart the timer.
if not self.common.gui.local_only: if not self.common.gui.local_only:
if self.onion.is_authenticated(): if self.common.gui.onion.is_authenticated():
if not self.timer.isActive(): if not self.timer.isActive():
self.timer.start(500) self.timer.start(500)
self.share_mode.on_reload_settings() self.share_mode.on_reload_settings()
@ -531,13 +208,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.receive_mode.server_status.autostart_timer_container.hide() self.receive_mode.server_status.autostart_timer_container.hide()
self.website_mode.server_status.autostart_timer_container.hide() self.website_mode.server_status.autostart_timer_container.hide()
d = SettingsDialog( d = SettingsDialog(self.common)
self.common,
self.onion,
self.common.gui.qtapp,
self.common.gui.config,
self.common.gui.local_only,
)
d.settings_saved.connect(reload_settings) d.settings_saved.connect(reload_settings)
d.exec_() d.exec_()
@ -562,203 +233,17 @@ class MainWindow(QtWidgets.QMainWindow):
) )
self.update_thread = UpdateThread( self.update_thread = UpdateThread(
self.common, self.onion, self.common.gui.config self.common, self.common.gui.onion, self.common.gui.config
) )
self.update_thread.update_available.connect(update_available) self.update_thread.update_available.connect(update_available)
self.update_thread.start() self.update_thread.start()
def timer_callback(self):
"""
Check for messages communicated from the web app, and update the GUI accordingly. Also,
call ShareMode and ReceiveMode's timer_callbacks.
"""
self.update()
if not self.common.gui.local_only:
# Have we lost connection to Tor somehow?
if not self.onion.is_authenticated():
self.timer.stop()
self.status_bar.showMessage(strings._("gui_tor_connection_lost"))
self.system_tray.showMessage(
strings._("gui_tor_connection_lost"),
strings._("gui_tor_connection_error_settings"),
)
self.share_mode.handle_tor_broke()
self.receive_mode.handle_tor_broke()
self.website_mode.handle_tor_broke()
# Process events from the web object
if self.mode == self.common.gui.MODE_SHARE:
mode = self.share_mode
elif self.mode == self.common.gui.MODE_WEBSITE:
mode = self.website_mode
else:
mode = self.receive_mode
events = []
done = False
while not done:
try:
r = mode.web.q.get(False)
events.append(r)
except queue.Empty:
done = True
for event in events:
if event["type"] == Web.REQUEST_LOAD:
mode.handle_request_load(event)
elif event["type"] == Web.REQUEST_STARTED:
mode.handle_request_started(event)
elif event["type"] == Web.REQUEST_RATE_LIMIT:
mode.handle_request_rate_limit(event)
elif event["type"] == Web.REQUEST_PROGRESS:
mode.handle_request_progress(event)
elif event["type"] == Web.REQUEST_CANCELED:
mode.handle_request_canceled(event)
elif event["type"] == Web.REQUEST_UPLOAD_FILE_RENAMED:
mode.handle_request_upload_file_renamed(event)
elif event["type"] == Web.REQUEST_UPLOAD_SET_DIR:
mode.handle_request_upload_set_dir(event)
elif event["type"] == Web.REQUEST_UPLOAD_FINISHED:
mode.handle_request_upload_finished(event)
elif event["type"] == Web.REQUEST_UPLOAD_CANCELED:
mode.handle_request_upload_canceled(event)
elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_STARTED:
mode.handle_request_individual_file_started(event)
elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_PROGRESS:
mode.handle_request_individual_file_progress(event)
elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_CANCELED:
mode.handle_request_individual_file_canceled(event)
if event["type"] == Web.REQUEST_ERROR_DATA_DIR_CANNOT_CREATE:
Alert(
self.common,
strings._("error_cannot_create_data_dir").format(
event["data"]["receive_mode_dir"]
),
)
if event["type"] == Web.REQUEST_OTHER:
if (
event["path"] != "/favicon.ico"
and event["path"] != f"/{mode.web.shutdown_password}/shutdown"
):
self.status_bar.showMessage(
f"{strings._('other_page_loaded')}: {event['path']}"
)
if event["type"] == Web.REQUEST_INVALID_PASSWORD:
self.status_bar.showMessage(
f"[#{mode.web.invalid_passwords_count}] {strings._('incorrect_password')}: {event['data']}"
)
mode.timer_callback()
def copy_url(self):
"""
When the URL gets copied to the clipboard, display this in the status bar.
"""
self.common.log("MainWindow", "copy_url")
self.system_tray.showMessage(
strings._("gui_copied_url_title"), strings._("gui_copied_url")
)
def copy_hidservauth(self):
"""
When the stealth onion service HidServAuth gets copied to the clipboard, display this in the status bar.
"""
self.common.log("MainWindow", "copy_hidservauth")
self.system_tray.showMessage(
strings._("gui_copied_hidservauth_title"),
strings._("gui_copied_hidservauth"),
)
def clear_message(self):
"""
Clear messages from the status bar.
"""
self.status_bar.clearMessage()
def set_server_active(self, active):
"""
Disable the Settings and Receive Files buttons while an Share Files server is active.
"""
if active:
self.settings_button.hide()
if self.mode == self.common.gui.MODE_SHARE:
self.share_mode_button.show()
self.receive_mode_button.hide()
self.website_mode_button.hide()
elif self.mode == self.common.gui.MODE_WEBSITE:
self.share_mode_button.hide()
self.receive_mode_button.hide()
self.website_mode_button.show()
else:
self.share_mode_button.hide()
self.receive_mode_button.show()
self.website_mode_button.hide()
else:
self.settings_button.show()
self.share_mode_button.show()
self.receive_mode_button.show()
self.website_mode_button.show()
# Disable settings menu action when server is active
self.settings_action.setEnabled(not active)
def closeEvent(self, e): def closeEvent(self, e):
self.common.log("MainWindow", "closeEvent") self.common.log("MainWindow", "closeEvent")
self.system_tray.hide() self.system_tray.hide()
try: # TODO: Run the tab's close_event
if self.mode == self.common.gui.MODE_WEBSITE: e.accept()
server_status = self.share_mode.server_status
if self.mode == self.common.gui.MODE_WEBSITE:
server_status = self.website_mode.server_status
else:
server_status = self.receive_mode.server_status
if server_status.status != server_status.STATUS_STOPPED:
self.common.log("MainWindow", "closeEvent, opening warning dialog")
dialog = QtWidgets.QMessageBox()
dialog.setWindowTitle(strings._("gui_quit_title"))
if self.mode == self.common.gui.MODE_WEBSITE:
dialog.setText(strings._("gui_share_quit_warning"))
else:
dialog.setText(strings._("gui_receive_quit_warning"))
dialog.setIcon(QtWidgets.QMessageBox.Critical)
quit_button = dialog.addButton(
strings._("gui_quit_warning_quit"), QtWidgets.QMessageBox.YesRole
)
dont_quit_button = dialog.addButton(
strings._("gui_quit_warning_dont_quit"),
QtWidgets.QMessageBox.NoRole,
)
dialog.setDefaultButton(dont_quit_button)
reply = dialog.exec_()
# Quit
if reply == 0:
self.stop_server()
e.accept()
# Don't Quit
else:
e.ignore()
except:
e.accept()
def cleanup(self): def cleanup(self):
self.onion.cleanup() self.common.gui.onion.cleanup()
self.app.cleanup() # TODO: Run the tab's cleanup

View File

@ -40,18 +40,13 @@ class SettingsDialog(QtWidgets.QDialog):
settings_saved = QtCore.pyqtSignal() settings_saved = QtCore.pyqtSignal()
def __init__(self, common, onion, qtapp, config=False, local_only=False): def __init__(self, common):
super(SettingsDialog, self).__init__() super(SettingsDialog, self).__init__()
self.common = common self.common = common
self.common.log("SettingsDialog", "__init__") self.common.log("SettingsDialog", "__init__")
self.onion = onion
self.qtapp = qtapp
self.config = config
self.local_only = local_only
self.setModal(True) self.setModal(True)
self.setWindowTitle(strings._("gui_settings_window_title")) self.setWindowTitle(strings._("gui_settings_window_title"))
self.setWindowIcon( self.setWindowIcon(
@ -346,7 +341,7 @@ class SettingsDialog(QtWidgets.QDialog):
) )
self.check_for_updates_button.clicked.connect(self.check_for_updates) self.check_for_updates_button.clicked.connect(self.check_for_updates)
# We can't check for updates if not connected to Tor # We can't check for updates if not connected to Tor
if not self.onion.connected_to_tor: if not self.common.gui.onion.connected_to_tor:
self.check_for_updates_button.setEnabled(False) self.check_for_updates_button.setEnabled(False)
# Autoupdate options layout # Autoupdate options layout
@ -721,7 +716,7 @@ class SettingsDialog(QtWidgets.QDialog):
def reload_settings(self): def reload_settings(self):
# Load settings, and fill them in # Load settings, and fill them in
self.old_settings = Settings(self.common, self.config) self.old_settings = Settings(self.common, self.common.gui.config)
self.old_settings.load() 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")
@ -861,12 +856,12 @@ class SettingsDialog(QtWidgets.QDialog):
self.tor_bridges_use_custom_textbox.setPlainText(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 # If we're connected to Tor, show onion service settings, show label if not
if self.onion.is_authenticated(): if self.common.gui.onion.is_authenticated():
self.connect_to_tor_label.hide() self.connect_to_tor_label.hide()
self.onion_settings_widget.show() self.onion_settings_widget.show()
# If v3 onion services are supported, allow using legacy mode # If v3 onion services are supported, allow using legacy mode
if self.onion.supports_v3_onions: if self.common.gui.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() self.use_legacy_v2_onions_checkbox.show()
else: else:
@ -1005,7 +1000,7 @@ class SettingsDialog(QtWidgets.QDialog):
"hidservauth_copy_button_clicked", "hidservauth_copy_button_clicked",
"HidServAuth was copied to clipboard", "HidServAuth was copied to clipboard",
) )
clipboard = self.qtapp.clipboard() clipboard = self.common.gui.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): def use_legacy_v2_onions_checkbox_clicked(self, checked):
@ -1068,7 +1063,7 @@ class SettingsDialog(QtWidgets.QDialog):
onion = Onion(self.common) onion = Onion(self.common)
onion.connect( onion.connect(
custom_settings=settings, custom_settings=settings,
config=self.config, config=self.common.gui.config,
tor_status_update_func=tor_status_update_func, tor_status_update_func=tor_status_update_func,
) )
@ -1110,11 +1105,11 @@ class SettingsDialog(QtWidgets.QDialog):
self.common.log("SettingsDialog", "check_for_updates") self.common.log("SettingsDialog", "check_for_updates")
# Disable buttons # Disable buttons
self._disable_buttons() self._disable_buttons()
self.qtapp.processEvents() self.common.gui.qtapp.processEvents()
def update_timestamp(): def update_timestamp():
# Update the last checked label # Update the last checked label
settings = Settings(self.common, self.config) settings = Settings(self.common, self.common.gui.config)
settings.load() settings.load()
autoupdate_timestamp = settings.get("autoupdate_timestamp") autoupdate_timestamp = settings.get("autoupdate_timestamp")
self._update_autoupdate_timestamp(autoupdate_timestamp) self._update_autoupdate_timestamp(autoupdate_timestamp)
@ -1157,7 +1152,7 @@ class SettingsDialog(QtWidgets.QDialog):
close_forced_update_thread() close_forced_update_thread()
forced_update_thread = UpdateThread( forced_update_thread = UpdateThread(
self.common, self.onion, self.config, force=True self.common, self.onion, self.common.gui.config, force=True
) )
forced_update_thread.update_available.connect(update_available) forced_update_thread.update_available.connect(update_available)
forced_update_thread.update_not_available.connect(update_not_available) forced_update_thread.update_not_available.connect(update_not_available)
@ -1205,8 +1200,8 @@ class SettingsDialog(QtWidgets.QDialog):
# If Tor isn't connected, or if Tor settings have changed, Reinitialize # If Tor isn't connected, or if Tor settings have changed, Reinitialize
# the Onion object # the Onion object
reboot_onion = False reboot_onion = False
if not self.local_only: if not self.common.gui.local_only:
if self.onion.is_authenticated(): if self.common.gui.onion.is_authenticated():
self.common.log( self.common.log(
"SettingsDialog", "save_clicked", "Connected to Tor" "SettingsDialog", "save_clicked", "Connected to Tor"
) )
@ -1245,20 +1240,18 @@ class SettingsDialog(QtWidgets.QDialog):
self.common.log( self.common.log(
"SettingsDialog", "save_clicked", "rebooting the Onion" "SettingsDialog", "save_clicked", "rebooting the Onion"
) )
self.onion.cleanup() self.common.gui.onion.cleanup()
tor_con = TorConnectionDialog( tor_con = TorConnectionDialog(self.common, settings)
self.common, self.qtapp, self.onion, settings
)
tor_con.start() tor_con.start()
self.common.log( self.common.log(
"SettingsDialog", "SettingsDialog",
"save_clicked", "save_clicked",
f"Onion done rebooting, connected to Tor: {self.onion.connected_to_tor}", f"Onion done rebooting, connected to Tor: {self.common.gui.onion.connected_to_tor}",
) )
if self.onion.is_authenticated() and not tor_con.wasCanceled(): if self.common.gui.onion.is_authenticated() and not tor_con.wasCanceled():
self.settings_saved.emit() self.settings_saved.emit()
self.close() self.close()
@ -1274,7 +1267,7 @@ class SettingsDialog(QtWidgets.QDialog):
Cancel button clicked. 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(): if not self.common.gui.local_only and not self.common.gui.onion.is_authenticated():
Alert( Alert(
self.common, self.common,
strings._("gui_tor_connection_canceled"), strings._("gui_tor_connection_canceled"),
@ -1301,7 +1294,7 @@ class SettingsDialog(QtWidgets.QDialog):
Return a Settings object that's full of values from the settings dialog. 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 = Settings(self.common, self.common.gui.config)
settings.load() # To get the last update timestamp settings.load() # To get the last update timestamp
settings.set( settings.set(
@ -1448,14 +1441,14 @@ class SettingsDialog(QtWidgets.QDialog):
self.common.log("SettingsDialog", "closeEvent") self.common.log("SettingsDialog", "closeEvent")
# On close, if Tor isn't connected, then quit OnionShare altogether # On close, if Tor isn't connected, then quit OnionShare altogether
if not self.local_only: if not self.common.gui.local_only:
if not self.onion.is_authenticated(): if not self.common.gui.onion.is_authenticated():
self.common.log( self.common.log(
"SettingsDialog", "closeEvent", "Closing while not connected to Tor" "SettingsDialog", "closeEvent", "Closing while not connected to Tor"
) )
# Wait 1ms for the event loop to finish, then quit # Wait 1ms for the event loop to finish, then quit
QtCore.QTimer.singleShot(1, self.qtapp.quit) QtCore.QTimer.singleShot(1, self.common.gui.qtapp.quit)
def _update_autoupdate_timestamp(self, autoupdate_timestamp): def _update_autoupdate_timestamp(self, autoupdate_timestamp):
self.common.log("SettingsDialog", "_update_autoupdate_timestamp") self.common.log("SettingsDialog", "_update_autoupdate_timestamp")
@ -1473,7 +1466,7 @@ class SettingsDialog(QtWidgets.QDialog):
self.tor_status.setText( self.tor_status.setText(
f"<strong>{strings._('connecting_to_tor')}</strong><br>{progress}% {summary}" f"<strong>{strings._('connecting_to_tor')}</strong><br>{progress}% {summary}"
) )
self.qtapp.processEvents() self.common.gui.qtapp.processEvents()
if "Done" in summary: if "Done" in summary:
self.tor_status.hide() self.tor_status.hide()
self._enable_buttons() self._enable_buttons()
@ -1489,7 +1482,7 @@ class SettingsDialog(QtWidgets.QDialog):
def _enable_buttons(self): 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 # We can't check for updates if we're still not connected to Tor
if not self.onion.connected_to_tor: if not self.common.gui.onion.connected_to_tor:
self.check_for_updates_button.setEnabled(False) self.check_for_updates_button.setEnabled(False)
else: else:
self.check_for_updates_button.setEnabled(True) self.check_for_updates_button.setEnabled(True)

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
"""
OnionShare | https://onionshare.org/
Copyright (C) 2014-2018 Micah Lee <micah@micahflee.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 .tab import Tab

562
onionshare_gui/tab/tab.py Normal file
View File

@ -0,0 +1,562 @@
# -*- coding: utf-8 -*-
"""
OnionShare | https://onionshare.org/
Copyright (C) 2014-2018 Micah Lee <micah@micahflee.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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
from onionshare import strings
from onionshare.onionshare import OnionShare
from onionshare.web import Web
from .mode.share_mode import ShareMode
from .mode.receive_mode import ReceiveMode
from .mode.website_mode import WebsiteMode
from .server_status import ServerStatus
from ..widgets import Alert
class Tab(QtWidgets.QWidget):
"""
A GUI tab, you know, sort of like in a web browser
"""
def __init__(self, common, system_tray, status_bar, filenames):
super(Tab, self).__init__()
self.common = common
self.common.log("Tab", "__init__")
self.system_tray = system_tray
self.status_bar = status_bar
self.mode = self.common.gui.MODE_SHARE
# Start the OnionShare app
self.app = OnionShare(common, self.common.gui.onion, self.common.gui.local_only)
# Mode switcher, to switch between share files and receive files
self.share_mode_button = QtWidgets.QPushButton(
strings._("gui_mode_share_button")
)
self.share_mode_button.setFixedHeight(50)
self.share_mode_button.clicked.connect(self.share_mode_clicked)
self.receive_mode_button = QtWidgets.QPushButton(
strings._("gui_mode_receive_button")
)
self.receive_mode_button.setFixedHeight(50)
self.receive_mode_button.clicked.connect(self.receive_mode_clicked)
self.website_mode_button = QtWidgets.QPushButton(
strings._("gui_mode_website_button")
)
self.website_mode_button.setFixedHeight(50)
self.website_mode_button.clicked.connect(self.website_mode_clicked)
self.settings_button = QtWidgets.QPushButton()
self.settings_button.setDefault(False)
self.settings_button.setFixedWidth(40)
self.settings_button.setFixedHeight(50)
self.settings_button.setIcon(
QtGui.QIcon(self.common.get_resource_path("images/settings.png"))
)
self.settings_button.clicked.connect(self.open_settings)
self.settings_button.setStyleSheet(self.common.gui.css["settings_button"])
mode_switcher_layout = QtWidgets.QHBoxLayout()
mode_switcher_layout.setSpacing(0)
mode_switcher_layout.addWidget(self.share_mode_button)
mode_switcher_layout.addWidget(self.receive_mode_button)
mode_switcher_layout.addWidget(self.website_mode_button)
mode_switcher_layout.addWidget(self.settings_button)
# Server status indicator icons
self.server_status_image_stopped = QtGui.QImage(
self.common.get_resource_path("images/server_stopped.png")
)
self.server_status_image_working = QtGui.QImage(
self.common.get_resource_path("images/server_working.png")
)
self.server_status_image_started = QtGui.QImage(
self.common.get_resource_path("images/server_started.png")
)
# Share mode
self.share_mode = ShareMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.server_status_label,
self.system_tray,
filenames,
self.common.gui.local_only,
)
self.share_mode.init()
self.share_mode.server_status.server_started.connect(
self.update_server_status_indicator
)
self.share_mode.server_status.server_stopped.connect(
self.update_server_status_indicator
)
self.share_mode.start_server_finished.connect(
self.update_server_status_indicator
)
self.share_mode.stop_server_finished.connect(
self.update_server_status_indicator
)
self.share_mode.stop_server_finished.connect(self.stop_server_finished)
self.share_mode.start_server_finished.connect(self.clear_message)
self.share_mode.server_status.button_clicked.connect(self.clear_message)
self.share_mode.server_status.url_copied.connect(self.copy_url)
self.share_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth)
self.share_mode.set_server_active.connect(self.set_server_active)
# Receive mode
self.receive_mode = ReceiveMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.server_status_label,
self.system_tray,
None,
self.common.gui.local_only,
)
self.receive_mode.init()
self.receive_mode.server_status.server_started.connect(
self.update_server_status_indicator
)
self.receive_mode.server_status.server_stopped.connect(
self.update_server_status_indicator
)
self.receive_mode.start_server_finished.connect(
self.update_server_status_indicator
)
self.receive_mode.stop_server_finished.connect(
self.update_server_status_indicator
)
self.receive_mode.stop_server_finished.connect(self.stop_server_finished)
self.receive_mode.start_server_finished.connect(self.clear_message)
self.receive_mode.server_status.button_clicked.connect(self.clear_message)
self.receive_mode.server_status.url_copied.connect(self.copy_url)
self.receive_mode.server_status.hidservauth_copied.connect(
self.copy_hidservauth
)
self.receive_mode.set_server_active.connect(self.set_server_active)
# Website mode
self.website_mode = WebsiteMode(
self.common,
self.common.gui.qtapp,
self.app,
self.status_bar,
self.server_status_label,
self.system_tray,
filenames,
)
self.website_mode.init()
self.website_mode.server_status.server_started.connect(
self.update_server_status_indicator
)
self.website_mode.server_status.server_stopped.connect(
self.update_server_status_indicator
)
self.website_mode.start_server_finished.connect(
self.update_server_status_indicator
)
self.website_mode.stop_server_finished.connect(
self.update_server_status_indicator
)
self.website_mode.stop_server_finished.connect(self.stop_server_finished)
self.website_mode.start_server_finished.connect(self.clear_message)
self.website_mode.server_status.button_clicked.connect(self.clear_message)
self.website_mode.server_status.url_copied.connect(self.copy_url)
self.website_mode.server_status.hidservauth_copied.connect(
self.copy_hidservauth
)
self.website_mode.set_server_active.connect(self.set_server_active)
self.update_mode_switcher()
self.update_server_status_indicator()
# Layouts
contents_layout = QtWidgets.QVBoxLayout()
contents_layout.setContentsMargins(10, 0, 10, 0)
contents_layout.addWidget(self.receive_mode)
contents_layout.addWidget(self.share_mode)
contents_layout.addWidget(self.website_mode)
layout = QtWidgets.QVBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.addLayout(mode_switcher_layout)
layout.addLayout(contents_layout)
self.setLayout(layout)
# The server isn't active yet
self.set_server_active(False)
# Create the timer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.timer_callback)
# Start the timer
self.timer.start(500)
def update_mode_switcher(self):
# Based on the current mode, switch the mode switcher button styles,
# and show and hide widgets to switch modes
if self.mode == self.common.gui.MODE_SHARE:
self.share_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_selected_style"]
)
self.receive_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.website_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.receive_mode.hide()
self.share_mode.show()
self.website_mode.hide()
elif self.mode == self.common.gui.MODE_WEBSITE:
self.share_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.receive_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.website_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_selected_style"]
)
self.receive_mode.hide()
self.share_mode.hide()
self.website_mode.show()
else:
self.share_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.receive_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_selected_style"]
)
self.website_mode_button.setStyleSheet(
self.common.gui.css["mode_switcher_unselected_style"]
)
self.share_mode.hide()
self.receive_mode.show()
self.website_mode.hide()
self.update_server_status_indicator()
def share_mode_clicked(self):
if self.mode != self.common.gui.MODE_SHARE:
self.common.log("Tab", "share_mode_clicked")
self.mode = self.common.gui.MODE_SHARE
self.update_mode_switcher()
def receive_mode_clicked(self):
if self.mode != self.common.gui.MODE_RECEIVE:
self.common.log("Tab", "receive_mode_clicked")
self.mode = self.common.gui.MODE_RECEIVE
self.update_mode_switcher()
def website_mode_clicked(self):
if self.mode != self.common.gui.MODE_WEBSITE:
self.common.log("Tab", "website_mode_clicked")
self.mode = self.common.gui.MODE_WEBSITE
self.update_mode_switcher()
def update_server_status_indicator(self):
# Set the status image
if self.mode == self.common.gui.MODE_SHARE:
# Share mode
if self.share_mode.server_status.status == ServerStatus.STATUS_STOPPED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_stopped)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_stopped")
)
elif self.share_mode.server_status.status == ServerStatus.STATUS_WORKING:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_working)
)
if self.share_mode.server_status.autostart_timer_datetime:
self.server_status_label.setText(
strings._("gui_status_indicator_share_scheduled")
)
else:
self.server_status_label.setText(
strings._("gui_status_indicator_share_working")
)
elif self.share_mode.server_status.status == ServerStatus.STATUS_STARTED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_started)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_started")
)
elif self.mode == self.common.gui.MODE_WEBSITE:
# Website mode
if self.website_mode.server_status.status == ServerStatus.STATUS_STOPPED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_stopped)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_stopped")
)
elif self.website_mode.server_status.status == ServerStatus.STATUS_WORKING:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_working)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_working")
)
elif self.website_mode.server_status.status == ServerStatus.STATUS_STARTED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_started)
)
self.server_status_label.setText(
strings._("gui_status_indicator_share_started")
)
else:
# Receive mode
if self.receive_mode.server_status.status == ServerStatus.STATUS_STOPPED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_stopped)
)
self.server_status_label.setText(
strings._("gui_status_indicator_receive_stopped")
)
elif self.receive_mode.server_status.status == ServerStatus.STATUS_WORKING:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_working)
)
if self.receive_mode.server_status.autostart_timer_datetime:
self.server_status_label.setText(
strings._("gui_status_indicator_receive_scheduled")
)
else:
self.server_status_label.setText(
strings._("gui_status_indicator_receive_working")
)
elif self.receive_mode.server_status.status == ServerStatus.STATUS_STARTED:
self.server_status_image_label.setPixmap(
QtGui.QPixmap.fromImage(self.server_status_image_started)
)
self.server_status_label.setText(
strings._("gui_status_indicator_receive_started")
)
def stop_server_finished(self):
# When the server stopped, cleanup the ephemeral onion service
self.common.gui.onion.cleanup(stop_tor=False)
def timer_callback(self):
"""
Check for messages communicated from the web app, and update the GUI accordingly. Also,
call ShareMode and ReceiveMode's timer_callbacks.
"""
self.update()
if not self.common.gui.local_only:
# Have we lost connection to Tor somehow?
if not self.common.gui.onion.is_authenticated():
self.timer.stop()
self.status_bar.showMessage(strings._("gui_tor_connection_lost"))
self.system_tray.showMessage(
strings._("gui_tor_connection_lost"),
strings._("gui_tor_connection_error_settings"),
)
self.share_mode.handle_tor_broke()
self.receive_mode.handle_tor_broke()
self.website_mode.handle_tor_broke()
# Process events from the web object
if self.mode == self.common.gui.MODE_SHARE:
mode = self.share_mode
elif self.mode == self.common.gui.MODE_WEBSITE:
mode = self.website_mode
else:
mode = self.receive_mode
events = []
done = False
while not done:
try:
r = mode.web.q.get(False)
events.append(r)
except queue.Empty:
done = True
for event in events:
if event["type"] == Web.REQUEST_LOAD:
mode.handle_request_load(event)
elif event["type"] == Web.REQUEST_STARTED:
mode.handle_request_started(event)
elif event["type"] == Web.REQUEST_RATE_LIMIT:
mode.handle_request_rate_limit(event)
elif event["type"] == Web.REQUEST_PROGRESS:
mode.handle_request_progress(event)
elif event["type"] == Web.REQUEST_CANCELED:
mode.handle_request_canceled(event)
elif event["type"] == Web.REQUEST_UPLOAD_FILE_RENAMED:
mode.handle_request_upload_file_renamed(event)
elif event["type"] == Web.REQUEST_UPLOAD_SET_DIR:
mode.handle_request_upload_set_dir(event)
elif event["type"] == Web.REQUEST_UPLOAD_FINISHED:
mode.handle_request_upload_finished(event)
elif event["type"] == Web.REQUEST_UPLOAD_CANCELED:
mode.handle_request_upload_canceled(event)
elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_STARTED:
mode.handle_request_individual_file_started(event)
elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_PROGRESS:
mode.handle_request_individual_file_progress(event)
elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_CANCELED:
mode.handle_request_individual_file_canceled(event)
if event["type"] == Web.REQUEST_ERROR_DATA_DIR_CANNOT_CREATE:
Alert(
self.common,
strings._("error_cannot_create_data_dir").format(
event["data"]["receive_mode_dir"]
),
)
if event["type"] == Web.REQUEST_OTHER:
if (
event["path"] != "/favicon.ico"
and event["path"] != f"/{mode.web.shutdown_password}/shutdown"
):
self.status_bar.showMessage(
f"{strings._('other_page_loaded')}: {event['path']}"
)
if event["type"] == Web.REQUEST_INVALID_PASSWORD:
self.status_bar.showMessage(
f"[#{mode.web.invalid_passwords_count}] {strings._('incorrect_password')}: {event['data']}"
)
mode.timer_callback()
def copy_url(self):
"""
When the URL gets copied to the clipboard, display this in the status bar.
"""
self.common.log("Tab", "copy_url")
self.system_tray.showMessage(
strings._("gui_copied_url_title"), strings._("gui_copied_url")
)
def copy_hidservauth(self):
"""
When the stealth onion service HidServAuth gets copied to the clipboard, display this in the status bar.
"""
self.common.log("Tab", "copy_hidservauth")
self.system_tray.showMessage(
strings._("gui_copied_hidservauth_title"),
strings._("gui_copied_hidservauth"),
)
def set_server_active(self, active):
"""
Disable the Settings and Receive Files buttons while an Share Files server is active.
"""
if active:
self.settings_button.hide()
if self.mode == self.common.gui.MODE_SHARE:
self.share_mode_button.show()
self.receive_mode_button.hide()
self.website_mode_button.hide()
elif self.mode == self.common.gui.MODE_WEBSITE:
self.share_mode_button.hide()
self.receive_mode_button.hide()
self.website_mode_button.show()
else:
self.share_mode_button.hide()
self.receive_mode_button.show()
self.website_mode_button.hide()
else:
self.settings_button.show()
self.share_mode_button.show()
self.receive_mode_button.show()
self.website_mode_button.show()
# Disable settings menu action when server is active
self.settings_action.setEnabled(not active)
def clear_message(self):
"""
Clear messages from the status bar.
"""
self.status_bar.clearMessage()
def close_event(self, e):
self.common.log("Tab", "close_event")
try:
if self.mode == self.common.gui.MODE_WEBSITE:
server_status = self.share_mode.server_status
if self.mode == self.common.gui.MODE_WEBSITE:
server_status = self.website_mode.server_status
else:
server_status = self.receive_mode.server_status
if server_status.status != server_status.STATUS_STOPPED:
self.common.log("MainWindow", "closeEvent, opening warning dialog")
dialog = QtWidgets.QMessageBox()
dialog.setWindowTitle(strings._("gui_quit_title"))
if self.mode == self.common.gui.MODE_WEBSITE:
dialog.setText(strings._("gui_share_quit_warning"))
else:
dialog.setText(strings._("gui_receive_quit_warning"))
dialog.setIcon(QtWidgets.QMessageBox.Critical)
quit_button = dialog.addButton(
strings._("gui_quit_warning_quit"), QtWidgets.QMessageBox.YesRole
)
dont_quit_button = dialog.addButton(
strings._("gui_quit_warning_dont_quit"),
QtWidgets.QMessageBox.NoRole,
)
dialog.setDefaultButton(dont_quit_button)
reply = dialog.exec_()
# Quit
if reply == 0:
self.stop_server()
e.accept()
# Don't Quit
else:
e.ignore()
except:
e.accept()
def cleanup(self):
self.app.cleanup()

View File

@ -32,7 +32,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog):
open_settings = QtCore.pyqtSignal() open_settings = QtCore.pyqtSignal()
def __init__(self, common, qtapp, onion, custom_settings=False): def __init__(self, common, custom_settings=False):
super(TorConnectionDialog, self).__init__(None) super(TorConnectionDialog, self).__init__(None)
self.common = common self.common = common
@ -44,9 +44,6 @@ class TorConnectionDialog(QtWidgets.QProgressDialog):
self.common.log("TorConnectionDialog", "__init__") self.common.log("TorConnectionDialog", "__init__")
self.qtapp = qtapp
self.onion = onion
self.setWindowTitle("OnionShare") self.setWindowTitle("OnionShare")
self.setWindowIcon( self.setWindowIcon(
QtGui.QIcon(self.common.get_resource_path("images/logo.png")) QtGui.QIcon(self.common.get_resource_path("images/logo.png"))
@ -68,7 +65,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog):
def start(self): def start(self):
self.common.log("TorConnectionDialog", "start") self.common.log("TorConnectionDialog", "start")
t = TorConnectionThread(self.common, self.settings, self, self.onion) t = TorConnectionThread(self.common, self.settings, self)
t.tor_status_update.connect(self._tor_status_update) t.tor_status_update.connect(self._tor_status_update)
t.connected_to_tor.connect(self._connected_to_tor) t.connected_to_tor.connect(self._connected_to_tor)
t.canceled_connecting_to_tor.connect(self._canceled_connecting_to_tor) t.canceled_connecting_to_tor.connect(self._canceled_connecting_to_tor)
@ -81,7 +78,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog):
self.active = True self.active = True
while self.active: while self.active:
time.sleep(0.1) time.sleep(0.1)
self.qtapp.processEvents() self.common.gui.qtapp.processEvents()
def _tor_status_update(self, progress, summary): def _tor_status_update(self, progress, summary):
self.setValue(int(progress)) self.setValue(int(progress))
@ -99,7 +96,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog):
def _canceled_connecting_to_tor(self): def _canceled_connecting_to_tor(self):
self.common.log("TorConnectionDialog", "_canceled_connecting_to_tor") self.common.log("TorConnectionDialog", "_canceled_connecting_to_tor")
self.active = False self.active = False
self.onion.cleanup() self.common.gui.onion.cleanup()
# Cancel connecting to Tor # Cancel connecting to Tor
QtCore.QTimer.singleShot(1, self.cancel) QtCore.QTimer.singleShot(1, self.cancel)
@ -131,7 +128,7 @@ class TorConnectionThread(QtCore.QThread):
canceled_connecting_to_tor = QtCore.pyqtSignal() canceled_connecting_to_tor = QtCore.pyqtSignal()
error_connecting_to_tor = QtCore.pyqtSignal(str) error_connecting_to_tor = QtCore.pyqtSignal(str)
def __init__(self, common, settings, dialog, onion): def __init__(self, common, settings, dialog):
super(TorConnectionThread, self).__init__() super(TorConnectionThread, self).__init__()
self.common = common self.common = common
@ -141,15 +138,14 @@ class TorConnectionThread(QtCore.QThread):
self.settings = settings self.settings = settings
self.dialog = dialog self.dialog = dialog
self.onion = onion
def run(self): def run(self):
self.common.log("TorConnectionThread", "run") self.common.log("TorConnectionThread", "run")
# Connect to the Onion # Connect to the Onion
try: try:
self.onion.connect(self.settings, False, self._tor_status_update) self.common.gui.onion.connect(self.settings, False, self._tor_status_update)
if self.onion.connected_to_tor: if self.common.gui.onion.connected_to_tor:
self.connected_to_tor.emit() self.connected_to_tor.emit()
else: else:
self.canceled_connecting_to_tor.emit() self.canceled_connecting_to_tor.emit()