def main(): """ The main() function implements all of the logic that the GUI version of onionshare uses. """ common = Common() common.define_css() # Load the default settings and strings early, for the sake of being able to parse options. # These won't be in the user's chosen locale necessarily, but we need to parse them # early in order to even display the option to pass alternate settings (which might # contain a preferred locale). # If an alternate --config is passed, we'll reload strings later. common.load_settings() strings.load_strings(common) # Display OnionShare banner print(strings._('version_string').format(common.version)) # Allow Ctrl-C to smoothly quit the program instead of throwing an exception # https://stackoverflow.com/questions/42814093/how-to-handle-ctrlc-in-python-app-with-pyqt signal.signal(signal.SIGINT, signal.SIG_DFL) # Start the Qt app global qtapp qtapp = Application(common) # Parse arguments parser = argparse.ArgumentParser(formatter_class=lambda prog: argparse. HelpFormatter(prog, max_help_position=48)) parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only")) parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug")) parser.add_argument('--filenames', metavar='filenames', nargs='+', help=strings._('help_filename')) parser.add_argument('--config', metavar='config', default=False, help=strings._('help_config')) args = parser.parse_args() filenames = args.filenames if filenames: for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) config = args.config if config: # Re-load the strings, in case the provided config has changed locale common.load_settings(config) strings.load_strings(common) local_only = bool(args.local_only) debug = bool(args.debug) # Debug mode? common.debug = debug # Validation if filenames: valid = True for filename in filenames: if not os.path.isfile(filename) and not os.path.isdir(filename): Alert(common, strings._("not_a_file").format(filename)) valid = False if not os.access(filename, os.R_OK): Alert(common, strings._("not_a_readable_file").format(filename)) valid = False if not valid: sys.exit() # Start the Onion onion = Onion(common) # Start the OnionShare app app = OnionShare(common, onion, local_only) # Launch the gui gui = OnionShareGui(common, onion, qtapp, app, filenames, config, local_only) # Clean up when app quits def shutdown(): onion.cleanup() app.cleanup() qtapp.aboutToQuit.connect(shutdown) # All done sys.exit(qtapp.exec_())
def main(): """ The main() function implements all of the logic that the GUI version of onionshare uses. """ common = Common() common.define_css() # Display OnionShare banner print("OnionShare {0:s} | https://onionshare.org/".format(common.version)) # Allow Ctrl-C to smoothly quit the program instead of throwing an exception # https://stackoverflow.com/questions/42814093/how-to-handle-ctrlc-in-python-app-with-pyqt signal.signal(signal.SIGINT, signal.SIG_DFL) # Start the Qt app global qtapp qtapp = Application(common) # Parse arguments parser = argparse.ArgumentParser( formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=48) ) parser.add_argument( "--local-only", action="store_true", dest="local_only", help="Don't use Tor (only for development)", ) parser.add_argument( "-v", "--verbose", action="store_true", dest="verbose", help="Log OnionShare errors to stdout, and web errors to disk", ) parser.add_argument( "--filenames", metavar="filenames", nargs="+", help="List of files or folders to share", ) parser.add_argument( "--config", metavar="config", default=False, help="Custom JSON config file location (optional)", ) args = parser.parse_args() filenames = args.filenames if filenames: for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) config = args.config if config: common.load_settings(config) local_only = bool(args.local_only) verbose = bool(args.verbose) # Verbose mode? common.verbose = verbose # Validation if filenames: valid = True for filename in filenames: if not os.path.isfile(filename) and not os.path.isdir(filename): Alert(common, "{0:s} is not a valid file.".format(filename)) valid = False if not os.access(filename, os.R_OK): Alert(common, "{0:s} is not a readable file.".format(filename)) valid = False if not valid: sys.exit() # Start the Onion onion = Onion(common) # Start the OnionShare app app = OnionShare(common, onion, local_only) # Launch the gui gui = OnionShareGui(common, onion, qtapp, app, filenames, config, local_only) # Clean up when app quits def shutdown(): onion.cleanup() app.cleanup() qtapp.aboutToQuit.connect(shutdown) # All done sys.exit(qtapp.exec_())
class Tab(QtWidgets.QWidget): """ A GUI tab, you know, sort of like in a web browser """ change_title = QtCore.pyqtSignal(int, str) change_icon = QtCore.pyqtSignal(int, str) change_persistent = QtCore.pyqtSignal(int, bool) def __init__( self, common, tab_id, system_tray, status_bar, mode_settings=None, filenames=None, ): super(Tab, self).__init__() self.common = common self.common.log("Tab", "__init__") self.tab_id = tab_id self.system_tray = system_tray self.status_bar = status_bar self.filenames = filenames self.mode = None # Start the OnionShare app self.app = OnionShare(common, self.common.gui.onion, self.common.gui.local_only) # New tab buttons self.share_button = NewTabButton( self.common, "images/mode_new_tab_share.png", strings._("gui_new_tab_share_button"), ) self.share_button.clicked.connect(self.share_mode_clicked) self.receive_button = NewTabButton( self.common, "images/mode_new_tab_receive.png", strings._("gui_new_tab_receive_button"), ) self.receive_button.clicked.connect(self.receive_mode_clicked) self.website_button = NewTabButton( self.common, "images/mode_new_tab_website.png", strings._("gui_new_tab_website_button"), ) self.website_button.clicked.connect(self.website_mode_clicked) self.chat_button = NewTabButton( self.common, "images/mode_new_tab_chat.png", strings._("gui_new_tab_chat_button"), ) self.chat_button.clicked.connect(self.chat_mode_clicked) new_tab_top_layout = QtWidgets.QHBoxLayout() new_tab_top_layout.addStretch() new_tab_top_layout.addWidget(self.share_button) new_tab_top_layout.addWidget(self.receive_button) new_tab_top_layout.addStretch() new_tab_bottom_layout = QtWidgets.QHBoxLayout() new_tab_bottom_layout.addStretch() new_tab_bottom_layout.addWidget(self.website_button) new_tab_bottom_layout.addWidget(self.chat_button) new_tab_bottom_layout.addStretch() new_tab_layout = QtWidgets.QVBoxLayout() new_tab_layout.addStretch() new_tab_layout.addLayout(new_tab_top_layout) new_tab_layout.addLayout(new_tab_bottom_layout) new_tab_layout.addStretch() self.new_tab = QtWidgets.QWidget() self.new_tab.setLayout(new_tab_layout) self.new_tab.show() # Layout self.layout = QtWidgets.QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.new_tab) self.setLayout(self.layout) # Create the timer self.timer = QtCore.QTimer() self.timer.timeout.connect(self.timer_callback) # Persistent image self.persistent_image_label = QtWidgets.QLabel() self.persistent_image_label.setPixmap( QtGui.QPixmap.fromImage( QtGui.QImage( self.common.get_resource_path("images/persistent_enabled.png") ) ) ) self.persistent_image_label.setFixedSize(20, 20) # Create the close warning dialog -- the dialog widget needs to be in the constructor # in order to test it self.close_dialog = QtWidgets.QMessageBox() self.close_dialog.setWindowTitle(strings._("gui_close_tab_warning_title")) self.close_dialog.setIcon(QtWidgets.QMessageBox.Critical) self.close_dialog.accept_button = self.close_dialog.addButton( strings._("gui_close_tab_warning_close"), QtWidgets.QMessageBox.AcceptRole ) self.close_dialog.reject_button = self.close_dialog.addButton( strings._("gui_close_tab_warning_cancel"), QtWidgets.QMessageBox.RejectRole ) self.close_dialog.setDefaultButton(self.close_dialog.reject_button) def init(self, mode_settings=None): if mode_settings: # Load this tab self.settings = mode_settings mode = self.settings.get("persistent", "mode") if mode == "share": self.filenames = self.settings.get("share", "filenames") self.share_mode_clicked() elif mode == "receive": self.receive_mode_clicked() elif mode == "website": self.filenames = self.settings.get("website", "filenames") self.website_mode_clicked() else: # This is a new tab self.settings = ModeSettings(self.common) def share_mode_clicked(self): self.common.log("Tab", "share_mode_clicked") self.mode = self.common.gui.MODE_SHARE self.new_tab.hide() self.share_mode = ShareMode(self) self.share_mode.change_persistent.connect(self.change_persistent) self.layout.addWidget(self.share_mode) self.share_mode.show() 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.change_title.emit(self.tab_id, strings._("gui_tab_name_share")) self.update_server_status_indicator() self.timer.start(500) def receive_mode_clicked(self): self.common.log("Tab", "receive_mode_clicked") self.mode = self.common.gui.MODE_RECEIVE self.new_tab.hide() self.receive_mode = ReceiveMode(self) self.receive_mode.change_persistent.connect(self.change_persistent) self.layout.addWidget(self.receive_mode) self.receive_mode.show() 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.change_title.emit(self.tab_id, strings._("gui_tab_name_receive")) self.update_server_status_indicator() self.timer.start(500) def website_mode_clicked(self): self.common.log("Tab", "website_mode_clicked") self.mode = self.common.gui.MODE_WEBSITE self.new_tab.hide() self.website_mode = WebsiteMode(self) self.website_mode.change_persistent.connect(self.change_persistent) self.layout.addWidget(self.website_mode) self.website_mode.show() 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.change_title.emit(self.tab_id, strings._("gui_tab_name_website")) self.update_server_status_indicator() self.timer.start(500) def chat_mode_clicked(self): self.common.log("Tab", "chat_mode_clicked") self.mode = self.common.gui.MODE_CHAT self.new_tab.hide() self.chat_mode = ChatMode(self) self.chat_mode.change_persistent.connect(self.change_persistent) self.layout.addWidget(self.chat_mode) self.chat_mode.show() self.chat_mode.init() self.chat_mode.server_status.server_started.connect( self.update_server_status_indicator ) self.chat_mode.server_status.server_stopped.connect( self.update_server_status_indicator ) self.chat_mode.start_server_finished.connect( self.update_server_status_indicator ) self.chat_mode.stop_server_finished.connect(self.update_server_status_indicator) self.chat_mode.stop_server_finished.connect(self.stop_server_finished) self.chat_mode.start_server_finished.connect(self.clear_message) self.chat_mode.server_status.button_clicked.connect(self.clear_message) self.chat_mode.server_status.url_copied.connect(self.copy_url) self.chat_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) self.change_title.emit(self.tab_id, strings._("gui_tab_name_chat")) self.update_server_status_indicator() self.timer.start(500) 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.set_server_status_indicator_stopped( strings._("gui_status_indicator_share_stopped") ) elif self.share_mode.server_status.status == ServerStatus.STATUS_WORKING: if self.settings.get("general", "autostart_timer"): self.set_server_status_indicator_working( strings._("gui_status_indicator_share_scheduled") ) else: self.set_server_status_indicator_working( strings._("gui_status_indicator_share_working") ) elif self.share_mode.server_status.status == ServerStatus.STATUS_STARTED: self.set_server_status_indicator_started( 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.set_server_status_indicator_stopped( strings._("gui_status_indicator_share_stopped") ) elif self.website_mode.server_status.status == ServerStatus.STATUS_WORKING: if self.website_mode.server_status.autostart_timer_datetime: self.set_server_status_indicator_working( strings._("gui_status_indicator_share_scheduled") ) else: self.set_server_status_indicator_working( strings._("gui_status_indicator_share_working") ) elif self.website_mode.server_status.status == ServerStatus.STATUS_STARTED: self.set_server_status_indicator_started( strings._("gui_status_indicator_share_started") ) elif self.mode == self.common.gui.MODE_RECEIVE: # Receive mode if self.receive_mode.server_status.status == ServerStatus.STATUS_STOPPED: self.set_server_status_indicator_stopped( strings._("gui_status_indicator_receive_stopped") ) elif self.receive_mode.server_status.status == ServerStatus.STATUS_WORKING: if self.settings.get("general", "autostart_timer"): self.set_server_status_indicator_working( strings._("gui_status_indicator_receive_scheduled") ) else: self.set_server_status_indicator_working( strings._("gui_status_indicator_receive_working") ) elif self.receive_mode.server_status.status == ServerStatus.STATUS_STARTED: self.set_server_status_indicator_started( strings._("gui_status_indicator_receive_started") ) elif self.mode == self.common.gui.MODE_CHAT: # Chat mode if self.chat_mode.server_status.status == ServerStatus.STATUS_STOPPED: self.set_server_status_indicator_stopped( strings._("gui_status_indicator_receive_stopped") ) elif self.chat_mode.server_status.status == ServerStatus.STATUS_WORKING: if self.settings.get("general", "autostart_timer"): self.set_server_status_indicator_working( strings._("gui_status_indicator_receive_scheduled") ) else: self.set_server_status_indicator_working( strings._("gui_status_indicator_receive_working") ) elif self.chat_mode.server_status.status == ServerStatus.STATUS_STARTED: self.set_server_status_indicator_started( strings._("gui_status_indicator_receive_started") ) def set_server_status_indicator_stopped(self, label_text): self.change_icon.emit(self.tab_id, "images/server_stopped.png") self.status_bar.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.status_bar.server_status_image_stopped) ) self.status_bar.server_status_label.setText(label_text) def set_server_status_indicator_working(self, label_text): self.change_icon.emit(self.tab_id, "images/server_working.png") self.status_bar.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.status_bar.server_status_image_working) ) self.status_bar.server_status_label.setText(label_text) def set_server_status_indicator_started(self, label_text): self.change_icon.emit(self.tab_id, "images/server_started.png") self.status_bar.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.status_bar.server_status_image_started) ) self.status_bar.server_status_label.setText(label_text) def stop_server_finished(self): # When the server stopped, cleanup the ephemeral onion service self.get_mode().app.stop_onion_service(self.settings) 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.get_mode().handle_tor_broke() # Process events from the web object mode = self.get_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 clear_message(self): """ Clear messages from the status bar. """ self.status_bar.clearMessage() def get_mode(self): if self.mode: if self.mode == self.common.gui.MODE_SHARE: return self.share_mode elif self.mode == self.common.gui.MODE_RECEIVE: return self.receive_mode elif self.mode == self.common.gui.MODE_CHAT: return self.chat_mode else: return self.website_mode else: return None def settings_have_changed(self): # Global settings have changed self.common.log("Tab", "settings_have_changed") # 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. if not self.common.gui.local_only: if self.common.gui.onion.is_authenticated(): mode = self.get_mode() if mode: if not self.timer.isActive(): self.timer.start(500) mode.on_reload_settings() def close_tab(self): self.common.log("Tab", "close_tab") if self.mode is None: return True if self.settings.get("persistent", "enabled"): dialog_text = strings._("gui_close_tab_warning_persistent_description") else: server_status = self.get_mode().server_status if server_status.status == server_status.STATUS_STOPPED: return True else: if self.mode == self.common.gui.MODE_SHARE: dialog_text = strings._("gui_close_tab_warning_share_description") elif self.mode == self.common.gui.MODE_RECEIVE: dialog_text = strings._("gui_close_tab_warning_receive_description") else: dialog_text = strings._("gui_close_tab_warning_website_description") # Open the warning dialog self.common.log("Tab", "close_tab, opening warning dialog") self.close_dialog.setText(dialog_text) self.close_dialog.exec_() # Close if self.close_dialog.clickedButton() == self.close_dialog.accept_button: self.common.log("Tab", "close_tab", "close, closing tab") self.get_mode().stop_server() self.app.cleanup() return True # Cancel else: self.common.log("Tab", "close_tab", "cancel, keeping tab open") return False def cleanup(self): self.app.cleanup()
def __init__( self, common, tab_id, system_tray, status_bar, mode_settings=None, filenames=None, ): super(Tab, self).__init__() self.common = common self.common.log("Tab", "__init__") self.tab_id = tab_id self.system_tray = system_tray self.status_bar = status_bar self.filenames = filenames self.mode = None # Start the OnionShare app self.app = OnionShare(common, self.common.gui.onion, self.common.gui.local_only) # New tab buttons self.share_button = NewTabButton( self.common, "images/mode_new_tab_share.png", strings._("gui_new_tab_share_button"), ) self.share_button.clicked.connect(self.share_mode_clicked) self.receive_button = NewTabButton( self.common, "images/mode_new_tab_receive.png", strings._("gui_new_tab_receive_button"), ) self.receive_button.clicked.connect(self.receive_mode_clicked) self.website_button = NewTabButton( self.common, "images/mode_new_tab_website.png", strings._("gui_new_tab_website_button"), ) self.website_button.clicked.connect(self.website_mode_clicked) self.chat_button = NewTabButton( self.common, "images/mode_new_tab_chat.png", strings._("gui_new_tab_chat_button"), ) self.chat_button.clicked.connect(self.chat_mode_clicked) new_tab_top_layout = QtWidgets.QHBoxLayout() new_tab_top_layout.addStretch() new_tab_top_layout.addWidget(self.share_button) new_tab_top_layout.addWidget(self.receive_button) new_tab_top_layout.addStretch() new_tab_bottom_layout = QtWidgets.QHBoxLayout() new_tab_bottom_layout.addStretch() new_tab_bottom_layout.addWidget(self.website_button) new_tab_bottom_layout.addWidget(self.chat_button) new_tab_bottom_layout.addStretch() new_tab_layout = QtWidgets.QVBoxLayout() new_tab_layout.addStretch() new_tab_layout.addLayout(new_tab_top_layout) new_tab_layout.addLayout(new_tab_bottom_layout) new_tab_layout.addStretch() self.new_tab = QtWidgets.QWidget() self.new_tab.setLayout(new_tab_layout) self.new_tab.show() # Layout self.layout = QtWidgets.QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.new_tab) self.setLayout(self.layout) # Create the timer self.timer = QtCore.QTimer() self.timer.timeout.connect(self.timer_callback) # Persistent image self.persistent_image_label = QtWidgets.QLabel() self.persistent_image_label.setPixmap( QtGui.QPixmap.fromImage( QtGui.QImage( self.common.get_resource_path("images/persistent_enabled.png") ) ) ) self.persistent_image_label.setFixedSize(20, 20) # Create the close warning dialog -- the dialog widget needs to be in the constructor # in order to test it self.close_dialog = QtWidgets.QMessageBox() self.close_dialog.setWindowTitle(strings._("gui_close_tab_warning_title")) self.close_dialog.setIcon(QtWidgets.QMessageBox.Critical) self.close_dialog.accept_button = self.close_dialog.addButton( strings._("gui_close_tab_warning_close"), QtWidgets.QMessageBox.AcceptRole ) self.close_dialog.reject_button = self.close_dialog.addButton( strings._("gui_close_tab_warning_cancel"), QtWidgets.QMessageBox.RejectRole ) self.close_dialog.setDefaultButton(self.close_dialog.reject_button)
def main(): """ The main() function implements all of the logic that the GUI version of onionshare uses. """ strings.load_strings(common) print(strings._('version_string').format(common.get_version())) # Start the Qt app global qtapp qtapp = Application() # Parse arguments parser = argparse.ArgumentParser() parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only")) parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open")) parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug")) parser.add_argument('--filenames', metavar='filenames', nargs='+', help=strings._('help_filename')) parser.add_argument('--config', metavar='config', default=False, help=strings._('help_config')) args = parser.parse_args() filenames = args.filenames if filenames: for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) config = args.config local_only = bool(args.local_only) stay_open = bool(args.stay_open) debug = bool(args.debug) # Debug mode? if debug: common.set_debug(debug) web.debug_mode() # Validation if filenames: valid = True for filename in filenames: if not os.path.exists(filename): Alert(strings._("not_a_file", True).format(filename)) valid = False if not os.access(filename, os.R_OK): Alert(strings._("not_a_readable_file", True).format(filename)) valid = False if not valid: sys.exit() # Start the Onion onion = Onion() # Start the OnionShare app web.set_stay_open(stay_open) app = OnionShare(onion, local_only, stay_open) # Launch the gui gui = OnionShareGui(onion, qtapp, app, filenames, config) # Clean up when app quits def shutdown(): onion.cleanup() app.cleanup() qtapp.aboutToQuit.connect(shutdown) # All done sys.exit(qtapp.exec_())