diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 0c54303b..9b7a35bd 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -316,14 +316,18 @@ class OnionShareGui(QtWidgets.QMainWindow): self.filesize_warning.setText(strings._("large_filesize", True)) self.filesize_warning.show() - if self.server_status.server_shutdown_timeout_checkbox.isChecked(): + if self.server_status.timer_enabled: # Convert the date value to seconds between now and then now = QtCore.QDateTime.currentDateTime() - self.timeout = now.secsTo(self.server_status.server_shutdown_timeout.dateTime()) + self.timeout = now.secsTo(self.server_status.timeout) # Set the shutdown timeout value if self.timeout > 0: self.app.shutdown_timer = common.close_after_seconds(self.timeout) self.app.shutdown_timer.start() + # The timeout has actually already passed since the user clicked Start. Probably the Onion service took too long to start. + else: + self.stop_server() + self.start_server_error(strings._('gui_server_started_after_timeout')) def start_server_error(self, error): """ @@ -383,10 +387,11 @@ 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.timeout > 0: + if self.app.shutdown_timer and self.server_status.timer_enabled and self.timeout > 0: if not self.app.shutdown_timer.is_alive(): self.stop_server() self.status_bar.showMessage(strings._('close_on_timeout',True)) + self.server_status.shutdown_timeout_reset() # scroll to the bottom of the dl progress bar log pane # if a new download has been added @@ -432,6 +437,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # close on finish? if not web.get_stay_open(): self.server_status.stop_server() + self.server_status.shutdown_timeout_reset() elif event["type"] == web.REQUEST_CANCELED: self.downloads.cancel_download(event["data"]["id"]) diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 99281773..297bb791 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ import platform +from .alert import Alert from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings, common @@ -44,15 +45,19 @@ class ServerStatus(QtWidgets.QVBoxLayout): self.web = web self.file_selection = file_selection - # shutdown timeout layout + # Helper boolean as this is used in a few places + self.timer_enabled = False + # Shutdown timeout layout self.server_shutdown_timeout_checkbox = QtWidgets.QCheckBox() self.server_shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Unchecked) self.server_shutdown_timeout_checkbox.toggled.connect(self.shutdown_timeout_toggled) self.server_shutdown_timeout_checkbox.setText(strings._("gui_settings_shutdown_timeout_choice", True)) self.server_shutdown_timeout_label = QtWidgets.QLabel(strings._('gui_settings_shutdown_timeout', True)) self.server_shutdown_timeout = QtWidgets.QDateTimeEdit() + # Set proposed timeout to be 5 minutes into the future self.server_shutdown_timeout.setDateTime(QtCore.QDateTime.currentDateTime().addSecs(300)) - self.server_shutdown_timeout.setMinimumDateTime(QtCore.QDateTime.currentDateTime()) + # Onion services can take a little while to start, so reduce the risk of it expiring too soon by setting the minimum to 2 min from now + self.server_shutdown_timeout.setMinimumDateTime(QtCore.QDateTime.currentDateTime().addSecs(120)) self.server_shutdown_timeout.setCurrentSectionIndex(4) self.server_shutdown_timeout_label.hide() self.server_shutdown_timeout.hide() @@ -99,16 +104,26 @@ class ServerStatus(QtWidgets.QVBoxLayout): Shutdown timer option was toggled. If checked, hide the option and show the timer settings. """ if checked: + self.timer_enabled = True + # Hide the checkbox, show the options self.server_shutdown_timeout_checkbox.hide() self.server_shutdown_timeout_label.show() # Reset the default timer to 5 minutes into the future after toggling the option on self.server_shutdown_timeout.setDateTime(QtCore.QDateTime.currentDateTime().addSecs(300)) self.server_shutdown_timeout.show() else: + self.timer_enabled = False self.server_shutdown_timeout_checkbox.show() self.server_shutdown_timeout_label.hide() self.server_shutdown_timeout.hide() + def shutdown_timeout_reset(self): + """ + Reset the timeout in the UI after stopping a share + """ + self.server_shutdown_timeout.setDateTime(QtCore.QDateTime.currentDateTime().addSecs(300)) + self.server_shutdown_timeout.setMinimumDateTime(QtCore.QDateTime.currentDateTime().addSecs(120)) + def update(self): """ Update the GUI elements based on the current state. @@ -171,9 +186,16 @@ class ServerStatus(QtWidgets.QVBoxLayout): Toggle starting or stopping the server. """ if self.status == self.STATUS_STOPPED: - self.start_server() + # 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.server_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. + if QtCore.QDateTime.currentDateTime().toPyDateTime() > self.timeout: + Alert(strings._('gui_server_timeout_expired', QtWidgets.QMessageBox.Warning)) + else: + self.start_server() elif self.status == self.STATUS_STARTED: self.stop_server() + self.shutdown_timeout_reset() def start_server(self): """ diff --git a/share/locale/en.json b/share/locale/en.json index 2965869e..27f4dab5 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -115,5 +115,7 @@ "gui_tor_connection_ask": "Would you like to open OnionShare settings to troubleshoot connecting to Tor?", "gui_tor_connection_ask_open_settings": "Open Settings", "gui_tor_connection_ask_quit": "Quit", - "gui_tor_connection_error_settings": "Try adjusting how OnionShare connects to the Tor network in Settings." + "gui_tor_connection_error_settings": "Try adjusting how OnionShare connects to the Tor network in Settings.", + "gui_server_started_after_timeout": "The server started after your chosen auto-timeout.\nPlease start a new share.", + "gui_server_timeout_expired": "The chosen timeout has already expired.\nPlease update the timeout and then you may start sharing." }