From 76d299a6c90f4fc7a899e3c19da7ac6f23c1389e Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Tue, 13 Mar 2018 03:28:47 -0700 Subject: [PATCH] Move settings into the Common object, so the settings are available to all objects (including Web, which is required for receive mode) --- onionshare/__init__.py | 30 ++++++++++----------- onionshare/common.py | 9 +++++++ onionshare/onion.py | 11 ++++---- onionshare_gui/__init__.py | 1 - onionshare_gui/onionshare_gui.py | 36 ++++++++++++------------- onionshare_gui/server_status.py | 30 ++++++++++----------- onionshare_gui/settings_dialog.py | 6 ++--- onionshare_gui/tor_connection_dialog.py | 15 +++++++---- 8 files changed, 72 insertions(+), 66 deletions(-) diff --git a/onionshare/__init__.py b/onionshare/__init__.py index 1e07f11c..5b23ad3e 100644 --- a/onionshare/__init__.py +++ b/onionshare/__init__.py @@ -25,7 +25,6 @@ from .common import Common from .web import Web from .onion import * from .onionshare import OnionShare -from .settings import Settings def main(cwd=None): """ @@ -71,9 +70,6 @@ def main(cwd=None): print(strings._('no_filenames')) sys.exit() - # Debug mode? - common.debug = debug - # Validate filenames if not receive: valid = True @@ -88,20 +84,22 @@ def main(cwd=None): sys.exit() # Load settings - settings = Settings(common, config) - settings.load() + common.load_settings(config) + + # Debug mode? + common.debug = debug # In receive mode, validate downloads dir if receive: valid = True - if not os.path.isdir(settings.get('downloads_dir')): + if not os.path.isdir(common.settings.get('downloads_dir')): try: - os.mkdir(settings.get('downloads_dir'), 0o700) + os.mkdir(common.settings.get('downloads_dir'), 0o700) except: - print(strings._('error_cannot_create_downloads_dir').format(settings.get('downloads_dir'))) + print(strings._('error_cannot_create_downloads_dir').format(common.settings.get('downloads_dir'))) valid = False if valid and not os.access(settings.get('downloads_dir'), os.W_OK): - print(strings._('error_downloads_dir_not_writable').format(settings.get('downloads_dir'))) + print(strings._('error_downloads_dir_not_writable').format(common.settings.get('downloads_dir'))) valid = False if not valid: sys.exit() @@ -112,7 +110,7 @@ def main(cwd=None): # Start the Onion object onion = Onion(common) try: - onion.connect(settings=False, config=config) + onion.connect(custom_settings=False, config=config) except (TorTooOld, TorErrorInvalidSetting, TorErrorAutomatic, TorErrorSocketPort, TorErrorSocketFile, TorErrorMissingPassword, TorErrorUnreadableCookieFile, TorErrorAuthError, TorErrorProtocolError, BundledTorNotSupported, BundledTorTimeout) as e: sys.exit(e.args[0]) except KeyboardInterrupt: @@ -144,7 +142,7 @@ def main(cwd=None): print('') # Start OnionShare http service in new thread - t = threading.Thread(target=web.start, args=(app.port, app.stay_open, settings.get('slug'))) + t = threading.Thread(target=web.start, args=(app.port, app.stay_open, common.settings.get('slug'))) t.daemon = True t.start() @@ -157,10 +155,10 @@ def main(cwd=None): app.shutdown_timer.start() # Save the web slug if we are using a persistent private key - if settings.get('save_private_key'): - if not settings.get('slug'): - settings.set('slug', web.slug) - settings.save() + if common.settings.get('save_private_key'): + if not common.settings.get('slug'): + common.settings.set('slug', web.slug) + common.settings.save() print('') if receive: diff --git a/onionshare/common.py b/onionshare/common.py index c24a1b4b..903e4148 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -29,6 +29,8 @@ import tempfile import threading import time +from .settings import Settings + class Common(object): """ The Common object is shared amongst all parts of OnionShare. @@ -45,6 +47,13 @@ class Common(object): with open(self.get_resource_path('version.txt')) as f: self.version = f.read().strip() + def load_settings(self, config=None): + """ + Loading settings, optionally from a custom config json file. + """ + self.settings = Settings(self, config) + self.settings.load() + def log(self, module, func, msg=None): """ If debug mode is on, log error messages to stdout diff --git a/onionshare/onion.py b/onionshare/onion.py index 4b3b0971..57e407ea 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -148,15 +148,14 @@ class Onion(object): # Start out not connected to Tor self.connected_to_tor = False - def connect(self, settings=False, config=False, tor_status_update_func=None): + def connect(self, custom_settings=False, config=False, tor_status_update_func=None): self.common.log('Onion', 'connect') - # Either use settings that are passed in, or load them from disk - if settings: - self.settings = settings + # Either use settings that are passed in, or use them from common + if custom_settings: + self.settings = custom_settings else: - self.settings = Settings(self.common, config) - self.settings.load() + self.settings = self.common.settings # The Tor controller self.c = None diff --git a/onionshare_gui/__init__.py b/onionshare_gui/__init__.py index 04fe1e62..e1ad8743 100644 --- a/onionshare_gui/__init__.py +++ b/onionshare_gui/__init__.py @@ -27,7 +27,6 @@ from onionshare.common import Common from onionshare.web import Web from onionshare.onion import Onion from onionshare.onionshare import OnionShare -from onionshare.settings import Settings from .onionshare_gui import OnionShareGui diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 04b8a066..a52f232a 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -25,7 +25,6 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings, common from onionshare.common import Common, ShutdownTimer -from onionshare.settings import Settings from onionshare.onion import * from .tor_connection_dialog import TorConnectionDialog @@ -66,8 +65,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # Load settings self.config = config - self.settings = Settings(self.common, self.config) - self.settings.load() + self.common.load_settings(self.config) # File selection self.file_selection = FileSelection(self.common) @@ -76,7 +74,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.file_selection.file_list.add_file(filename) # Server status - self.server_status = ServerStatus(self.common, self.qtapp, self.app, self.web, self.file_selection, self.settings) + self.server_status = ServerStatus(self.common, self.qtapp, self.app, self.web, self.file_selection) self.server_status.server_started.connect(self.file_selection.server_started) self.server_status.server_started.connect(self.start_server) self.server_status.server_started.connect(self.update_server_status_indicator) @@ -222,7 +220,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.timer.timeout.connect(self.check_for_requests) # Start the "Connecting to Tor" dialog, which calls onion.connect() - tor_con = TorConnectionDialog(self.common, self.qtapp, self.settings, self.onion) + tor_con = TorConnectionDialog(self.common, self.qtapp, self.onion) tor_con.canceled.connect(self._tor_connection_canceled) tor_con.open_settings.connect(self._tor_connection_open_settings) tor_con.start() @@ -339,7 +337,7 @@ class OnionShareGui(QtWidgets.QMainWindow): def reload_settings(): self.common.log('OnionShareGui', 'open_settings', 'settings have changed, reloading') - self.settings.load() + self.common.settings.load() # We might've stopped the main requests timer if a Tor connection failed. # If we've reloaded settings, we probably succeeded in obtaining a new # connection. If so, restart the timer. @@ -352,7 +350,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.server_status.server_button.setEnabled(True) self.status_bar.clearMessage() # If we switched off the shutdown timeout setting, ensure the widget is hidden. - if not self.settings.get('shutdown_timeout'): + if not self.common.settings.get('shutdown_timeout'): self.server_status.shutdown_timeout_container.hide() d = SettingsDialog(self.common, self.onion, self.qtapp, self.config) @@ -371,7 +369,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.set_server_active(True) - self.app.set_stealth(self.settings.get('use_stealth')) + self.app.set_stealth(self.common.settings.get('use_stealth')) # Hide and reset the downloads if we have previously shared self.downloads_container.hide() @@ -395,10 +393,10 @@ class OnionShareGui(QtWidgets.QMainWindow): return - self.app.stay_open = not self.settings.get('close_after_first_download') + self.app.stay_open = not self.common.settings.get('close_after_first_download') # start onionshare http service in new thread - t = threading.Thread(target=self.web.start, args=(self.app.port, self.app.stay_open, self.settings.get('slug'))) + t = threading.Thread(target=self.web.start, args=(self.app.port, self.app.stay_open, self.common.settings.get('slug'))) t.daemon = True t.start() # wait for modules in thread to load, preventing a thread-related cx_Freeze crash @@ -462,7 +460,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.filesize_warning.setText(strings._("large_filesize", True)) self.filesize_warning.show() - if self.settings.get('shutdown_timeout'): + if self.common.settings.get('shutdown_timeout'): # Convert the date value to seconds between now and then now = QtCore.QDateTime.currentDateTime() self.timeout = now.secsTo(self.server_status.timeout) @@ -527,7 +525,7 @@ class OnionShareGui(QtWidgets.QMainWindow): Check for updates in a new thread, if enabled. """ if self.common.platform == 'Windows' or self.common.platform == 'Darwin': - if self.settings.get('use_autoupdate'): + if self.common.settings.get('use_autoupdate'): def update_available(update_url, installed_version, latest_version): Alert(self.common, strings._("update_available", True).format(update_url, installed_version, latest_version)) @@ -558,7 +556,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.server_status.stop_server() self.server_status.server_button.setEnabled(False) self.status_bar.showMessage(strings._('gui_tor_connection_lost', True)) - if self.systemTray.supportsMessages() and self.settings.get('systray_notifications'): + if self.systemTray.supportsMessages() and self.common.settings.get('systray_notifications'): self.systemTray.showMessage(strings._('gui_tor_connection_lost', True), strings._('gui_tor_connection_error_settings', True)) # scroll to the bottom of the dl progress bar log pane @@ -587,7 +585,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.new_download = True self.downloads_in_progress += 1 self.update_downloads_in_progress(self.downloads_in_progress) - if self.systemTray.supportsMessages() and self.settings.get('systray_notifications'): + if self.systemTray.supportsMessages() and self.common.settings.get('systray_notifications'): self.systemTray.showMessage(strings._('systray_download_started_title', True), strings._('systray_download_started_message', True)) elif event["type"] == self.web.REQUEST_RATE_LIMIT: @@ -599,7 +597,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # is the download complete? if event["data"]["bytes"] == self.web.zip_filesize: - if self.systemTray.supportsMessages() and self.settings.get('systray_notifications'): + if self.systemTray.supportsMessages() and self.common.settings.get('systray_notifications'): self.systemTray.showMessage(strings._('systray_download_completed_title', True), strings._('systray_download_completed_message', True)) # Update the total 'completed downloads' info self.downloads_completed += 1 @@ -625,7 +623,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # Update the 'in progress downloads' info self.downloads_in_progress -= 1 self.update_downloads_in_progress(self.downloads_in_progress) - if self.systemTray.supportsMessages() and self.settings.get('systray_notifications'): + if self.systemTray.supportsMessages() and self.common.settings.get('systray_notifications'): self.systemTray.showMessage(strings._('systray_download_canceled_title', True), strings._('systray_download_canceled_message', True)) elif event["path"] != '/favicon.ico': @@ -633,7 +631,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # If the auto-shutdown timer has stopped, stop the server if self.server_status.status == self.server_status.STATUS_STARTED: - if self.app.shutdown_timer and self.settings.get('shutdown_timeout'): + if self.app.shutdown_timer and self.common.settings.get('shutdown_timeout'): if self.timeout > 0: now = QtCore.QDateTime.currentDateTime() seconds_remaining = now.secsTo(self.server_status.timeout) @@ -654,7 +652,7 @@ class OnionShareGui(QtWidgets.QMainWindow): When the URL gets copied to the clipboard, display this in the status bar. """ self.common.log('OnionShareGui', 'copy_url') - if self.systemTray.supportsMessages() and self.settings.get('systray_notifications'): + if self.systemTray.supportsMessages() and self.common.settings.get('systray_notifications'): self.systemTray.showMessage(strings._('gui_copied_url_title', True), strings._('gui_copied_url', True)) def copy_hidservauth(self): @@ -662,7 +660,7 @@ class OnionShareGui(QtWidgets.QMainWindow): When the stealth onion service HidServAuth gets copied to the clipboard, display this in the status bar. """ self.common.log('OnionShareGui', 'copy_hidservauth') - if self.systemTray.supportsMessages() and self.settings.get('systray_notifications'): + if self.systemTray.supportsMessages() and self.common.settings.get('systray_notifications'): self.systemTray.showMessage(strings._('gui_copied_hidservauth_title', True), strings._('gui_copied_hidservauth', True)) def clear_message(self): diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 62df81ff..ed8bc5f5 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -38,7 +38,7 @@ class ServerStatus(QtWidgets.QWidget): STATUS_WORKING = 1 STATUS_STARTED = 2 - def __init__(self, common, qtapp, app, web, file_selection, settings): + def __init__(self, common, qtapp, app, web, file_selection): super(ServerStatus, self).__init__() self.common = common @@ -50,8 +50,6 @@ class ServerStatus(QtWidgets.QWidget): self.web = web self.file_selection = file_selection - self.settings = settings - # Shutdown timeout layout self.shutdown_timeout_label = QtWidgets.QLabel(strings._('gui_settings_shutdown_timeout', True)) self.shutdown_timeout = QtWidgets.QDateTimeEdit() @@ -135,13 +133,13 @@ class ServerStatus(QtWidgets.QWidget): info_image = self.common.get_resource_path('images/info.png') self.url_description.setText(strings._('gui_url_description', True).format(info_image)) # Show a Tool Tip explaining the lifecycle of this URL - if self.settings.get('save_private_key'): - if self.settings.get('close_after_first_download'): + if self.common.settings.get('save_private_key'): + if self.common.settings.get('close_after_first_download'): self.url_description.setToolTip(strings._('gui_url_label_onetime_and_persistent', True)) else: self.url_description.setToolTip(strings._('gui_url_label_persistent', True)) else: - if self.settings.get('close_after_first_download'): + if self.common.settings.get('close_after_first_download'): self.url_description.setToolTip(strings._('gui_url_label_onetime', True)) else: self.url_description.setToolTip(strings._('gui_url_label_stay_open', True)) @@ -151,12 +149,12 @@ class ServerStatus(QtWidgets.QWidget): self.copy_url_button.show() - if self.settings.get('save_private_key'): - if not self.settings.get('slug'): - self.settings.set('slug', self.web.slug) - self.settings.save() + if self.common.settings.get('save_private_key'): + if not self.common.settings.get('slug'): + self.common.settings.set('slug', self.web.slug) + self.common.settings.save() - if self.settings.get('shutdown_timeout'): + if self.common.settings.get('shutdown_timeout'): self.shutdown_timeout_container.hide() if self.app.stealth: @@ -183,26 +181,26 @@ class ServerStatus(QtWidgets.QWidget): self.server_button.setEnabled(True) self.server_button.setText(strings._('gui_start_server', True)) self.server_button.setToolTip('') - if self.settings.get('shutdown_timeout'): + if self.common.settings.get('shutdown_timeout'): self.shutdown_timeout_container.show() elif self.status == self.STATUS_STARTED: self.server_button.setStyleSheet(button_started_style) self.server_button.setEnabled(True) self.server_button.setText(strings._('gui_stop_server', True)) - if self.settings.get('shutdown_timeout'): + if self.common.settings.get('shutdown_timeout'): self.shutdown_timeout_container.hide() self.server_button.setToolTip(strings._('gui_stop_server_shutdown_timeout_tooltip', True).format(self.timeout)) elif self.status == self.STATUS_WORKING: self.server_button.setStyleSheet(button_working_style) self.server_button.setEnabled(True) self.server_button.setText(strings._('gui_please_wait')) - if self.settings.get('shutdown_timeout'): + if self.common.settings.get('shutdown_timeout'): self.shutdown_timeout_container.hide() else: self.server_button.setStyleSheet(button_working_style) self.server_button.setEnabled(False) self.server_button.setText(strings._('gui_please_wait')) - if self.settings.get('shutdown_timeout'): + if self.common.settings.get('shutdown_timeout'): self.shutdown_timeout_container.hide() def server_button_clicked(self): @@ -210,7 +208,7 @@ class ServerStatus(QtWidgets.QWidget): Toggle starting or stopping the server. """ if self.status == self.STATUS_STOPPED: - if self.settings.get('shutdown_timeout'): + if self.common.settings.get('shutdown_timeout'): # Get the timeout chosen, stripped of its seconds. This prevents confusion if the share stops at (say) 37 seconds past the minute chosen self.timeout = self.shutdown_timeout.dateTime().toPyDateTime().replace(second=0, microsecond=0) # If the timeout has actually passed already before the user hit Start, refuse to start the server. diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 2bd20d84..192815da 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -599,8 +599,8 @@ class SettingsDialog(QtWidgets.QDialog): else: tor_status_update_func = None - onion = Onion() - onion.connect(settings=settings, config=self.config, tor_status_update_func=tor_status_update_func) + onion = Onion(self.common) + 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', True).format(onion.tor_version, onion.supports_ephemeral, onion.supports_stealth)) @@ -707,7 +707,7 @@ class SettingsDialog(QtWidgets.QDialog): self.common.log('SettingsDialog', 'save_clicked', 'rebooting the Onion') self.onion.cleanup() - tor_con = TorConnectionDialog(self.common, self.qtapp, settings, self.onion) + 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)) diff --git a/onionshare_gui/tor_connection_dialog.py b/onionshare_gui/tor_connection_dialog.py index 6d127df9..2ee13a66 100644 --- a/onionshare_gui/tor_connection_dialog.py +++ b/onionshare_gui/tor_connection_dialog.py @@ -30,15 +30,19 @@ class TorConnectionDialog(QtWidgets.QProgressDialog): """ open_settings = QtCore.pyqtSignal() - def __init__(self, common, qtapp, settings, onion): + def __init__(self, common, qtapp, onion, custom_settings=False): super(TorConnectionDialog, self).__init__(None) self.common = common + if custom_settings: + self.settings = custom_settings + else: + self.settings = self.common.settings + self.common.log('TorConnectionDialog', '__init__') self.qtapp = qtapp - self.settings = settings self.onion = onion self.setWindowTitle("OnionShare") @@ -60,7 +64,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog): def start(self): self.common.log('TorConnectionDialog', 'start') - t = TorConnectionThread(self.common, self, self.settings, self.onion) + t = TorConnectionThread(self.common, self.settings, self, self.onion) 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) @@ -116,15 +120,16 @@ class TorConnectionThread(QtCore.QThread): canceled_connecting_to_tor = QtCore.pyqtSignal() error_connecting_to_tor = QtCore.pyqtSignal(str) - def __init__(self, common, dialog, settings, onion): + def __init__(self, common, settings, dialog, onion): super(TorConnectionThread, self).__init__() self.common = common self.common.log('TorConnectionThread', '__init__') - self.dialog = dialog self.settings = settings + + self.dialog = dialog self.onion = onion def run(self):