diff --git a/onionshare/__init__.py b/onionshare/__init__.py index 27d9506f..6ff322d2 100644 --- a/onionshare/__init__.py +++ b/onionshare/__init__.py @@ -105,7 +105,8 @@ def main(cwd=None): sys.exit() # Create the Web object - web = Web(common, stay_open, False, receive) + web = Web(common, False, receive) + web.stay_open = stay_open # Start the Onion object onion = Onion(common) diff --git a/onionshare/web.py b/onionshare/web.py index bc8699b9..42f4b6d8 100644 --- a/onionshare/web.py +++ b/onionshare/web.py @@ -38,28 +38,25 @@ from flask import ( ) from werkzeug.utils import secure_filename -from . import strings, common +from . import strings class Web(object): """ The Web object is the OnionShare web server, powered by flask """ - def __init__(self, common, stay_open, gui_mode, receive_mode=False): + def __init__(self, common, gui_mode, receive_mode=False): self.common = common # The flask app self.app = Flask(__name__, - static_folder=common.get_resource_path('static'), - template_folder=common.get_resource_path('templates')) + static_folder=self.common.get_resource_path('static'), + template_folder=self.common.get_resource_path('templates')) self.app.secret_key = self.common.random_string(8) # Debug mode? if self.common.debug: self.debug_mode() - # Stay open after the first download? - self.stay_open = stay_open - # Are we running in GUI mode? self.gui_mode = gui_mode diff --git a/onionshare_gui/__init__.py b/onionshare_gui/__init__.py index 38db94d4..a46fe009 100644 --- a/onionshare_gui/__init__.py +++ b/onionshare_gui/__init__.py @@ -24,7 +24,6 @@ from PyQt5 import QtCore, QtWidgets from onionshare import strings from onionshare.common import Common -from onionshare.web import Web from onionshare.onion import Onion from onionshare.onionshare import OnionShare @@ -100,9 +99,6 @@ def main(): if not valid: sys.exit() - # Create the Web object - web = Web(common, stay_open, True) - # Start the Onion onion = Onion(common) @@ -110,7 +106,7 @@ def main(): app = OnionShare(common, onion, local_only, stay_open, shutdown_timeout) # Launch the gui - gui = OnionShareGui(common, web, onion, qtapp, app, filenames, config, local_only) + gui = OnionShareGui(common, onion, qtapp, app, filenames, config, local_only) # Clean up when app quits def shutdown(): diff --git a/onionshare_gui/mode.py b/onionshare_gui/mode.py index debd2657..90d1ec7b 100644 --- a/onionshare_gui/mode.py +++ b/onionshare_gui/mode.py @@ -39,12 +39,11 @@ class Mode(QtWidgets.QWidget): starting_server_error = QtCore.pyqtSignal(str) set_server_active = QtCore.pyqtSignal(bool) - def __init__(self, common, qtapp, app, web, status_bar, server_status_label, system_tray, filenames=None): + def __init__(self, common, qtapp, app, status_bar, server_status_label, system_tray, filenames=None): super(Mode, self).__init__() self.common = common self.qtapp = qtapp self.app = app - self.web = web self.status_bar = status_bar self.server_status_label = server_status_label @@ -52,8 +51,11 @@ class Mode(QtWidgets.QWidget): self.filenames = filenames + # The web object gets created in init() + self.web = None + # Server status - self.server_status = ServerStatus(self.common, self.qtapp, self.app, self.web) + self.server_status = ServerStatus(self.common, self.qtapp, self.app) self.server_status.server_started.connect(self.start_server) self.server_status.server_stopped.connect(self.stop_server) self.server_status.server_canceled.connect(self.cancel_server) @@ -102,11 +104,7 @@ class Mode(QtWidgets.QWidget): self.status_bar.clearMessage() self.server_status_label.setText('') - # Reset web counters - self.web.download_count = 0 - self.web.error404_count = 0 - - # start the onion service in a new thread + # Start the onion service in a new thread def start_onion_service(self): try: self.app.start_onion_service() @@ -116,14 +114,13 @@ class Mode(QtWidgets.QWidget): self.starting_server_error.emit(e.args[0]) return - self.app.stay_open = not self.common.settings.get('close_after_first_download') - # start onionshare http service in new thread + # Start http service in new thread 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 + # Wait for modules in thread to load, preventing a thread-related cx_Freeze crash time.sleep(0.2) self.common.log('Mode', 'start_server', 'Starting an onion thread') diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index c30142ff..c53aebb7 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -21,6 +21,7 @@ import queue from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings +from onionshare.web import Web from .share_mode import ShareMode from .receive_mode import ReceiveMode @@ -39,19 +40,19 @@ class OnionShareGui(QtWidgets.QMainWindow): MODE_SHARE = 'share' MODE_RECEIVE = 'receive' - def __init__(self, common, web, onion, qtapp, app, filenames, config=False, local_only=False): + def __init__(self, common, onion, qtapp, app, filenames, config=False, local_only=False): super(OnionShareGui, self).__init__() self.common = common self.common.log('OnionShareGui', '__init__') - self.web = web self.onion = onion self.qtapp = qtapp self.app = app self.local_only = local_only self.mode = self.MODE_SHARE + self.web = None self.setWindowTitle('OnionShare') self.setWindowIcon(QtGui.QIcon(self.common.get_resource_path('images/logo.png'))) @@ -156,8 +157,8 @@ class OnionShareGui(QtWidgets.QMainWindow): self.server_status_label.setStyleSheet('QLabel { font-style: italic; color: #666666; padding: 2px; }') self.status_bar.insertWidget(0, self.server_status_label) - # Share and receive mode widgets - self.share_mode = ShareMode(self.common, qtapp, app, web, self.status_bar, self.server_status_label, self.system_tray, filenames) + # Share mode + self.share_mode = ShareMode(self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray, filenames) 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) @@ -169,7 +170,9 @@ class OnionShareGui(QtWidgets.QMainWindow): 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) - self.receive_mode = ReceiveMode(self.common, qtapp, app, web, self.status_bar, self.server_status_label, self.system_tray) + + # Receive mode + self.receive_mode = ReceiveMode(self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray) self.receive_mode.init() self.receive_mode.set_server_active.connect(self.set_server_active) @@ -371,34 +374,36 @@ class OnionShareGui(QtWidgets.QMainWindow): self.share_mode.handle_tor_broke() - events = [] + # If we have a web object, process events from it + if self.web: + events = [] - done = False - while not done: - try: - r = self.web.q.get(False) - events.append(r) - except queue.Empty: - done = True + done = False + while not done: + try: + r = self.web.q.get(False) + events.append(r) + except queue.Empty: + done = True - for event in events: - if event["type"] == self.web.REQUEST_LOAD: - self.share_mode.handle_request_load(event) + for event in events: + if event["type"] == Web.REQUEST_LOAD: + self.share_mode.handle_request_load(event) - elif event["type"] == self.web.REQUEST_DOWNLOAD: - self.share_mode.handle_request_download(event) + elif event["type"] == Web.REQUEST_DOWNLOAD: + self.share_mode.handle_request_download(event) - elif event["type"] == self.web.REQUEST_RATE_LIMIT: - self.share_mode.handle_request_rate_limit(event) + elif event["type"] == Web.REQUEST_RATE_LIMIT: + self.share_mode.handle_request_rate_limit(event) - elif event["type"] == self.web.REQUEST_PROGRESS: - self.share_mode.handle_request_progress(event) + elif event["type"] == Web.REQUEST_PROGRESS: + self.share_mode.handle_request_progress(event) - elif event["type"] == self.web.REQUEST_CANCELED: - self.share_mode.handle_request_canceled(event) + elif event["type"] == Web.REQUEST_CANCELED: + self.share_mode.handle_request_canceled(event) - elif event["path"] != '/favicon.ico': - self.status_bar.showMessage('[#{0:d}] {1:s}: {2:s}'.format(self.web.error404_count, strings._('other_page_loaded', True), event["path"])) + elif event["path"] != '/favicon.ico': + self.status_bar.showMessage('[#{0:d}] {1:s}: {2:s}'.format(self.web.error404_count, strings._('other_page_loaded', True), event["path"])) if self.mode == self.MODE_SHARE: self.share_mode.timer_callback() diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index b7813170..76e8b30b 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -20,6 +20,7 @@ along with this program. If not, see . from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings +from onionshare.web import Web from ..mode import Mode @@ -31,6 +32,13 @@ class ReceiveMode(Mode): """ Custom initialization for ReceiveMode. """ + # Create the Web object + self.web = Web(self.common, True, True) + + # Tell server_status about web, then update + self.server_status.web = self.web + self.server_status.update() + # Receive mode info self.receive_info = QtWidgets.QLabel(strings._('gui_receive_mode_warning', True)) self.receive_info.setMinimumHeight(80) @@ -47,7 +55,10 @@ class ReceiveMode(Mode): def start_server_step2_custom(self): """ - Step 2 in starting the server. Nothing to do here but move on to step 3. + Step 2 in starting the server. """ + # Set up web + + # Continue self.starting_server_step3.emit() self.start_server_finished.emit() diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 602af595..2e087eb5 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -39,7 +39,7 @@ class ServerStatus(QtWidgets.QWidget): STATUS_WORKING = 1 STATUS_STARTED = 2 - def __init__(self, common, qtapp, app, web, file_selection=None): + def __init__(self, common, qtapp, app, file_selection=None): super(ServerStatus, self).__init__() self.common = common @@ -49,7 +49,8 @@ class ServerStatus(QtWidgets.QWidget): self.qtapp = qtapp self.app = app - self.web = web + + self.web = None # Shutdown timeout layout self.shutdown_timeout_label = QtWidgets.QLabel(strings._('gui_settings_shutdown_timeout', True)) @@ -112,8 +113,6 @@ class ServerStatus(QtWidgets.QWidget): layout.addLayout(url_layout) layout.addWidget(self.shutdown_timeout_container) self.setLayout(layout) - - self.update() def set_share_mode(self, file_selection): """ @@ -121,6 +120,7 @@ class ServerStatus(QtWidgets.QWidget): """ self.share_mode = True self.file_selection = file_selection + self.update() def shutdown_timeout_reset(self): """ diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index 0d05da06..c905a80d 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -24,6 +24,7 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.onion import * from onionshare.common import Common +from onionshare.web import Web from .file_selection import FileSelection from .downloads import Downloads @@ -39,6 +40,9 @@ class ShareMode(Mode): """ Custom initialization for ReceiveMode. """ + # Create the Web object + self.web = Web(self.common, True, False) + # File selection self.file_selection = FileSelection(self.common) if self.filenames: @@ -54,6 +58,9 @@ class ShareMode(Mode): self.server_status.server_canceled.connect(self.update_primary_action) self.file_selection.file_list.files_updated.connect(self.server_status.update) self.file_selection.file_list.files_updated.connect(self.update_primary_action) + # Tell server_status about web, then update + self.server_status.web = self.web + self.server_status.update() # Filesize warning self.filesize_warning = QtWidgets.QLabel() @@ -143,6 +150,10 @@ class ShareMode(Mode): """ Starting the server. """ + # Reset web counters + self.web.download_count = 0 + self.web.error404_count = 0 + # Hide and reset the downloads if we have previously shared self.downloads.reset_downloads() self.reset_info_counters()