Example #1
0
 def update_downloads_in_progress(self, count):
     """
     Update the 'Downloads in progress' info widget.
     """
     if count == 0:
         self.info_in_progress_downloads_image = common.get_resource_path('images/download_in_progress_none.png')
     else:
         self.info_in_progress_downloads_image = common.get_resource_path('images/download_in_progress.png')
     self.info_in_progress_downloads_count.setText('<img src="{0:s}" /> {1:d}'.format(self.info_in_progress_downloads_image, count))
     self.info_in_progress_downloads_count.setToolTip(strings._('info_in_progress_downloads_tooltip', True).format(count))
    def set_server_active(self, active):
        """
        Disable the Settings button while an OnionShare server is active.
        """
        self.settings_button.setEnabled(not active)
        if active:
            self.settings_button.setIcon( QtGui.QIcon(common.get_resource_path('images/settings_inactive.png')) )
        else:
            self.settings_button.setIcon( QtGui.QIcon(common.get_resource_path('images/settings.png')) )

        # Disable settings menu action when server is active
        self.settingsAction.setEnabled(not active)
Example #3
0
    def set_server_active(self, active):
        """
        Disable the Settings button while an OnionShare server is active.
        """
        self.settings_button.setEnabled(not active)
        if active:
            self.settings_button.setIcon( QtGui.QIcon(common.get_resource_path('images/settings_inactive.png')) )
        else:
            self.settings_button.setIcon( QtGui.QIcon(common.get_resource_path('images/settings.png')) )

        # Disable settings menu action when server is active
        self.settingsAction.setEnabled(not active)
Example #4
0
    def _initSystemTray(self):
        system = common.get_platform()

        menu = QtWidgets.QMenu()
        exitAction = menu.addAction(strings._('systray_menu_exit', True))
        exitAction.triggered.connect(self.close)

        self.systemTray = QtWidgets.QSystemTrayIcon(self)
        # The convention is Mac systray icons are always grayscale
        if system == 'Darwin':
            self.systemTray.setIcon(QtGui.QIcon(common.get_resource_path('images/logo_grayscale.png')))
        else:
            self.systemTray.setIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.systemTray.setContextMenu(menu)
        self.systemTray.show()
Example #5
0
 def update_downloads_completed(self, count):
     """
     Update the 'Downloads completed' info widget.
     """
     if count == 0:
         self.info_completed_downloads_image = common.get_resource_path(
             'images/download_completed_none.png')
     else:
         self.info_completed_downloads_image = common.get_resource_path(
             'images/download_completed.png')
     self.info_completed_downloads_count.setText(
         '<img src="{0:s}" /> {1:d}'.format(
             self.info_completed_downloads_image, count))
     self.info_completed_downloads_count.setToolTip(
         strings._('info_completed_downloads_tooltip', True).format(count))
Example #6
0
    def __init__(self, qtapp, app, web, file_selection):
        super(ServerStatus, self).__init__()
        self.status = self.STATUS_STOPPED

        self.qtapp = qtapp
        self.app = app
        self.web = web
        self.file_selection = file_selection

        # server layout
        self.status_image_stopped = QtGui.QImage(
            common.get_resource_path('images/server_stopped.png'))
        self.status_image_working = QtGui.QImage(
            common.get_resource_path('images/server_working.png'))
        self.status_image_started = QtGui.QImage(
            common.get_resource_path('images/server_started.png'))
        self.status_image_label = QtWidgets.QLabel()
        self.status_image_label.setFixedWidth(30)
        self.server_button = QtWidgets.QPushButton()
        self.server_button.clicked.connect(self.server_button_clicked)
        server_layout = QtWidgets.QHBoxLayout()
        server_layout.addWidget(self.status_image_label)
        server_layout.addWidget(self.server_button)

        # url layout
        url_font = QtGui.QFont()
        self.url_label = QtWidgets.QLabel()
        self.url_label.setFont(url_font)
        self.url_label.setWordWrap(False)
        self.url_label.setAlignment(QtCore.Qt.AlignCenter)
        self.copy_url_button = QtWidgets.QPushButton(
            strings._('gui_copy_url', True))
        self.copy_url_button.clicked.connect(self.copy_url)
        self.copy_hidservauth_button = QtWidgets.QPushButton(
            strings._('gui_copy_hidservauth', True))
        self.copy_hidservauth_button.clicked.connect(self.copy_hidservauth)
        url_layout = QtWidgets.QHBoxLayout()
        url_layout.addWidget(self.url_label)
        url_layout.addWidget(self.copy_url_button)
        url_layout.addWidget(self.copy_hidservauth_button)

        # add the widgets
        self.addLayout(server_layout)
        self.addLayout(url_layout)

        self.update()
 def test_onionshare_dev_mode(self, sys_onionshare_dev_mode):
     prefix = os.path.join(
         os.path.dirname(
             os.path.dirname(
                 os.path.abspath(inspect.getfile(inspect.currentframe())))),
         'share')
     assert (common.get_resource_path(os.path.join(
         prefix, 'test_filename')) == os.path.join(prefix, 'test_filename'))
Example #8
0
    def _initSystemTray(self):
        system = common.get_platform()

        menu = QtWidgets.QMenu()
        self.settingsAction = menu.addAction(strings._('gui_settings_window_title', True))
        self.settingsAction.triggered.connect(self.open_settings)
        self.helpAction = menu.addAction(strings._('gui_settings_button_help', True))
        self.helpAction.triggered.connect(SettingsDialog.help_clicked)
        self.exitAction = menu.addAction(strings._('systray_menu_exit', True))
        self.exitAction.triggered.connect(self.close)

        self.systemTray = QtWidgets.QSystemTrayIcon(self)
        # The convention is Mac systray icons are always grayscale
        if system == 'Darwin':
            self.systemTray.setIcon(QtGui.QIcon(common.get_resource_path('images/logo_grayscale.png')))
        else:
            self.systemTray.setIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.systemTray.setContextMenu(menu)
        self.systemTray.show()
Example #9
0
    def _initSystemTray(self):
        system = common.get_platform()

        menu = QtWidgets.QMenu()
        self.settingsAction = menu.addAction(strings._('gui_settings_window_title', True))
        self.settingsAction.triggered.connect(self.open_settings)
        self.helpAction = menu.addAction(strings._('gui_settings_button_help', True))
        self.helpAction.triggered.connect(SettingsDialog.help_clicked)
        self.exitAction = menu.addAction(strings._('systray_menu_exit', True))
        self.exitAction.triggered.connect(self.close)

        self.systemTray = QtWidgets.QSystemTrayIcon(self)
        # The convention is Mac systray icons are always grayscale
        if system == 'Darwin':
            self.systemTray.setIcon(QtGui.QIcon(common.get_resource_path('images/logo_grayscale.png')))
        else:
            self.systemTray.setIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.systemTray.setContextMenu(menu)
        self.systemTray.show()
 def test_onionshare_dev_mode(self, sys_onionshare_dev_mode):
     prefix = os.path.join(
         os.path.dirname(
             os.path.dirname(
                 os.path.abspath(
                     inspect.getfile(
                         inspect.currentframe())))), 'share')
     assert (
         common.get_resource_path(os.path.join(prefix, 'test_filename')) ==
         os.path.join(prefix, 'test_filename'))
 def test_get_tor_paths_darwin(self, platform_darwin, sys_frozen,
                               sys_meipass):
     base_path = os.path.dirname(
         os.path.dirname(os.path.dirname(common.get_resource_path(''))))
     tor_path = os.path.join(base_path, 'Resources', 'Tor', 'tor')
     tor_geo_ip_file_path = os.path.join(base_path, 'Resources', 'Tor',
                                         'geoip')
     tor_geo_ipv6_file_path = os.path.join(base_path, 'Resources', 'Tor',
                                           'geoip6')
     assert (common.get_tor_paths() == (tor_path, tor_geo_ip_file_path,
                                        tor_geo_ipv6_file_path))
 def test_get_tor_paths_windows(self, platform_windows, sys_frozen):
     base_path = os.path.join(
         os.path.dirname(os.path.dirname(common.get_resource_path(''))),
         'tor')
     tor_path = os.path.join(os.path.join(base_path, 'Tor'), "tor.exe")
     tor_geo_ip_file_path = os.path.join(
         os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip')
     tor_geo_ipv6_file_path = os.path.join(
         os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip6')
     assert (common.get_tor_paths() == (tor_path, tor_geo_ip_file_path,
                                        tor_geo_ipv6_file_path))
Example #13
0
    def __init__(self, message, icon=QtWidgets.QMessageBox.NoIcon, buttons=QtWidgets.QMessageBox.Ok, autostart=True):
        super(Alert, self).__init__(None)
        common.log('Alert', '__init__')

        self.setWindowTitle("OnionShare")
        self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.setText(message)
        self.setIcon(icon)
        self.setStandardButtons(buttons)

        if autostart:
            self.exec_()
Example #14
0
            def __init__(self, parent, image=False):
                self.parent = parent
                super(DropHereLabel, self).__init__(parent=parent)
                self.setAcceptDrops(True)
                self.setAlignment(QtCore.Qt.AlignCenter)

                if image:
                    self.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(common.get_resource_path('images/drop_files.png'))))
                else:
                    self.setText(strings._('gui_drag_and_drop', True))
                    self.setStyleSheet('color: #999999;')

                self.hide()
 def test_get_tor_paths_darwin(self, platform_darwin, sys_frozen, sys_meipass):
     base_path = os.path.dirname(
         os.path.dirname(
             os.path.dirname(
                 common.get_resource_path(''))))
     tor_path = os.path.join(
         base_path, 'Resources', 'Tor', 'tor')
     tor_geo_ip_file_path = os.path.join(
         base_path, 'Resources', 'Tor', 'geoip')
     tor_geo_ipv6_file_path = os.path.join(
         base_path, 'Resources', 'Tor', 'geoip6')
     assert (common.get_tor_paths() ==
             (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path))
            def __init__(self, parent, image=False):
                self.parent = parent
                super(DropHereLabel, self).__init__(parent=parent)
                self.setAcceptDrops(True)
                self.setAlignment(QtCore.Qt.AlignCenter)

                if image:
                    self.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(common.get_resource_path('images/drop_files.png'))))
                else:
                    self.setText(strings._('gui_drag_and_drop', True))
                    self.setStyleSheet('color: #999999;')

                self.hide()
 def test_get_tor_paths_windows(self, platform_windows, sys_frozen):
     base_path = os.path.join(
         os.path.dirname(
             os.path.dirname(
                 common.get_resource_path(''))), 'tor')
     tor_path = os.path.join(
         os.path.join(base_path, 'Tor'), "tor.exe")
     tor_geo_ip_file_path = os.path.join(
         os.path.join(
             os.path.join(base_path, 'Data'), 'Tor'), 'geoip')
     tor_geo_ipv6_file_path = os.path.join(
         os.path.join(
             os.path.join(base_path, 'Data'), 'Tor'), 'geoip6')
     assert (common.get_tor_paths() ==
             (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path))
Example #18
0
    def __init__(self,
                 message,
                 icon=QtWidgets.QMessageBox.NoIcon,
                 buttons=QtWidgets.QMessageBox.Ok,
                 autostart=True):
        super(Alert, self).__init__(None)
        common.log('Alert', '__init__')

        self.setWindowTitle("OnionShare")
        self.setWindowIcon(
            QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.setText(message)
        self.setIcon(icon)
        self.setStandardButtons(buttons)

        if autostart:
            self.exec_()
    def __init__(self, qtapp, settings, onion):
        super(TorConnectionDialog, self).__init__(None)
        common.log('TorConnectionDialog', '__init__')

        self.qtapp = qtapp
        self.settings = settings
        self.onion = onion

        self.setWindowTitle("OnionShare")
        self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.setModal(True)
        self.setFixedSize(400, 150)

        # Label
        self.setLabelText(strings._('connecting_to_tor', True))

        # Progress bar ticks from 0 to 100
        self.setRange(0, 100)
        # Don't show if connection takes less than 100ms (for non-bundled tor)
        self.setMinimumDuration(100)

        # Start displaying the status at 0
        self._tor_status_update(0, '')
    def __init__(self, qtapp, settings, onion):
        super(TorConnectionDialog, self).__init__(None)
        common.log('TorConnectionDialog', '__init__')

        self.qtapp = qtapp
        self.settings = settings
        self.onion = onion

        self.setWindowTitle("OnionShare")
        self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.setModal(True)
        self.setFixedSize(400, 150)

        # Label
        self.setLabelText(strings._('connecting_to_tor', True))

        # Progress bar ticks from 0 to 100
        self.setRange(0, 100)
        # Don't show if connection takes less than 100ms (for non-bundled tor)
        self.setMinimumDuration(100)

        # Start displaying the status at 0
        self._tor_status_update(0, '')
 def test_linux(self, platform_linux, sys_argv_sys_prefix):
     prefix = os.path.join(sys.prefix, 'share/onionshare')
     assert (
         common.get_resource_path(os.path.join(prefix, 'test_filename')) ==
         os.path.join(prefix, 'test_filename'))
Example #22
0
    def __init__(self, onion, qtapp, app, filenames, config=False):
        super(OnionShareGui, self).__init__()

        self._initSystemTray()

        common.log('OnionShareGui', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.app = app

        self.setWindowTitle('OnionShare')
        self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.setMinimumWidth(430)

        # Load settings
        self.config = config
        self.settings = Settings(self.config)
        self.settings.load()

        # File selection
        self.file_selection = FileSelection()
        if filenames:
            for filename in filenames:
                self.file_selection.file_list.add_file(filename)

        # Server status
        self.server_status = ServerStatus(self.qtapp, self.app, web, self.file_selection, self.settings)
        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)
        self.server_status.server_stopped.connect(self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.stop_server)
        self.server_status.server_stopped.connect(self.update_server_status_indicator)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.cancel_server)
        self.server_status.server_canceled.connect(self.file_selection.server_stopped)
        self.server_status.server_canceled.connect(self.update_primary_action)
        self.start_server_finished.connect(self.clear_message)
        self.start_server_finished.connect(self.server_status.start_server_finished)
        self.start_server_finished.connect(self.update_server_status_indicator)
        self.stop_server_finished.connect(self.server_status.stop_server_finished)
        self.stop_server_finished.connect(self.update_server_status_indicator)
        self.file_selection.file_list.files_updated.connect(self.server_status.update)
        self.file_selection.file_list.files_updated.connect(self.update_primary_action)
        self.server_status.url_copied.connect(self.copy_url)
        self.server_status.hidservauth_copied.connect(self.copy_hidservauth)
        self.starting_server_step2.connect(self.start_server_step2)
        self.starting_server_step3.connect(self.start_server_step3)
        self.starting_server_error.connect(self.start_server_error)
        self.server_status.button_clicked.connect(self.clear_message)

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setWordWrap(True)
        self.filesize_warning.setStyleSheet('padding: 10px 0; font-weight: bold; color: #333333;')
        self.filesize_warning.hide()

        # Downloads
        self.downloads = Downloads()
        self.downloads_container = QtWidgets.QScrollArea()
        self.downloads_container.setWidget(self.downloads)
        self.downloads_container.setWidgetResizable(True)
        self.downloads_container.setMaximumHeight(200)
        self.downloads_container.setMinimumHeight(75)
        self.vbar = self.downloads_container.verticalScrollBar()
        self.downloads_container.hide() # downloads start out hidden
        self.new_download = False
        self.downloads_in_progress = 0
        self.downloads_completed = 0

        # Info label along top of screen
        self.info_layout = QtWidgets.QHBoxLayout()
        self.info_label = QtWidgets.QLabel()
        self.info_label.setStyleSheet('QLabel { font-size: 12px; color: #666666; }')

        self.info_in_progress_downloads_count = QtWidgets.QLabel()
        self.info_in_progress_downloads_count.setStyleSheet('QLabel { font-size: 12px; color: #666666; }')

        self.info_completed_downloads_count = QtWidgets.QLabel()
        self.info_completed_downloads_count.setStyleSheet('QLabel { font-size: 12px; color: #666666; }')

        self.update_downloads_completed(self.downloads_in_progress)
        self.update_downloads_in_progress(self.downloads_in_progress)

        self.info_layout.addWidget(self.info_label)
        self.info_layout.addStretch()
        self.info_layout.addWidget(self.info_in_progress_downloads_count)
        self.info_layout.addWidget(self.info_completed_downloads_count)

        self.info_widget = QtWidgets.QWidget()
        self.info_widget.setLayout(self.info_layout)
        self.info_widget.hide()

        # Settings button on the status bar
        self.settings_button = QtWidgets.QPushButton()
        self.settings_button.setDefault(False)
        self.settings_button.setFlat(True)
        self.settings_button.setFixedWidth(40)
        self.settings_button.setIcon( QtGui.QIcon(common.get_resource_path('images/settings.png')) )
        self.settings_button.clicked.connect(self.open_settings)

        # Server status indicator on the status bar
        self.server_status_image_stopped = QtGui.QImage(common.get_resource_path('images/server_stopped.png'))
        self.server_status_image_working = QtGui.QImage(common.get_resource_path('images/server_working.png'))
        self.server_status_image_started = QtGui.QImage(common.get_resource_path('images/server_started.png'))
        self.server_status_image_label = QtWidgets.QLabel()
        self.server_status_image_label.setFixedWidth(20)
        self.server_status_label = QtWidgets.QLabel()
        self.server_status_label.setStyleSheet('QLabel { font-style: italic; color: #666666; }')
        server_status_indicator_layout = QtWidgets.QHBoxLayout()
        server_status_indicator_layout.addWidget(self.server_status_image_label)
        server_status_indicator_layout.addWidget(self.server_status_label)
        self.server_status_indicator = QtWidgets.QWidget()
        self.server_status_indicator.setLayout(server_status_indicator_layout)
        self.update_server_status_indicator()

        # Status bar
        self.status_bar = QtWidgets.QStatusBar()
        self.status_bar.setSizeGripEnabled(False)
        statusBar_cssStyleData ="""
        QStatusBar {
            font-style: italic;
            color: #666666;
        }

        QStatusBar::item {
            border: 0px;
        }"""

        self.status_bar.setStyleSheet(statusBar_cssStyleData)
        self.status_bar.addPermanentWidget(self.server_status_indicator)
        self.status_bar.addPermanentWidget(self.settings_button)
        self.setStatusBar(self.status_bar)

        # Status bar, zip progress bar
        self._zip_progress_bar = None
        # Status bar, sharing messages
        self.server_share_status_label = QtWidgets.QLabel('')
        self.server_share_status_label.setStyleSheet('QLabel { font-style: italic; color: #666666; padding: 2px; }')
        self.status_bar.insertWidget(0, self.server_share_status_label)

        # Primary action layout
        primary_action_layout = QtWidgets.QVBoxLayout()
        primary_action_layout.addWidget(self.server_status)
        primary_action_layout.addWidget(self.filesize_warning)
        primary_action_layout.addWidget(self.downloads_container)
        self.primary_action = QtWidgets.QWidget()
        self.primary_action.setLayout(primary_action_layout)
        self.primary_action.hide()
        self.update_primary_action()

        # Main layout
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.info_widget)
        self.layout.addLayout(self.file_selection)
        self.layout.addWidget(self.primary_action)
        central_widget = QtWidgets.QWidget()
        central_widget.setLayout(self.layout)
        self.setCentralWidget(central_widget)
        self.show()

        # Always start with focus on file selection
        self.file_selection.setFocus()

        # The server isn't active yet
        self.set_server_active(False)

        # Create the timer
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.check_for_requests)

        # Start the "Connecting to Tor" dialog, which calls onion.connect()
        tor_con = TorConnectionDialog(self.qtapp, self.settings, self.onion)
        tor_con.canceled.connect(self._tor_connection_canceled)
        tor_con.open_settings.connect(self._tor_connection_open_settings)
        tor_con.start()

        # Start the timer
        self.timer.start(500)

        # After connecting to Tor, check for updates
        self.check_for_updates()
    def __init__(self, onion, qtapp, config=False):
        super(SettingsDialog, self).__init__()
        common.log('SettingsDialog', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.config = config

        self.setModal(True)
        self.setWindowTitle(strings._('gui_settings_window_title', True))
        self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))

        system = platform.system()

        # Sharing options

        # Close after first download
        self.close_after_first_download_checkbox = QtWidgets.QCheckBox()
        self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked)
        self.close_after_first_download_checkbox.setText(strings._("gui_settings_close_after_first_download_option", True))

        # Whether or not to show systray notifications
        self.systray_notifications_checkbox = QtWidgets.QCheckBox()
        self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked)
        self.systray_notifications_checkbox.setText(strings._("gui_settings_systray_notifications", True))

        # Sharing options layout
        sharing_group_layout = QtWidgets.QVBoxLayout()
        sharing_group_layout.addWidget(self.close_after_first_download_checkbox)
        sharing_group_layout.addWidget(self.systray_notifications_checkbox)
        sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label", True))
        sharing_group.setLayout(sharing_group_layout)

        # Stealth options

        # Stealth
        stealth_details = QtWidgets.QLabel(strings._("gui_settings_stealth_option_details", True))
        stealth_details.setWordWrap(True)
        self.stealth_checkbox = QtWidgets.QCheckBox()
        self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.stealth_checkbox.setText(strings._("gui_settings_stealth_option", True))

        # Stealth options layout
        stealth_group_layout = QtWidgets.QVBoxLayout()
        stealth_group_layout.addWidget(stealth_details)
        stealth_group_layout.addWidget(self.stealth_checkbox)
        stealth_group = QtWidgets.QGroupBox(strings._("gui_settings_stealth_label", True))
        stealth_group.setLayout(stealth_group_layout)

        # Automatic updates options

        # Autoupdate
        self.autoupdate_checkbox = QtWidgets.QCheckBox()
        self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.autoupdate_checkbox.setText(strings._("gui_settings_autoupdate_option", True))

        # Last update time
        self.autoupdate_timestamp = QtWidgets.QLabel()

        # Check for updates button
        self.check_for_updates_button = QtWidgets.QPushButton(strings._('gui_settings_autoupdate_check_button', True))
        self.check_for_updates_button.clicked.connect(self.check_for_updates)

        # Autoupdate options layout
        autoupdate_group_layout = QtWidgets.QVBoxLayout()
        autoupdate_group_layout.addWidget(self.autoupdate_checkbox)
        autoupdate_group_layout.addWidget(self.autoupdate_timestamp)
        autoupdate_group_layout.addWidget(self.check_for_updates_button)
        autoupdate_group = QtWidgets.QGroupBox(strings._("gui_settings_autoupdate_label", True))
        autoupdate_group.setLayout(autoupdate_group_layout)

        # Autoupdate is only available for Windows and Mac (Linux updates using package manager)
        if system != 'Windows' and system != 'Darwin':
            autoupdate_group.hide()

        # Connection type: either automatic, control port, or socket file

        # Bundled Tor
        self.connection_type_bundled_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_bundled_option', True))
        self.connection_type_bundled_radio.toggled.connect(self.connection_type_bundled_toggled)

        # Bundled Tor doesn't work on dev mode in Windows or Mac
        if (system == 'Windows' or system == 'Darwin') and getattr(sys, 'onionshare_dev_mode', False):
            self.connection_type_bundled_radio.setEnabled(False)

        # Automatic
        self.connection_type_automatic_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_automatic_option', True))
        self.connection_type_automatic_radio.toggled.connect(self.connection_type_automatic_toggled)

        # Control port
        self.connection_type_control_port_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_control_port_option', True))
        self.connection_type_control_port_radio.toggled.connect(self.connection_type_control_port_toggled)

        connection_type_control_port_extras_label = QtWidgets.QLabel(strings._('gui_settings_control_port_label', True))
        self.connection_type_control_port_extras_address = QtWidgets.QLineEdit()
        self.connection_type_control_port_extras_port = QtWidgets.QLineEdit()
        connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_control_port_extras_layout.addWidget(connection_type_control_port_extras_label)
        connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_address)
        connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_port)

        self.connection_type_control_port_extras = QtWidgets.QWidget()
        self.connection_type_control_port_extras.setLayout(connection_type_control_port_extras_layout)
        self.connection_type_control_port_extras.hide()

        # Socket file
        self.connection_type_socket_file_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_socket_file_option', True))
        self.connection_type_socket_file_radio.toggled.connect(self.connection_type_socket_file_toggled)

        connection_type_socket_file_extras_label = QtWidgets.QLabel(strings._('gui_settings_socket_file_label', True))
        self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit()
        connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_socket_file_extras_layout.addWidget(connection_type_socket_file_extras_label)
        connection_type_socket_file_extras_layout.addWidget(self.connection_type_socket_file_extras_path)

        self.connection_type_socket_file_extras = QtWidgets.QWidget()
        self.connection_type_socket_file_extras.setLayout(connection_type_socket_file_extras_layout)
        self.connection_type_socket_file_extras.hide()

        # Tor SOCKS address and port
        gui_settings_socks_label = QtWidgets.QLabel(strings._('gui_settings_socks_label', True))
        self.connection_type_socks_address = QtWidgets.QLineEdit()
        self.connection_type_socks_port = QtWidgets.QLineEdit()
        connection_type_socks_layout = QtWidgets.QHBoxLayout()
        connection_type_socks_layout.addWidget(gui_settings_socks_label)
        connection_type_socks_layout.addWidget(self.connection_type_socks_address)
        connection_type_socks_layout.addWidget(self.connection_type_socks_port)

        self.connection_type_socks = QtWidgets.QWidget()
        self.connection_type_socks.setLayout(connection_type_socks_layout)
        self.connection_type_socks.hide()

        # Authentication options

        # No authentication
        self.authenticate_no_auth_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_no_auth_option', True))
        self.authenticate_no_auth_radio.toggled.connect(self.authenticate_no_auth_toggled)

        # Password
        self.authenticate_password_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_password_option', True))
        self.authenticate_password_radio.toggled.connect(self.authenticate_password_toggled)

        authenticate_password_extras_label = QtWidgets.QLabel(strings._('gui_settings_password_label', True))
        self.authenticate_password_extras_password = QtWidgets.QLineEdit('')
        authenticate_password_extras_layout = QtWidgets.QHBoxLayout()
        authenticate_password_extras_layout.addWidget(authenticate_password_extras_label)
        authenticate_password_extras_layout.addWidget(self.authenticate_password_extras_password)

        self.authenticate_password_extras = QtWidgets.QWidget()
        self.authenticate_password_extras.setLayout(authenticate_password_extras_layout)
        self.authenticate_password_extras.hide()

        # Authentication options layout
        authenticate_group_layout = QtWidgets.QVBoxLayout()
        authenticate_group_layout.addWidget(self.authenticate_no_auth_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_extras)
        self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label", True))
        self.authenticate_group.setLayout(authenticate_group_layout)

        # Test tor settings button
        self.connection_type_test_button = QtWidgets.QPushButton(strings._('gui_settings_connection_type_test_button', True))
        self.connection_type_test_button.clicked.connect(self.test_tor_clicked)

        # Put the radios into their own group so they are exclusive
        connection_type_radio_group_layout = QtWidgets.QVBoxLayout()
        connection_type_radio_group_layout.addWidget(self.connection_type_bundled_radio)
        connection_type_radio_group_layout.addWidget(self.connection_type_automatic_radio)
        connection_type_radio_group_layout.addWidget(self.connection_type_control_port_radio)
        connection_type_radio_group_layout.addWidget(self.connection_type_socket_file_radio)
        connection_type_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_connection_type_label", True))
        connection_type_radio_group.setLayout(connection_type_radio_group_layout)

        # Connection type layout
        connection_type_group_layout = QtWidgets.QVBoxLayout()
        connection_type_group_layout.addWidget(self.connection_type_control_port_extras)
        connection_type_group_layout.addWidget(self.connection_type_socket_file_extras)
        connection_type_group_layout.addWidget(self.connection_type_socks)
        connection_type_group_layout.addWidget(self.authenticate_group)
        connection_type_group_layout.addWidget(self.connection_type_test_button)
        connection_type_group = QtWidgets.QGroupBox()
        connection_type_group.setLayout(connection_type_group_layout)

        # Buttons
        self.save_button = QtWidgets.QPushButton(strings._('gui_settings_button_save', True))
        self.save_button.clicked.connect(self.save_clicked)
        self.cancel_button = QtWidgets.QPushButton(strings._('gui_settings_button_cancel', True))
        self.cancel_button.clicked.connect(self.cancel_clicked)
        self.help_button = QtWidgets.QPushButton(strings._('gui_settings_button_help', True))
        self.help_button.clicked.connect(self.help_clicked)
        buttons_layout = QtWidgets.QHBoxLayout()
        buttons_layout.addWidget(self.help_button)
        buttons_layout.addStretch()
        buttons_layout.addWidget(self.save_button)
        buttons_layout.addWidget(self.cancel_button)

        # Tor network connection status
        self.tor_status = QtWidgets.QLabel()
        self.tor_status.setStyleSheet('background-color: #ffffff; color: #000000; padding: 10px')
        self.tor_status.hide()

        # Layout
        left_col_layout = QtWidgets.QVBoxLayout()
        left_col_layout.addWidget(sharing_group)
        left_col_layout.addWidget(stealth_group)
        left_col_layout.addWidget(autoupdate_group)
        left_col_layout.addStretch()

        right_col_layout = QtWidgets.QVBoxLayout()
        right_col_layout.addWidget(connection_type_radio_group)
        right_col_layout.addWidget(connection_type_group)
        right_col_layout.addWidget(self.tor_status)
        right_col_layout.addStretch()

        col_layout = QtWidgets.QHBoxLayout()
        col_layout.addLayout(left_col_layout)
        col_layout.addLayout(right_col_layout)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(col_layout)
        layout.addLayout(buttons_layout)

        self.setLayout(layout)
        self.cancel_button.setFocus()

        # Load settings, and fill them in
        self.old_settings = Settings(self.config)
        self.old_settings.load()

        close_after_first_download = self.old_settings.get('close_after_first_download')
        if close_after_first_download:
            self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Unchecked)

        systray_notifications = self.old_settings.get('systray_notifications')
        if systray_notifications:
            self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Unchecked)

        use_stealth = self.old_settings.get('use_stealth')
        if use_stealth:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)

        use_autoupdate = self.old_settings.get('use_autoupdate')
        if use_autoupdate:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)

        autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp')
        self._update_autoupdate_timestamp(autoupdate_timestamp)

        connection_type = self.old_settings.get('connection_type')
        if connection_type == 'bundled':
            if self.connection_type_bundled_radio.isEnabled():
                self.connection_type_bundled_radio.setChecked(True)
            else:
                # If bundled tor is disabled, fallback to automatic
                self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'automatic':
            self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'control_port':
            self.connection_type_control_port_radio.setChecked(True)
        elif connection_type == 'socket_file':
            self.connection_type_socket_file_radio.setChecked(True)
        self.connection_type_control_port_extras_address.setText(self.old_settings.get('control_port_address'))
        self.connection_type_control_port_extras_port.setText(str(self.old_settings.get('control_port_port')))
        self.connection_type_socket_file_extras_path.setText(self.old_settings.get('socket_file_path'))
        self.connection_type_socks_address.setText(self.old_settings.get('socks_address'))
        self.connection_type_socks_port.setText(str(self.old_settings.get('socks_port')))
        auth_type = self.old_settings.get('auth_type')
        if auth_type == 'no_auth':
            self.authenticate_no_auth_radio.setChecked(True)
        elif auth_type == 'password':
            self.authenticate_password_radio.setChecked(True)
        self.authenticate_password_extras_password.setText(self.old_settings.get('auth_password'))
    def __init__(self, onion, qtapp, app, filenames, config=False):
        super(OnionShareGui, self).__init__()

        self._initSystemTray()

        common.log('OnionShareGui', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.app = app

        self.setWindowTitle('OnionShare')
        self.setWindowIcon(
            QtGui.QIcon(common.get_resource_path('images/logo.png')))

        # Load settings
        self.config = config
        self.settings = Settings(self.config)
        self.settings.load()

        # File selection
        self.file_selection = FileSelection()
        if filenames:
            for filename in filenames:
                self.file_selection.file_list.add_file(filename)

        # Server status
        self.server_status = ServerStatus(self.qtapp, self.app, 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_stopped.connect(
            self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.stop_server)
        self.start_server_finished.connect(self.clear_message)
        self.start_server_finished.connect(
            self.server_status.start_server_finished)
        self.stop_server_finished.connect(
            self.server_status.stop_server_finished)
        self.file_selection.file_list.files_updated.connect(
            self.server_status.update)
        self.server_status.url_copied.connect(self.copy_url)
        self.server_status.hidservauth_copied.connect(self.copy_hidservauth)
        self.starting_server_step2.connect(self.start_server_step2)
        self.starting_server_step3.connect(self.start_server_step3)
        self.starting_server_error.connect(self.start_server_error)

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setStyleSheet(
            'padding: 10px 0; font-weight: bold; color: #333333;')
        self.filesize_warning.hide()

        # Downloads
        self.downloads = Downloads()
        self.downloads_container = QtWidgets.QScrollArea()
        self.downloads_container.setWidget(self.downloads)
        self.downloads_container.setWidgetResizable(True)
        self.downloads_container.setMaximumHeight(200)
        self.downloads_container.setMinimumHeight(75)
        self.vbar = self.downloads_container.verticalScrollBar()
        self.downloads_container.hide()  # downloads start out hidden
        self.new_download = False

        # Status bar
        self.status_bar = QtWidgets.QStatusBar()
        self.status_bar.setSizeGripEnabled(False)
        self.status_bar.setStyleSheet("QStatusBar::item { border: 0px; }")
        version_label = QtWidgets.QLabel('v{0:s}'.format(common.get_version()))
        version_label.setStyleSheet('color: #666666')
        self.settings_button = QtWidgets.QPushButton()
        self.settings_button.setDefault(False)
        self.settings_button.setFlat(True)
        self.settings_button.setIcon(
            QtGui.QIcon(common.get_resource_path('images/settings.png')))
        self.settings_button.clicked.connect(self.open_settings)
        self.status_bar.addPermanentWidget(version_label)
        self.status_bar.addPermanentWidget(self.settings_button)
        self.setStatusBar(self.status_bar)

        # Status bar, zip progress bar
        self._zip_progress_bar = None

        # Main layout
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addLayout(self.file_selection)
        self.layout.addLayout(self.server_status)
        self.layout.addWidget(self.filesize_warning)
        self.layout.addWidget(self.downloads_container)
        central_widget = QtWidgets.QWidget()
        central_widget.setLayout(self.layout)
        self.setCentralWidget(central_widget)
        self.show()

        # Check for requests frequently
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.check_for_requests)
        self.timer.start(500)

        # Always start with focus on file selection
        self.file_selection.setFocus()

        # The server isn't active yet
        self.set_server_active(False)

        # Start the "Connecting to Tor" dialog, which calls onion.connect()
        tor_con = TorConnectionDialog(self.qtapp, self.settings, self.onion)
        tor_con.canceled.connect(self._tor_connection_canceled)
        tor_con.open_settings.connect(self._tor_connection_open_settings)
        tor_con.start()

        # After connecting to Tor, check for updates
        self.check_for_updates()
Example #25
0
    def __init__(self, onion, qtapp, app, filenames, config=False):
        super(OnionShareGui, self).__init__()

        self._initSystemTray()

        common.log('OnionShareGui', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.app = app

        self.setWindowTitle('OnionShare')
        self.setWindowIcon(
            QtGui.QIcon(common.get_resource_path('images/logo.png')))
        self.setMinimumWidth(430)

        # Load settings
        self.config = config
        self.settings = Settings(self.config)
        self.settings.load()

        # File selection
        self.file_selection = FileSelection()
        if filenames:
            for filename in filenames:
                self.file_selection.file_list.add_file(filename)

        # Server status
        self.server_status = ServerStatus(self.qtapp, self.app, web,
                                          self.file_selection, self.settings)
        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)
        self.server_status.server_stopped.connect(
            self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.stop_server)
        self.server_status.server_stopped.connect(
            self.update_server_status_indicator)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.cancel_server)
        self.server_status.server_canceled.connect(
            self.file_selection.server_stopped)
        self.server_status.server_canceled.connect(self.update_primary_action)
        self.start_server_finished.connect(self.clear_message)
        self.start_server_finished.connect(
            self.server_status.start_server_finished)
        self.start_server_finished.connect(self.update_server_status_indicator)
        self.stop_server_finished.connect(
            self.server_status.stop_server_finished)
        self.stop_server_finished.connect(self.update_server_status_indicator)
        self.file_selection.file_list.files_updated.connect(
            self.server_status.update)
        self.file_selection.file_list.files_updated.connect(
            self.update_primary_action)
        self.server_status.url_copied.connect(self.copy_url)
        self.server_status.hidservauth_copied.connect(self.copy_hidservauth)
        self.starting_server_step2.connect(self.start_server_step2)
        self.starting_server_step3.connect(self.start_server_step3)
        self.starting_server_error.connect(self.start_server_error)
        self.server_status.button_clicked.connect(self.clear_message)

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setWordWrap(True)
        self.filesize_warning.setStyleSheet(
            'padding: 10px 0; font-weight: bold; color: #333333;')
        self.filesize_warning.hide()

        # Downloads
        self.downloads = Downloads()
        self.downloads_container = QtWidgets.QScrollArea()
        self.downloads_container.setWidget(self.downloads)
        self.downloads_container.setWidgetResizable(True)
        self.downloads_container.setMaximumHeight(200)
        self.downloads_container.setMinimumHeight(75)
        self.vbar = self.downloads_container.verticalScrollBar()
        self.downloads_container.hide()  # downloads start out hidden
        self.new_download = False
        self.downloads_in_progress = 0
        self.downloads_completed = 0

        # Info label along top of screen
        self.info_layout = QtWidgets.QHBoxLayout()
        self.info_label = QtWidgets.QLabel()
        self.info_label.setStyleSheet(
            'QLabel { font-size: 12px; color: #666666; }')

        self.info_in_progress_downloads_count = QtWidgets.QLabel()
        self.info_in_progress_downloads_count.setStyleSheet(
            'QLabel { font-size: 12px; color: #666666; }')

        self.info_completed_downloads_count = QtWidgets.QLabel()
        self.info_completed_downloads_count.setStyleSheet(
            'QLabel { font-size: 12px; color: #666666; }')

        self.update_downloads_completed(self.downloads_in_progress)
        self.update_downloads_in_progress(self.downloads_in_progress)

        self.info_layout.addWidget(self.info_label)
        self.info_layout.addStretch()
        self.info_layout.addWidget(self.info_in_progress_downloads_count)
        self.info_layout.addWidget(self.info_completed_downloads_count)

        self.info_widget = QtWidgets.QWidget()
        self.info_widget.setLayout(self.info_layout)
        self.info_widget.hide()

        # Settings button on the status bar
        self.settings_button = QtWidgets.QPushButton()
        self.settings_button.setDefault(False)
        self.settings_button.setFlat(True)
        self.settings_button.setFixedWidth(40)
        self.settings_button.setIcon(
            QtGui.QIcon(common.get_resource_path('images/settings.png')))
        self.settings_button.clicked.connect(self.open_settings)

        # Server status indicator on the status bar
        self.server_status_image_stopped = QtGui.QImage(
            common.get_resource_path('images/server_stopped.png'))
        self.server_status_image_working = QtGui.QImage(
            common.get_resource_path('images/server_working.png'))
        self.server_status_image_started = QtGui.QImage(
            common.get_resource_path('images/server_started.png'))
        self.server_status_image_label = QtWidgets.QLabel()
        self.server_status_image_label.setFixedWidth(20)
        self.server_status_label = QtWidgets.QLabel()
        self.server_status_label.setStyleSheet(
            'QLabel { font-style: italic; color: #666666; }')
        server_status_indicator_layout = QtWidgets.QHBoxLayout()
        server_status_indicator_layout.addWidget(
            self.server_status_image_label)
        server_status_indicator_layout.addWidget(self.server_status_label)
        self.server_status_indicator = QtWidgets.QWidget()
        self.server_status_indicator.setLayout(server_status_indicator_layout)
        self.update_server_status_indicator()

        # Status bar
        self.status_bar = QtWidgets.QStatusBar()
        self.status_bar.setSizeGripEnabled(False)
        statusBar_cssStyleData = """
        QStatusBar {
            font-style: italic;
            color: #666666;
        }

        QStatusBar::item {
            border: 0px;
        }"""

        self.status_bar.setStyleSheet(statusBar_cssStyleData)
        self.status_bar.addPermanentWidget(self.server_status_indicator)
        self.status_bar.addPermanentWidget(self.settings_button)
        self.setStatusBar(self.status_bar)

        # Status bar, zip progress bar
        self._zip_progress_bar = None
        # Status bar, sharing messages
        self.server_share_status_label = QtWidgets.QLabel('')
        self.server_share_status_label.setStyleSheet(
            'QLabel { font-style: italic; color: #666666; padding: 2px; }')
        self.status_bar.insertWidget(0, self.server_share_status_label)

        # Primary action layout
        primary_action_layout = QtWidgets.QVBoxLayout()
        primary_action_layout.addWidget(self.server_status)
        primary_action_layout.addWidget(self.filesize_warning)
        primary_action_layout.addWidget(self.downloads_container)
        self.primary_action = QtWidgets.QWidget()
        self.primary_action.setLayout(primary_action_layout)
        self.primary_action.hide()
        self.update_primary_action()

        # Main layout
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.info_widget)
        self.layout.addLayout(self.file_selection)
        self.layout.addWidget(self.primary_action)
        central_widget = QtWidgets.QWidget()
        central_widget.setLayout(self.layout)
        self.setCentralWidget(central_widget)
        self.show()

        # Always start with focus on file selection
        self.file_selection.setFocus()

        # The server isn't active yet
        self.set_server_active(False)

        # Create the timer
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.check_for_requests)

        # Start the "Connecting to Tor" dialog, which calls onion.connect()
        tor_con = TorConnectionDialog(self.qtapp, self.settings, self.onion)
        tor_con.canceled.connect(self._tor_connection_canceled)
        tor_con.open_settings.connect(self._tor_connection_open_settings)
        tor_con.start()

        # Start the timer
        self.timer.start(500)

        # After connecting to Tor, check for updates
        self.check_for_updates()
Example #26
0
    def add_file(self, filename):
        """
        Add a file or directory to this widget.
        """
        filenames = []
        for index in range(self.count()):
            filenames.append(self.item(index).filename)

        if filename not in filenames:
            if not os.access(filename, os.R_OK):
                Alert(strings._("not_a_readable_file", True).format(filename))
                return

            fileinfo = QtCore.QFileInfo(filename)
            ip = QtWidgets.QFileIconProvider()
            icon = ip.icon(fileinfo)

            if os.path.isfile(filename):
                size_bytes = fileinfo.size()
                size_readable = common.human_readable_filesize(size_bytes)
            else:
                size_bytes = common.dir_size(filename)
                size_readable = common.human_readable_filesize(size_bytes)

            # Create a new item
            item = QtWidgets.QListWidgetItem()
            item.setIcon(icon)
            item.size_bytes = size_bytes

            # Item's filename attribute and size labels
            item.filename = filename
            item_size = QtWidgets.QLabel(size_readable)
            item_size.setStyleSheet('QLabel { color: #666666; font-size: 11px; }')

            item.basename = os.path.basename(filename.rstrip('/'))
            # Use the basename as the method with which to sort the list
            metrics = QtGui.QFontMetrics(item.font())
            elided = metrics.elidedText(item.basename, QtCore.Qt.ElideRight, self.sizeHint().width())
            item.setData(QtCore.Qt.DisplayRole, elided)

            # Item's delete button
            def delete_item():
                itemrow = self.row(item)
                self.takeItem(itemrow)
                self.files_updated.emit()

            item.item_button = QtWidgets.QPushButton()
            item.item_button.setDefault(False)
            item.item_button.setFlat(True)
            item.item_button.setIcon( QtGui.QIcon(common.get_resource_path('images/file_delete.png')) )
            item.item_button.clicked.connect(delete_item)
            item.item_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)

            # Item info widget, with a white background
            item_info_layout = QtWidgets.QHBoxLayout()
            item_info_layout.addWidget(item_size)
            item_info_layout.addWidget(item.item_button)
            item_info = QtWidgets.QWidget()
            item_info.setObjectName('item-info')
            item_info.setLayout(item_info_layout)

            # Create the item's widget and layouts
            item_hlayout = QtWidgets.QHBoxLayout()
            item_hlayout.addStretch()
            item_hlayout.addWidget(item_info)
            widget = QtWidgets.QWidget()
            widget.setLayout(item_hlayout)

            item.setSizeHint(widget.sizeHint())

            self.addItem(item)
            self.setItemWidget(item, widget)

            self.files_updated.emit()
Example #27
0
    def __init__(self, onion, qtapp, config=False):
        super(SettingsDialog, self).__init__()
        common.log('SettingsDialog', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.config = config

        self.setModal(True)
        self.setWindowTitle(strings._('gui_settings_window_title', True))
        self.setWindowIcon(
            QtGui.QIcon(common.get_resource_path('images/logo.png')))

        system = platform.system()

        # Sharing options

        # Close after first download
        self.close_after_first_download_checkbox = QtWidgets.QCheckBox()
        self.close_after_first_download_checkbox.setCheckState(
            QtCore.Qt.Checked)
        self.close_after_first_download_checkbox.setText(
            strings._("gui_settings_close_after_first_download_option", True))

        # Whether or not to show systray notifications
        self.systray_notifications_checkbox = QtWidgets.QCheckBox()
        self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked)
        self.systray_notifications_checkbox.setText(
            strings._("gui_settings_systray_notifications", True))

        # Sharing options layout
        sharing_group_layout = QtWidgets.QVBoxLayout()
        sharing_group_layout.addWidget(
            self.close_after_first_download_checkbox)
        sharing_group_layout.addWidget(self.systray_notifications_checkbox)
        sharing_group = QtWidgets.QGroupBox(
            strings._("gui_settings_sharing_label", True))
        sharing_group.setLayout(sharing_group_layout)

        # Stealth options

        # Stealth
        stealth_details = QtWidgets.QLabel(
            strings._("gui_settings_stealth_option_details", True))
        stealth_details.setWordWrap(True)
        self.stealth_checkbox = QtWidgets.QCheckBox()
        self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.stealth_checkbox.setText(
            strings._("gui_settings_stealth_option", True))

        # Stealth options layout
        stealth_group_layout = QtWidgets.QVBoxLayout()
        stealth_group_layout.addWidget(stealth_details)
        stealth_group_layout.addWidget(self.stealth_checkbox)
        stealth_group = QtWidgets.QGroupBox(
            strings._("gui_settings_stealth_label", True))
        stealth_group.setLayout(stealth_group_layout)

        # Automatic updates options

        # Autoupdate
        self.autoupdate_checkbox = QtWidgets.QCheckBox()
        self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.autoupdate_checkbox.setText(
            strings._("gui_settings_autoupdate_option", True))

        # Last update time
        self.autoupdate_timestamp = QtWidgets.QLabel()

        # Check for updates button
        self.check_for_updates_button = QtWidgets.QPushButton(
            strings._('gui_settings_autoupdate_check_button', True))
        self.check_for_updates_button.clicked.connect(self.check_for_updates)

        # Autoupdate options layout
        autoupdate_group_layout = QtWidgets.QVBoxLayout()
        autoupdate_group_layout.addWidget(self.autoupdate_checkbox)
        autoupdate_group_layout.addWidget(self.autoupdate_timestamp)
        autoupdate_group_layout.addWidget(self.check_for_updates_button)
        autoupdate_group = QtWidgets.QGroupBox(
            strings._("gui_settings_autoupdate_label", True))
        autoupdate_group.setLayout(autoupdate_group_layout)

        # Autoupdate is only available for Windows and Mac (Linux updates using package manager)
        if system != 'Windows' and system != 'Darwin':
            autoupdate_group.hide()

        # Connection type: either automatic, control port, or socket file

        # Bundled Tor
        self.connection_type_bundled_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_bundled_option', True))
        self.connection_type_bundled_radio.toggled.connect(
            self.connection_type_bundled_toggled)

        # Bundled Tor doesn't work on dev mode in Windows or Mac
        if (system == 'Windows' or system == 'Darwin') and getattr(
                sys, 'onionshare_dev_mode', False):
            self.connection_type_bundled_radio.setEnabled(False)

        # Automatic
        self.connection_type_automatic_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_automatic_option', True))
        self.connection_type_automatic_radio.toggled.connect(
            self.connection_type_automatic_toggled)

        # Control port
        self.connection_type_control_port_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_control_port_option',
                      True))
        self.connection_type_control_port_radio.toggled.connect(
            self.connection_type_control_port_toggled)

        connection_type_control_port_extras_label = QtWidgets.QLabel(
            strings._('gui_settings_control_port_label', True))
        self.connection_type_control_port_extras_address = QtWidgets.QLineEdit(
        )
        self.connection_type_control_port_extras_port = QtWidgets.QLineEdit()
        connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_control_port_extras_layout.addWidget(
            connection_type_control_port_extras_label)
        connection_type_control_port_extras_layout.addWidget(
            self.connection_type_control_port_extras_address)
        connection_type_control_port_extras_layout.addWidget(
            self.connection_type_control_port_extras_port)

        self.connection_type_control_port_extras = QtWidgets.QWidget()
        self.connection_type_control_port_extras.setLayout(
            connection_type_control_port_extras_layout)
        self.connection_type_control_port_extras.hide()

        # Socket file
        self.connection_type_socket_file_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_socket_file_option', True))
        self.connection_type_socket_file_radio.toggled.connect(
            self.connection_type_socket_file_toggled)

        connection_type_socket_file_extras_label = QtWidgets.QLabel(
            strings._('gui_settings_socket_file_label', True))
        self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit()
        connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_socket_file_extras_layout.addWidget(
            connection_type_socket_file_extras_label)
        connection_type_socket_file_extras_layout.addWidget(
            self.connection_type_socket_file_extras_path)

        self.connection_type_socket_file_extras = QtWidgets.QWidget()
        self.connection_type_socket_file_extras.setLayout(
            connection_type_socket_file_extras_layout)
        self.connection_type_socket_file_extras.hide()

        # Tor SOCKS address and port
        gui_settings_socks_label = QtWidgets.QLabel(
            strings._('gui_settings_socks_label', True))
        self.connection_type_socks_address = QtWidgets.QLineEdit()
        self.connection_type_socks_port = QtWidgets.QLineEdit()
        connection_type_socks_layout = QtWidgets.QHBoxLayout()
        connection_type_socks_layout.addWidget(gui_settings_socks_label)
        connection_type_socks_layout.addWidget(
            self.connection_type_socks_address)
        connection_type_socks_layout.addWidget(self.connection_type_socks_port)

        self.connection_type_socks = QtWidgets.QWidget()
        self.connection_type_socks.setLayout(connection_type_socks_layout)
        self.connection_type_socks.hide()

        # Authentication options

        # No authentication
        self.authenticate_no_auth_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_authenticate_no_auth_option', True))
        self.authenticate_no_auth_radio.toggled.connect(
            self.authenticate_no_auth_toggled)

        # Password
        self.authenticate_password_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_authenticate_password_option', True))
        self.authenticate_password_radio.toggled.connect(
            self.authenticate_password_toggled)

        authenticate_password_extras_label = QtWidgets.QLabel(
            strings._('gui_settings_password_label', True))
        self.authenticate_password_extras_password = QtWidgets.QLineEdit('')
        authenticate_password_extras_layout = QtWidgets.QHBoxLayout()
        authenticate_password_extras_layout.addWidget(
            authenticate_password_extras_label)
        authenticate_password_extras_layout.addWidget(
            self.authenticate_password_extras_password)

        self.authenticate_password_extras = QtWidgets.QWidget()
        self.authenticate_password_extras.setLayout(
            authenticate_password_extras_layout)
        self.authenticate_password_extras.hide()

        # Authentication options layout
        authenticate_group_layout = QtWidgets.QVBoxLayout()
        authenticate_group_layout.addWidget(self.authenticate_no_auth_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_extras)
        self.authenticate_group = QtWidgets.QGroupBox(
            strings._("gui_settings_authenticate_label", True))
        self.authenticate_group.setLayout(authenticate_group_layout)

        # Test tor settings button
        self.connection_type_test_button = QtWidgets.QPushButton(
            strings._('gui_settings_connection_type_test_button', True))
        self.connection_type_test_button.clicked.connect(self.test_tor_clicked)

        # Put the radios into their own group so they are exclusive
        connection_type_radio_group_layout = QtWidgets.QVBoxLayout()
        connection_type_radio_group_layout.addWidget(
            self.connection_type_bundled_radio)
        connection_type_radio_group_layout.addWidget(
            self.connection_type_automatic_radio)
        connection_type_radio_group_layout.addWidget(
            self.connection_type_control_port_radio)
        connection_type_radio_group_layout.addWidget(
            self.connection_type_socket_file_radio)
        connection_type_radio_group = QtWidgets.QGroupBox(
            strings._("gui_settings_connection_type_label", True))
        connection_type_radio_group.setLayout(
            connection_type_radio_group_layout)

        # Connection type layout
        connection_type_group_layout = QtWidgets.QVBoxLayout()
        connection_type_group_layout.addWidget(
            self.connection_type_control_port_extras)
        connection_type_group_layout.addWidget(
            self.connection_type_socket_file_extras)
        connection_type_group_layout.addWidget(self.connection_type_socks)
        connection_type_group_layout.addWidget(self.authenticate_group)
        connection_type_group_layout.addWidget(
            self.connection_type_test_button)
        connection_type_group = QtWidgets.QGroupBox()
        connection_type_group.setLayout(connection_type_group_layout)

        # Buttons
        self.save_button = QtWidgets.QPushButton(
            strings._('gui_settings_button_save', True))
        self.save_button.clicked.connect(self.save_clicked)
        self.cancel_button = QtWidgets.QPushButton(
            strings._('gui_settings_button_cancel', True))
        self.cancel_button.clicked.connect(self.cancel_clicked)
        self.help_button = QtWidgets.QPushButton(
            strings._('gui_settings_button_help', True))
        self.help_button.clicked.connect(self.help_clicked)
        buttons_layout = QtWidgets.QHBoxLayout()
        buttons_layout.addWidget(self.help_button)
        buttons_layout.addStretch()
        buttons_layout.addWidget(self.save_button)
        buttons_layout.addWidget(self.cancel_button)

        # Tor network connection status
        self.tor_status = QtWidgets.QLabel()
        self.tor_status.setStyleSheet(
            'background-color: #ffffff; color: #000000; padding: 10px')
        self.tor_status.hide()

        # Layout
        left_col_layout = QtWidgets.QVBoxLayout()
        left_col_layout.addWidget(sharing_group)
        left_col_layout.addWidget(stealth_group)
        left_col_layout.addWidget(autoupdate_group)
        left_col_layout.addStretch()

        right_col_layout = QtWidgets.QVBoxLayout()
        right_col_layout.addWidget(connection_type_radio_group)
        right_col_layout.addWidget(connection_type_group)
        right_col_layout.addWidget(self.tor_status)
        right_col_layout.addStretch()

        col_layout = QtWidgets.QHBoxLayout()
        col_layout.addLayout(left_col_layout)
        col_layout.addLayout(right_col_layout)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(col_layout)
        layout.addLayout(buttons_layout)

        self.setLayout(layout)
        self.cancel_button.setFocus()

        # Load settings, and fill them in
        self.old_settings = Settings(self.config)
        self.old_settings.load()

        close_after_first_download = self.old_settings.get(
            'close_after_first_download')
        if close_after_first_download:
            self.close_after_first_download_checkbox.setCheckState(
                QtCore.Qt.Checked)
        else:
            self.close_after_first_download_checkbox.setCheckState(
                QtCore.Qt.Unchecked)

        systray_notifications = self.old_settings.get('systray_notifications')
        if systray_notifications:
            self.systray_notifications_checkbox.setCheckState(
                QtCore.Qt.Checked)
        else:
            self.systray_notifications_checkbox.setCheckState(
                QtCore.Qt.Unchecked)

        use_stealth = self.old_settings.get('use_stealth')
        if use_stealth:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)

        use_autoupdate = self.old_settings.get('use_autoupdate')
        if use_autoupdate:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)

        autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp')
        self._update_autoupdate_timestamp(autoupdate_timestamp)

        connection_type = self.old_settings.get('connection_type')
        if connection_type == 'bundled':
            if self.connection_type_bundled_radio.isEnabled():
                self.connection_type_bundled_radio.setChecked(True)
            else:
                # If bundled tor is disabled, fallback to automatic
                self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'automatic':
            self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'control_port':
            self.connection_type_control_port_radio.setChecked(True)
        elif connection_type == 'socket_file':
            self.connection_type_socket_file_radio.setChecked(True)
        self.connection_type_control_port_extras_address.setText(
            self.old_settings.get('control_port_address'))
        self.connection_type_control_port_extras_port.setText(
            str(self.old_settings.get('control_port_port')))
        self.connection_type_socket_file_extras_path.setText(
            self.old_settings.get('socket_file_path'))
        self.connection_type_socks_address.setText(
            self.old_settings.get('socks_address'))
        self.connection_type_socks_port.setText(
            str(self.old_settings.get('socks_port')))
        auth_type = self.old_settings.get('auth_type')
        if auth_type == 'no_auth':
            self.authenticate_no_auth_radio.setChecked(True)
        elif auth_type == 'password':
            self.authenticate_password_radio.setChecked(True)
        self.authenticate_password_extras_password.setText(
            self.old_settings.get('auth_password'))
Example #28
0
    def add_file(self, filename):
        """
        Add a file or directory to this widget.
        """
        filenames = []
        for index in range(self.count()):
            filenames.append(self.item(index).filename)

        if filename not in filenames:
            if not os.access(filename, os.R_OK):
                Alert(strings._("not_a_readable_file", True).format(filename))
                return

            fileinfo = QtCore.QFileInfo(filename)
            ip = QtWidgets.QFileIconProvider()
            icon = ip.icon(fileinfo)

            if os.path.isfile(filename):
                size_bytes = fileinfo.size()
                size_readable = common.human_readable_filesize(size_bytes)
            else:
                size_bytes = common.dir_size(filename)
                size_readable = common.human_readable_filesize(size_bytes)

            # Create a new item
            item = QtWidgets.QListWidgetItem()
            item.setIcon(icon)
            item.size_bytes = size_bytes

            # Item's filename attribute and size labels
            item.filename = filename
            item_size = QtWidgets.QLabel(size_readable)
            item_size.setStyleSheet(
                'QLabel { color: #666666; font-size: 11px; }')

            item.basename = os.path.basename(filename.rstrip('/'))
            # Use the basename as the method with which to sort the list
            metrics = QtGui.QFontMetrics(item.font())
            elided = metrics.elidedText(item.basename, QtCore.Qt.ElideRight,
                                        self.sizeHint().width())
            item.setData(QtCore.Qt.DisplayRole, elided)

            # Item's delete button
            def delete_item():
                itemrow = self.row(item)
                self.takeItem(itemrow)
                self.files_updated.emit()

            item.item_button = QtWidgets.QPushButton()
            item.item_button.setDefault(False)
            item.item_button.setFlat(True)
            item.item_button.setIcon(
                QtGui.QIcon(
                    common.get_resource_path('images/file_delete.png')))
            item.item_button.clicked.connect(delete_item)
            item.item_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                           QtWidgets.QSizePolicy.Fixed)

            # Item info widget, with a white background
            item_info_layout = QtWidgets.QHBoxLayout()
            item_info_layout.addWidget(item_size)
            item_info_layout.addWidget(item.item_button)
            item_info = QtWidgets.QWidget()
            item_info.setObjectName('item-info')
            item_info.setLayout(item_info_layout)

            # Create the item's widget and layouts
            item_hlayout = QtWidgets.QHBoxLayout()
            item_hlayout.addStretch()
            item_hlayout.addWidget(item_info)
            widget = QtWidgets.QWidget()
            widget.setLayout(item_hlayout)

            item.setSizeHint(widget.sizeHint())

            self.addItem(item)
            self.setItemWidget(item, widget)

            self.files_updated.emit()
    def test_get_version(self, sys_onionshare_dev_mode):
        with open(common.get_resource_path('version.txt')) as f:
            version = f.read().strip()

        assert version == common.get_version()
Example #30
0
    def __init__(self, onion, qtapp, config=False):
        super(SettingsDialog, self).__init__()
        common.log('SettingsDialog', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.config = config

        self.setModal(True)
        self.setWindowTitle(strings._('gui_settings_window_title', True))
        self.setWindowIcon(
            QtGui.QIcon(common.get_resource_path('images/logo.png')))

        system = platform.system()

        # Sharing options

        # Close after first download
        self.close_after_first_download_checkbox = QtWidgets.QCheckBox()
        self.close_after_first_download_checkbox.setCheckState(
            QtCore.Qt.Checked)
        self.close_after_first_download_checkbox.setText(
            strings._("gui_settings_close_after_first_download_option", True))

        # Whether or not to show systray notifications
        self.systray_notifications_checkbox = QtWidgets.QCheckBox()
        self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked)
        self.systray_notifications_checkbox.setText(
            strings._("gui_settings_systray_notifications", True))

        # Whether or not to save the Onion private key for reuse
        self.save_private_key_checkbox = QtWidgets.QCheckBox()
        self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.save_private_key_checkbox.setText(
            strings._("gui_save_private_key_checkbox", True))

        # Sharing options layout
        sharing_group_layout = QtWidgets.QVBoxLayout()
        sharing_group_layout.addWidget(
            self.close_after_first_download_checkbox)
        sharing_group_layout.addWidget(self.systray_notifications_checkbox)
        sharing_group_layout.addWidget(self.save_private_key_checkbox)
        sharing_group = QtWidgets.QGroupBox(
            strings._("gui_settings_sharing_label", True))
        sharing_group.setLayout(sharing_group_layout)

        # Stealth options

        # Stealth
        stealth_details = QtWidgets.QLabel(
            strings._("gui_settings_stealth_option_details", True))
        stealth_details.setWordWrap(True)
        stealth_details.setTextInteractionFlags(
            QtCore.Qt.TextBrowserInteraction)
        stealth_details.setOpenExternalLinks(True)
        self.stealth_checkbox = QtWidgets.QCheckBox()
        self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.stealth_checkbox.setText(
            strings._("gui_settings_stealth_option", True))

        hidservauth_details = QtWidgets.QLabel(
            strings._('gui_settings_stealth_hidservauth_string', True))
        hidservauth_details.setWordWrap(True)
        hidservauth_details.hide()

        self.hidservauth_copy_button = QtWidgets.QPushButton(
            strings._('gui_copy_hidservauth', True))
        self.hidservauth_copy_button.clicked.connect(
            self.hidservauth_copy_button_clicked)
        self.hidservauth_copy_button.hide()

        # Stealth options layout
        stealth_group_layout = QtWidgets.QVBoxLayout()
        stealth_group_layout.addWidget(stealth_details)
        stealth_group_layout.addWidget(self.stealth_checkbox)
        stealth_group_layout.addWidget(hidservauth_details)
        stealth_group_layout.addWidget(self.hidservauth_copy_button)
        stealth_group = QtWidgets.QGroupBox(
            strings._("gui_settings_stealth_label", True))
        stealth_group.setLayout(stealth_group_layout)

        # Automatic updates options

        # Autoupdate
        self.autoupdate_checkbox = QtWidgets.QCheckBox()
        self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.autoupdate_checkbox.setText(
            strings._("gui_settings_autoupdate_option", True))

        # Last update time
        self.autoupdate_timestamp = QtWidgets.QLabel()

        # Check for updates button
        self.check_for_updates_button = QtWidgets.QPushButton(
            strings._('gui_settings_autoupdate_check_button', True))
        self.check_for_updates_button.clicked.connect(self.check_for_updates)
        # We can't check for updates if not connected to Tor
        if not self.onion.connected_to_tor:
            self.check_for_updates_button.setEnabled(False)

        # Autoupdate options layout
        autoupdate_group_layout = QtWidgets.QVBoxLayout()
        autoupdate_group_layout.addWidget(self.autoupdate_checkbox)
        autoupdate_group_layout.addWidget(self.autoupdate_timestamp)
        autoupdate_group_layout.addWidget(self.check_for_updates_button)
        autoupdate_group = QtWidgets.QGroupBox(
            strings._("gui_settings_autoupdate_label", True))
        autoupdate_group.setLayout(autoupdate_group_layout)

        # Autoupdate is only available for Windows and Mac (Linux updates using package manager)
        if system != 'Windows' and system != 'Darwin':
            autoupdate_group.hide()

        # Connection type: either automatic, control port, or socket file

        # Bundled Tor
        self.connection_type_bundled_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_bundled_option', True))
        self.connection_type_bundled_radio.toggled.connect(
            self.connection_type_bundled_toggled)

        # Bundled Tor doesn't work on dev mode in Windows or Mac
        if (system == 'Windows' or system == 'Darwin') and getattr(
                sys, 'onionshare_dev_mode', False):
            self.connection_type_bundled_radio.setEnabled(False)

        # Bridge options for bundled tor

        # No bridges option radio
        self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_tor_bridges_no_bridges_radio_option',
                      True))
        self.tor_bridges_no_bridges_radio.toggled.connect(
            self.tor_bridges_no_bridges_radio_toggled)

        # obfs4 option radio
        # if the obfs4proxy binary is missing, we can't use obfs4 transports
        (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path,
         self.obfs4proxy_file_path) = common.get_tor_paths()
        if not os.path.isfile(self.obfs4proxy_file_path):
            self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(
                strings.
                _('gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy',
                  True))
            self.tor_bridges_use_obfs4_radio.setEnabled(False)
        else:
            self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(
                strings._('gui_settings_tor_bridges_obfs4_radio_option', True))
        self.tor_bridges_use_obfs4_radio.toggled.connect(
            self.tor_bridges_use_obfs4_radio_toggled)

        # Custom bridges radio and textbox
        self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_tor_bridges_custom_radio_option', True))
        self.tor_bridges_use_custom_radio.toggled.connect(
            self.tor_bridges_use_custom_radio_toggled)

        self.tor_bridges_use_custom_label = QtWidgets.QLabel(
            strings._('gui_settings_tor_bridges_custom_label', True))
        self.tor_bridges_use_custom_label.setTextInteractionFlags(
            QtCore.Qt.TextBrowserInteraction)
        self.tor_bridges_use_custom_label.setOpenExternalLinks(True)
        self.tor_bridges_use_custom_textbox = QtWidgets.QPlainTextEdit()
        self.tor_bridges_use_custom_textbox.setMaximumHeight(200)
        self.tor_bridges_use_custom_textbox.setPlaceholderText(
            '[address:port] [identifier]')

        tor_bridges_use_custom_textbox_options_layout = QtWidgets.QVBoxLayout()
        tor_bridges_use_custom_textbox_options_layout.addWidget(
            self.tor_bridges_use_custom_label)
        tor_bridges_use_custom_textbox_options_layout.addWidget(
            self.tor_bridges_use_custom_textbox)

        self.tor_bridges_use_custom_textbox_options = QtWidgets.QWidget()
        self.tor_bridges_use_custom_textbox_options.setLayout(
            tor_bridges_use_custom_textbox_options_layout)
        self.tor_bridges_use_custom_textbox_options.hide()

        # Bridges layout/widget
        bridges_layout = QtWidgets.QVBoxLayout()
        bridges_layout.addWidget(self.tor_bridges_no_bridges_radio)
        bridges_layout.addWidget(self.tor_bridges_use_obfs4_radio)
        bridges_layout.addWidget(self.tor_bridges_use_custom_radio)
        bridges_layout.addWidget(self.tor_bridges_use_custom_textbox_options)

        self.bridges = QtWidgets.QWidget()
        self.bridges.setLayout(bridges_layout)

        # Automatic
        self.connection_type_automatic_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_automatic_option', True))
        self.connection_type_automatic_radio.toggled.connect(
            self.connection_type_automatic_toggled)

        # Control port
        self.connection_type_control_port_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_control_port_option',
                      True))
        self.connection_type_control_port_radio.toggled.connect(
            self.connection_type_control_port_toggled)

        connection_type_control_port_extras_label = QtWidgets.QLabel(
            strings._('gui_settings_control_port_label', True))
        self.connection_type_control_port_extras_address = QtWidgets.QLineEdit(
        )
        self.connection_type_control_port_extras_port = QtWidgets.QLineEdit()
        connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_control_port_extras_layout.addWidget(
            connection_type_control_port_extras_label)
        connection_type_control_port_extras_layout.addWidget(
            self.connection_type_control_port_extras_address)
        connection_type_control_port_extras_layout.addWidget(
            self.connection_type_control_port_extras_port)

        self.connection_type_control_port_extras = QtWidgets.QWidget()
        self.connection_type_control_port_extras.setLayout(
            connection_type_control_port_extras_layout)
        self.connection_type_control_port_extras.hide()

        # Socket file
        self.connection_type_socket_file_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_connection_type_socket_file_option', True))
        self.connection_type_socket_file_radio.toggled.connect(
            self.connection_type_socket_file_toggled)

        connection_type_socket_file_extras_label = QtWidgets.QLabel(
            strings._('gui_settings_socket_file_label', True))
        self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit()
        connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_socket_file_extras_layout.addWidget(
            connection_type_socket_file_extras_label)
        connection_type_socket_file_extras_layout.addWidget(
            self.connection_type_socket_file_extras_path)

        self.connection_type_socket_file_extras = QtWidgets.QWidget()
        self.connection_type_socket_file_extras.setLayout(
            connection_type_socket_file_extras_layout)
        self.connection_type_socket_file_extras.hide()

        # Tor SOCKS address and port
        gui_settings_socks_label = QtWidgets.QLabel(
            strings._('gui_settings_socks_label', True))
        self.connection_type_socks_address = QtWidgets.QLineEdit()
        self.connection_type_socks_port = QtWidgets.QLineEdit()
        connection_type_socks_layout = QtWidgets.QHBoxLayout()
        connection_type_socks_layout.addWidget(gui_settings_socks_label)
        connection_type_socks_layout.addWidget(
            self.connection_type_socks_address)
        connection_type_socks_layout.addWidget(self.connection_type_socks_port)

        self.connection_type_socks = QtWidgets.QWidget()
        self.connection_type_socks.setLayout(connection_type_socks_layout)
        self.connection_type_socks.hide()

        # Authentication options

        # No authentication
        self.authenticate_no_auth_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_authenticate_no_auth_option', True))
        self.authenticate_no_auth_radio.toggled.connect(
            self.authenticate_no_auth_toggled)

        # Password
        self.authenticate_password_radio = QtWidgets.QRadioButton(
            strings._('gui_settings_authenticate_password_option', True))
        self.authenticate_password_radio.toggled.connect(
            self.authenticate_password_toggled)

        authenticate_password_extras_label = QtWidgets.QLabel(
            strings._('gui_settings_password_label', True))
        self.authenticate_password_extras_password = QtWidgets.QLineEdit('')
        authenticate_password_extras_layout = QtWidgets.QHBoxLayout()
        authenticate_password_extras_layout.addWidget(
            authenticate_password_extras_label)
        authenticate_password_extras_layout.addWidget(
            self.authenticate_password_extras_password)

        self.authenticate_password_extras = QtWidgets.QWidget()
        self.authenticate_password_extras.setLayout(
            authenticate_password_extras_layout)
        self.authenticate_password_extras.hide()

        # Authentication options layout
        authenticate_group_layout = QtWidgets.QVBoxLayout()
        authenticate_group_layout.addWidget(self.authenticate_no_auth_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_extras)
        self.authenticate_group = QtWidgets.QGroupBox(
            strings._("gui_settings_authenticate_label", True))
        self.authenticate_group.setLayout(authenticate_group_layout)

        # Test tor settings button
        self.connection_type_test_button = QtWidgets.QPushButton(
            strings._('gui_settings_connection_type_test_button', True))
        self.connection_type_test_button.clicked.connect(self.test_tor_clicked)

        # Put the radios into their own group so they are exclusive
        connection_type_radio_group_layout = QtWidgets.QVBoxLayout()
        connection_type_radio_group_layout.addWidget(
            self.connection_type_bundled_radio)
        connection_type_radio_group_layout.addWidget(
            self.connection_type_automatic_radio)
        connection_type_radio_group_layout.addWidget(
            self.connection_type_control_port_radio)
        connection_type_radio_group_layout.addWidget(
            self.connection_type_socket_file_radio)
        connection_type_radio_group = QtWidgets.QGroupBox(
            strings._("gui_settings_connection_type_label", True))
        connection_type_radio_group.setLayout(
            connection_type_radio_group_layout)

        # Connection type layout
        connection_type_group_layout = QtWidgets.QVBoxLayout()
        connection_type_group_layout.addWidget(
            self.connection_type_control_port_extras)
        connection_type_group_layout.addWidget(
            self.connection_type_socket_file_extras)
        connection_type_group_layout.addWidget(self.connection_type_socks)
        connection_type_group_layout.addWidget(self.authenticate_group)
        connection_type_group_layout.addWidget(
            self.connection_type_test_button)
        connection_type_group = QtWidgets.QGroupBox()
        connection_type_group.setLayout(connection_type_group_layout)

        # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges)
        connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout()
        connection_type_bridges_radio_group_layout.addWidget(self.bridges)
        self.connection_type_bridges_radio_group = QtWidgets.QGroupBox(
            strings._("gui_settings_tor_bridges", True))
        self.connection_type_bridges_radio_group.setLayout(
            connection_type_bridges_radio_group_layout)
        self.connection_type_bridges_radio_group.hide()

        # Buttons
        self.save_button = QtWidgets.QPushButton(
            strings._('gui_settings_button_save', True))
        self.save_button.clicked.connect(self.save_clicked)
        self.cancel_button = QtWidgets.QPushButton(
            strings._('gui_settings_button_cancel', True))
        self.cancel_button.clicked.connect(self.cancel_clicked)
        self.help_button = QtWidgets.QPushButton(
            strings._('gui_settings_button_help', True))
        self.help_button.clicked.connect(self.help_clicked)
        buttons_layout = QtWidgets.QHBoxLayout()
        buttons_layout.addWidget(self.help_button)
        buttons_layout.addStretch()
        buttons_layout.addWidget(self.save_button)
        buttons_layout.addWidget(self.cancel_button)

        # Tor network connection status
        self.tor_status = QtWidgets.QLabel()
        self.tor_status.setStyleSheet(
            'background-color: #ffffff; color: #000000; padding: 10px')
        self.tor_status.hide()

        # Layout
        left_col_layout = QtWidgets.QVBoxLayout()
        left_col_layout.addWidget(sharing_group)
        left_col_layout.addWidget(stealth_group)
        left_col_layout.addWidget(autoupdate_group)
        left_col_layout.addStretch()

        right_col_layout = QtWidgets.QVBoxLayout()
        right_col_layout.addWidget(connection_type_radio_group)
        right_col_layout.addWidget(connection_type_group)
        right_col_layout.addWidget(self.connection_type_bridges_radio_group)
        right_col_layout.addWidget(self.tor_status)
        right_col_layout.addStretch()

        col_layout = QtWidgets.QHBoxLayout()
        col_layout.addLayout(left_col_layout)
        col_layout.addLayout(right_col_layout)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(col_layout)
        layout.addLayout(buttons_layout)

        self.setLayout(layout)
        self.cancel_button.setFocus()

        # Load settings, and fill them in
        self.old_settings = Settings(self.config)
        self.old_settings.load()

        close_after_first_download = self.old_settings.get(
            'close_after_first_download')
        if close_after_first_download:
            self.close_after_first_download_checkbox.setCheckState(
                QtCore.Qt.Checked)
        else:
            self.close_after_first_download_checkbox.setCheckState(
                QtCore.Qt.Unchecked)

        systray_notifications = self.old_settings.get('systray_notifications')
        if systray_notifications:
            self.systray_notifications_checkbox.setCheckState(
                QtCore.Qt.Checked)
        else:
            self.systray_notifications_checkbox.setCheckState(
                QtCore.Qt.Unchecked)

        save_private_key = self.old_settings.get('save_private_key')
        if save_private_key:
            self.save_private_key_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked)

        use_stealth = self.old_settings.get('use_stealth')
        if use_stealth:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Checked)
            if save_private_key:
                hidservauth_details.show()
                self.hidservauth_copy_button.show()
        else:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)

        use_autoupdate = self.old_settings.get('use_autoupdate')
        if use_autoupdate:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)

        autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp')
        self._update_autoupdate_timestamp(autoupdate_timestamp)

        connection_type = self.old_settings.get('connection_type')
        if connection_type == 'bundled':
            if self.connection_type_bundled_radio.isEnabled():
                self.connection_type_bundled_radio.setChecked(True)
            else:
                # If bundled tor is disabled, fallback to automatic
                self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'automatic':
            self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'control_port':
            self.connection_type_control_port_radio.setChecked(True)
        elif connection_type == 'socket_file':
            self.connection_type_socket_file_radio.setChecked(True)
        self.connection_type_control_port_extras_address.setText(
            self.old_settings.get('control_port_address'))
        self.connection_type_control_port_extras_port.setText(
            str(self.old_settings.get('control_port_port')))
        self.connection_type_socket_file_extras_path.setText(
            self.old_settings.get('socket_file_path'))
        self.connection_type_socks_address.setText(
            self.old_settings.get('socks_address'))
        self.connection_type_socks_port.setText(
            str(self.old_settings.get('socks_port')))
        auth_type = self.old_settings.get('auth_type')
        if auth_type == 'no_auth':
            self.authenticate_no_auth_radio.setChecked(True)
        elif auth_type == 'password':
            self.authenticate_password_radio.setChecked(True)
        self.authenticate_password_extras_password.setText(
            self.old_settings.get('auth_password'))

        if self.old_settings.get('no_bridges'):
            self.tor_bridges_no_bridges_radio.setChecked(True)
            self.tor_bridges_use_obfs4_radio.setChecked(False)
            self.tor_bridges_use_custom_radio.setChecked(False)
        else:
            self.tor_bridges_no_bridges_radio.setChecked(False)
            self.tor_bridges_use_obfs4_radio.setChecked(
                self.old_settings.get('tor_bridges_use_obfs4'))
            if self.old_settings.get('tor_bridges_use_custom_bridges'):
                self.tor_bridges_use_custom_radio.setChecked(True)
                # Remove the 'Bridge' lines at the start of each bridge.
                # They are added automatically to provide compatibility with
                # copying/pasting bridges provided from https://bridges.torproject.org
                new_bridges = []
                bridges = self.old_settings.get(
                    'tor_bridges_use_custom_bridges').split('Bridge ')
                for bridge in bridges:
                    new_bridges.append(bridge)
                new_bridges = ''.join(new_bridges)
                self.tor_bridges_use_custom_textbox.setPlainText(new_bridges)
 def test_frozen_windows(self, platform_windows, sys_frozen):
     prefix = os.path.join(os.path.dirname(sys.executable), 'share')
     assert (common.get_resource_path(os.path.join(
         prefix, 'test_filename')) == os.path.join(prefix, 'test_filename'))
Example #32
0
    def update(self):
        """
        Update the GUI elements based on the current state.
        """
        # Set the URL fields
        if self.status == self.STATUS_STARTED:
            self.url_description.show()

            info_image = 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'):
                    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'):
                    self.url_description.setToolTip(strings._('gui_url_label_onetime', True))
                else:
                    self.url_description.setToolTip(strings._('gui_url_label_stay_open', True))

            self.url.setText('http://{0:s}/{1:s}'.format(self.app.onion_host, self.web.slug))
            self.url.show()

            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.settings.get('shutdown_timeout'):
                self.shutdown_timeout_container.hide()

            if self.app.stealth:
                self.copy_hidservauth_button.show()
            else:
                self.copy_hidservauth_button.hide()
        else:
            self.url_description.hide()
            self.url.hide()
            self.copy_url_button.hide()
            self.copy_hidservauth_button.hide()

        # Button
        button_stopped_style = 'QPushButton { background-color: #5fa416; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; }'
        button_working_style = 'QPushButton { background-color: #4c8211; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; font-style: italic; }'
        button_started_style = 'QPushButton { background-color: #d0011b; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; }'
        if self.file_selection.get_num_files() == 0:
            self.server_button.hide()
        else:
            self.server_button.show()

            if self.status == self.STATUS_STOPPED:
                self.server_button.setStyleSheet(button_stopped_style)
                self.server_button.setEnabled(True)
                self.server_button.setText(strings._('gui_start_server', True))
                self.server_button.setToolTip('')
                if self.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'):
                    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'):
                    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'):
                    self.shutdown_timeout_container.hide()
 def test_frozen_darwin(self, platform_darwin, sys_frozen, sys_meipass):
     prefix = os.path.join(sys._MEIPASS, 'share')
     assert (
         common.get_resource_path(os.path.join(prefix, 'test_filename')) ==
         os.path.join(prefix, 'test_filename'))
Example #34
0
    def __init__(self, qtapp, app, web, file_selection, settings):
        super(ServerStatus, self).__init__()
        self.status = self.STATUS_STOPPED

        self.qtapp = qtapp
        self.app = app
        self.web = web
        self.file_selection = file_selection

        self.settings = settings

        # 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))
        # 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()
        shutdown_timeout_layout_group = QtWidgets.QHBoxLayout()
        shutdown_timeout_layout_group.addWidget(
            self.server_shutdown_timeout_checkbox)
        shutdown_timeout_layout_group.addWidget(
            self.server_shutdown_timeout_label)
        shutdown_timeout_layout_group.addWidget(self.server_shutdown_timeout)
        # server layout
        self.status_image_stopped = QtGui.QImage(
            common.get_resource_path('images/server_stopped.png'))
        self.status_image_working = QtGui.QImage(
            common.get_resource_path('images/server_working.png'))
        self.status_image_started = QtGui.QImage(
            common.get_resource_path('images/server_started.png'))
        self.status_image_label = QtWidgets.QLabel()
        self.status_image_label.setFixedWidth(30)
        self.server_button = QtWidgets.QPushButton()
        self.server_button.clicked.connect(self.server_button_clicked)
        server_layout = QtWidgets.QHBoxLayout()
        server_layout.addWidget(self.status_image_label)
        server_layout.addWidget(self.server_button)

        # url layout
        url_font = QtGui.QFont()
        self.url_label = QtWidgets.QLabel()
        self.url_label.setFont(url_font)
        self.url_label.setWordWrap(False)
        self.url_label.setAlignment(QtCore.Qt.AlignCenter)
        self.copy_url_button = QtWidgets.QPushButton(
            strings._('gui_copy_url', True))
        self.copy_url_button.clicked.connect(self.copy_url)
        self.copy_hidservauth_button = QtWidgets.QPushButton(
            strings._('gui_copy_hidservauth', True))
        self.copy_hidservauth_button.clicked.connect(self.copy_hidservauth)
        url_layout = QtWidgets.QHBoxLayout()
        url_layout.addWidget(self.url_label)
        url_layout.addWidget(self.copy_url_button)
        url_layout.addWidget(self.copy_hidservauth_button)

        # add the widgets
        self.addLayout(shutdown_timeout_layout_group)
        self.addLayout(server_layout)
        self.addLayout(url_layout)

        self.update()
 def test_frozen_windows(self, platform_windows, sys_frozen):
     prefix = os.path.join(os.path.dirname(sys.executable), 'share')
     assert (
         common.get_resource_path(os.path.join(prefix, 'test_filename')) ==
         os.path.join(prefix, 'test_filename'))
    def test_get_version(self, sys_onionshare_dev_mode):
        with open(common.get_resource_path('version.txt')) as f:
            version = f.read().strip()

        assert version == common.get_version()
 def test_linux(self, platform_linux, sys_argv_sys_prefix):
     prefix = os.path.join(sys.prefix, 'share/onionshare')
     assert (common.get_resource_path(os.path.join(
         prefix, 'test_filename')) == os.path.join(prefix, 'test_filename'))
    def __init__(self, qtapp, app, web, file_selection):
        super(ServerStatus, self).__init__()
        self.status = self.STATUS_STOPPED

        self.qtapp = qtapp
        self.app = app
        self.web = web
        self.file_selection = file_selection

        # 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))
        # 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()
        shutdown_timeout_layout_group = QtWidgets.QHBoxLayout()
        shutdown_timeout_layout_group.addWidget(self.server_shutdown_timeout_checkbox)
        shutdown_timeout_layout_group.addWidget(self.server_shutdown_timeout_label)
        shutdown_timeout_layout_group.addWidget(self.server_shutdown_timeout)
        # server layout
        self.status_image_stopped = QtGui.QImage(common.get_resource_path('images/server_stopped.png'))
        self.status_image_working = QtGui.QImage(common.get_resource_path('images/server_working.png'))
        self.status_image_started = QtGui.QImage(common.get_resource_path('images/server_started.png'))
        self.status_image_label = QtWidgets.QLabel()
        self.status_image_label.setFixedWidth(30)
        self.server_button = QtWidgets.QPushButton()
        self.server_button.clicked.connect(self.server_button_clicked)
        server_layout = QtWidgets.QHBoxLayout()
        server_layout.addWidget(self.status_image_label)
        server_layout.addWidget(self.server_button)

        # url layout
        url_font = QtGui.QFont()
        self.url_label = QtWidgets.QLabel()
        self.url_label.setFont(url_font)
        self.url_label.setWordWrap(False)
        self.url_label.setAlignment(QtCore.Qt.AlignCenter)
        self.copy_url_button = QtWidgets.QPushButton(strings._('gui_copy_url', True))
        self.copy_url_button.clicked.connect(self.copy_url)
        self.copy_hidservauth_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth', True))
        self.copy_hidservauth_button.clicked.connect(self.copy_hidservauth)
        url_layout = QtWidgets.QHBoxLayout()
        url_layout.addWidget(self.url_label)
        url_layout.addWidget(self.copy_url_button)
        url_layout.addWidget(self.copy_hidservauth_button)

        # add the widgets
        self.addLayout(shutdown_timeout_layout_group)
        self.addLayout(server_layout)
        self.addLayout(url_layout)

        self.update()
Example #39
0
    def update(self):
        """
        Update the GUI elements based on the current state.
        """
        # Set the URL fields
        if self.status == self.STATUS_STARTED:
            self.url_description.show()

            info_image = 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'):
                    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'):
                    self.url_description.setToolTip(
                        strings._('gui_url_label_onetime', True))
                else:
                    self.url_description.setToolTip(
                        strings._('gui_url_label_stay_open', True))

            self.url.setText('http://{0:s}/{1:s}'.format(
                self.app.onion_host, self.web.slug))
            self.url.show()

            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.settings.get('shutdown_timeout'):
                self.shutdown_timeout_container.hide()

            if self.app.stealth:
                self.copy_hidservauth_button.show()
            else:
                self.copy_hidservauth_button.hide()
        else:
            self.url_description.hide()
            self.url.hide()
            self.copy_url_button.hide()
            self.copy_hidservauth_button.hide()

        # Button
        button_stopped_style = 'QPushButton { background-color: #5fa416; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; }'
        button_working_style = 'QPushButton { background-color: #4c8211; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; font-style: italic; }'
        button_started_style = 'QPushButton { background-color: #d0011b; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; }'
        if self.file_selection.get_num_files() == 0:
            self.server_button.hide()
        else:
            self.server_button.show()

            if self.status == self.STATUS_STOPPED:
                self.server_button.setStyleSheet(button_stopped_style)
                self.server_button.setEnabled(True)
                self.server_button.setText(strings._('gui_start_server', True))
                self.server_button.setToolTip('')
                if self.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'):
                    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'):
                    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'):
                    self.shutdown_timeout_container.hide()
 def test_frozen_darwin(self, platform_darwin, sys_frozen, sys_meipass):
     prefix = os.path.join(sys._MEIPASS, 'share')
     assert (common.get_resource_path(os.path.join(
         prefix, 'test_filename')) == os.path.join(prefix, 'test_filename'))
Example #41
0
    def __init__(self, onion, qtapp, config=False):
        super(SettingsDialog, self).__init__()
        common.log('SettingsDialog', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.config = config

        self.setModal(True)
        self.setWindowTitle(strings._('gui_settings_window_title', True))
        self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))

        self.system = platform.system()

        # Sharing options

        # Close after first download
        self.close_after_first_download_checkbox = QtWidgets.QCheckBox()
        self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked)
        self.close_after_first_download_checkbox.setText(strings._("gui_settings_close_after_first_download_option", True))

        # Whether or not to show systray notifications
        self.systray_notifications_checkbox = QtWidgets.QCheckBox()
        self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked)
        self.systray_notifications_checkbox.setText(strings._("gui_settings_systray_notifications", True))

        # Whether or not to use a shutdown timer
        self.shutdown_timeout_checkbox = QtWidgets.QCheckBox()
        self.shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Checked)
        self.shutdown_timeout_checkbox.setText(strings._("gui_settings_shutdown_timeout_checkbox", True))

        # Whether or not to save the Onion private key for reuse
        self.save_private_key_checkbox = QtWidgets.QCheckBox()
        self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.save_private_key_checkbox.setText(strings._("gui_save_private_key_checkbox", True))

        # Sharing options layout
        sharing_group_layout = QtWidgets.QVBoxLayout()
        sharing_group_layout.addWidget(self.close_after_first_download_checkbox)
        sharing_group_layout.addWidget(self.systray_notifications_checkbox)
        sharing_group_layout.addWidget(self.shutdown_timeout_checkbox)
        sharing_group_layout.addWidget(self.save_private_key_checkbox)
        sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label", True))
        sharing_group.setLayout(sharing_group_layout)

        # Stealth options

        # Stealth
        stealth_details = QtWidgets.QLabel(strings._("gui_settings_stealth_option_details", True))
        stealth_details.setWordWrap(True)
        stealth_details.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction)
        stealth_details.setOpenExternalLinks(True)
        stealth_details.setMinimumSize(stealth_details.sizeHint())
        self.stealth_checkbox = QtWidgets.QCheckBox()
        self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.stealth_checkbox.setText(strings._("gui_settings_stealth_option", True))

        hidservauth_details = QtWidgets.QLabel(strings._('gui_settings_stealth_hidservauth_string', True))
        hidservauth_details.setWordWrap(True)
        hidservauth_details.setMinimumSize(hidservauth_details.sizeHint())
        hidservauth_details.hide()

        self.hidservauth_copy_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth', True))
        self.hidservauth_copy_button.clicked.connect(self.hidservauth_copy_button_clicked)
        self.hidservauth_copy_button.hide()

        # Stealth options layout
        stealth_group_layout = QtWidgets.QVBoxLayout()
        stealth_group_layout.addWidget(stealth_details)
        stealth_group_layout.addWidget(self.stealth_checkbox)
        stealth_group_layout.addWidget(hidservauth_details)
        stealth_group_layout.addWidget(self.hidservauth_copy_button)
        stealth_group = QtWidgets.QGroupBox(strings._("gui_settings_stealth_label", True))
        stealth_group.setLayout(stealth_group_layout)

        # Automatic updates options

        # Autoupdate
        self.autoupdate_checkbox = QtWidgets.QCheckBox()
        self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)
        self.autoupdate_checkbox.setText(strings._("gui_settings_autoupdate_option", True))

        # Last update time
        self.autoupdate_timestamp = QtWidgets.QLabel()

        # Check for updates button
        self.check_for_updates_button = QtWidgets.QPushButton(strings._('gui_settings_autoupdate_check_button', True))
        self.check_for_updates_button.clicked.connect(self.check_for_updates)
        # We can't check for updates if not connected to Tor
        if not self.onion.connected_to_tor:
            self.check_for_updates_button.setEnabled(False)

        # Autoupdate options layout
        autoupdate_group_layout = QtWidgets.QVBoxLayout()
        autoupdate_group_layout.addWidget(self.autoupdate_checkbox)
        autoupdate_group_layout.addWidget(self.autoupdate_timestamp)
        autoupdate_group_layout.addWidget(self.check_for_updates_button)
        autoupdate_group = QtWidgets.QGroupBox(strings._("gui_settings_autoupdate_label", True))
        autoupdate_group.setLayout(autoupdate_group_layout)

        # Autoupdate is only available for Windows and Mac (Linux updates using package manager)
        if self.system != 'Windows' and self.system != 'Darwin':
            autoupdate_group.hide()

        # Connection type: either automatic, control port, or socket file

        # Bundled Tor
        self.connection_type_bundled_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_bundled_option', True))
        self.connection_type_bundled_radio.toggled.connect(self.connection_type_bundled_toggled)

        # Bundled Tor doesn't work on dev mode in Windows or Mac
        if (self.system == 'Windows' or self.system == 'Darwin') and getattr(sys, 'onionshare_dev_mode', False):
            self.connection_type_bundled_radio.setEnabled(False)

        # Bridge options for bundled tor

        # No bridges option radio
        self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_no_bridges_radio_option', True))
        self.tor_bridges_no_bridges_radio.toggled.connect(self.tor_bridges_no_bridges_radio_toggled)

        # obfs4 option radio
        # if the obfs4proxy binary is missing, we can't use obfs4 transports
        (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths()
        if not os.path.isfile(self.obfs4proxy_file_path):
            self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy', True))
            self.tor_bridges_use_obfs4_radio.setEnabled(False)
        else:
            self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option', True))
        self.tor_bridges_use_obfs4_radio.toggled.connect(self.tor_bridges_use_obfs4_radio_toggled)

        # meek_lite-amazon option radio
        # if the obfs4proxy binary is missing, we can't use meek_lite-amazon transports
        (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths()
        if not os.path.isfile(self.obfs4proxy_file_path):
            self.tor_bridges_use_meek_lite_amazon_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_obfs4proxy', True))
            self.tor_bridges_use_meek_lite_amazon_radio.setEnabled(False)
        else:
            self.tor_bridges_use_meek_lite_amazon_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_amazon_radio_option', True))
        self.tor_bridges_use_meek_lite_amazon_radio.toggled.connect(self.tor_bridges_use_meek_lite_amazon_radio_toggled)

        # meek_lite-azure option radio
        # if the obfs4proxy binary is missing, we can't use meek_lite-azure transports
        (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths()
        if not os.path.isfile(self.obfs4proxy_file_path):
            self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy', True))
            self.tor_bridges_use_meek_lite_azure_radio.setEnabled(False)
        else:
            self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option', True))
        self.tor_bridges_use_meek_lite_azure_radio.toggled.connect(self.tor_bridges_use_meek_lite_azure_radio_toggled)

        # meek_lite currently not supported on the version of obfs4proxy bundled with TorBrowser
        if self.system == 'Windows' or self.system == 'Darwin':
            self.tor_bridges_use_meek_lite_amazon_radio.hide()
            self.tor_bridges_use_meek_lite_azure_radio.hide()

        # Custom bridges radio and textbox
        self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_custom_radio_option', True))
        self.tor_bridges_use_custom_radio.toggled.connect(self.tor_bridges_use_custom_radio_toggled)

        self.tor_bridges_use_custom_label = QtWidgets.QLabel(strings._('gui_settings_tor_bridges_custom_label', True))
        self.tor_bridges_use_custom_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction)
        self.tor_bridges_use_custom_label.setOpenExternalLinks(True)
        self.tor_bridges_use_custom_textbox = QtWidgets.QPlainTextEdit()
        self.tor_bridges_use_custom_textbox.setMaximumHeight(200)
        self.tor_bridges_use_custom_textbox.setPlaceholderText('[address:port] [identifier]')

        tor_bridges_use_custom_textbox_options_layout = QtWidgets.QVBoxLayout()
        tor_bridges_use_custom_textbox_options_layout.addWidget(self.tor_bridges_use_custom_label)
        tor_bridges_use_custom_textbox_options_layout.addWidget(self.tor_bridges_use_custom_textbox)

        self.tor_bridges_use_custom_textbox_options = QtWidgets.QWidget()
        self.tor_bridges_use_custom_textbox_options.setLayout(tor_bridges_use_custom_textbox_options_layout)
        self.tor_bridges_use_custom_textbox_options.hide()

        # Bridges layout/widget
        bridges_layout = QtWidgets.QVBoxLayout()
        bridges_layout.addWidget(self.tor_bridges_no_bridges_radio)
        bridges_layout.addWidget(self.tor_bridges_use_obfs4_radio)
        bridges_layout.addWidget(self.tor_bridges_use_meek_lite_amazon_radio)
        bridges_layout.addWidget(self.tor_bridges_use_meek_lite_azure_radio)
        bridges_layout.addWidget(self.tor_bridges_use_custom_radio)
        bridges_layout.addWidget(self.tor_bridges_use_custom_textbox_options)

        self.bridges = QtWidgets.QWidget()
        self.bridges.setLayout(bridges_layout)

        # Automatic
        self.connection_type_automatic_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_automatic_option', True))
        self.connection_type_automatic_radio.toggled.connect(self.connection_type_automatic_toggled)

        # Control port
        self.connection_type_control_port_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_control_port_option', True))
        self.connection_type_control_port_radio.toggled.connect(self.connection_type_control_port_toggled)

        connection_type_control_port_extras_label = QtWidgets.QLabel(strings._('gui_settings_control_port_label', True))
        self.connection_type_control_port_extras_address = QtWidgets.QLineEdit()
        self.connection_type_control_port_extras_port = QtWidgets.QLineEdit()
        connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_control_port_extras_layout.addWidget(connection_type_control_port_extras_label)
        connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_address)
        connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_port)

        self.connection_type_control_port_extras = QtWidgets.QWidget()
        self.connection_type_control_port_extras.setLayout(connection_type_control_port_extras_layout)
        self.connection_type_control_port_extras.hide()

        # Socket file
        self.connection_type_socket_file_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_socket_file_option', True))
        self.connection_type_socket_file_radio.toggled.connect(self.connection_type_socket_file_toggled)

        connection_type_socket_file_extras_label = QtWidgets.QLabel(strings._('gui_settings_socket_file_label', True))
        self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit()
        connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout()
        connection_type_socket_file_extras_layout.addWidget(connection_type_socket_file_extras_label)
        connection_type_socket_file_extras_layout.addWidget(self.connection_type_socket_file_extras_path)

        self.connection_type_socket_file_extras = QtWidgets.QWidget()
        self.connection_type_socket_file_extras.setLayout(connection_type_socket_file_extras_layout)
        self.connection_type_socket_file_extras.hide()

        # Tor SOCKS address and port
        gui_settings_socks_label = QtWidgets.QLabel(strings._('gui_settings_socks_label', True))
        self.connection_type_socks_address = QtWidgets.QLineEdit()
        self.connection_type_socks_port = QtWidgets.QLineEdit()
        connection_type_socks_layout = QtWidgets.QHBoxLayout()
        connection_type_socks_layout.addWidget(gui_settings_socks_label)
        connection_type_socks_layout.addWidget(self.connection_type_socks_address)
        connection_type_socks_layout.addWidget(self.connection_type_socks_port)

        self.connection_type_socks = QtWidgets.QWidget()
        self.connection_type_socks.setLayout(connection_type_socks_layout)
        self.connection_type_socks.hide()

        # Authentication options

        # No authentication
        self.authenticate_no_auth_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_no_auth_option', True))
        self.authenticate_no_auth_radio.toggled.connect(self.authenticate_no_auth_toggled)

        # Password
        self.authenticate_password_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_password_option', True))
        self.authenticate_password_radio.toggled.connect(self.authenticate_password_toggled)

        authenticate_password_extras_label = QtWidgets.QLabel(strings._('gui_settings_password_label', True))
        self.authenticate_password_extras_password = QtWidgets.QLineEdit('')
        authenticate_password_extras_layout = QtWidgets.QHBoxLayout()
        authenticate_password_extras_layout.addWidget(authenticate_password_extras_label)
        authenticate_password_extras_layout.addWidget(self.authenticate_password_extras_password)

        self.authenticate_password_extras = QtWidgets.QWidget()
        self.authenticate_password_extras.setLayout(authenticate_password_extras_layout)
        self.authenticate_password_extras.hide()

        # Authentication options layout
        authenticate_group_layout = QtWidgets.QVBoxLayout()
        authenticate_group_layout.addWidget(self.authenticate_no_auth_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_radio)
        authenticate_group_layout.addWidget(self.authenticate_password_extras)
        self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label", True))
        self.authenticate_group.setLayout(authenticate_group_layout)

        # Test tor settings button
        self.connection_type_test_button = QtWidgets.QPushButton(strings._('gui_settings_connection_type_test_button', True))
        self.connection_type_test_button.clicked.connect(self.test_tor_clicked)

        # Put the radios into their own group so they are exclusive
        connection_type_radio_group_layout = QtWidgets.QVBoxLayout()
        connection_type_radio_group_layout.addWidget(self.connection_type_bundled_radio)
        connection_type_radio_group_layout.addWidget(self.connection_type_automatic_radio)
        connection_type_radio_group_layout.addWidget(self.connection_type_control_port_radio)
        connection_type_radio_group_layout.addWidget(self.connection_type_socket_file_radio)
        connection_type_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_connection_type_label", True))
        connection_type_radio_group.setLayout(connection_type_radio_group_layout)

        # Connection type layout
        connection_type_group_layout = QtWidgets.QVBoxLayout()
        connection_type_group_layout.addWidget(self.connection_type_control_port_extras)
        connection_type_group_layout.addWidget(self.connection_type_socket_file_extras)
        connection_type_group_layout.addWidget(self.connection_type_socks)
        connection_type_group_layout.addWidget(self.authenticate_group)
        connection_type_group_layout.addWidget(self.connection_type_test_button)
        connection_type_group = QtWidgets.QGroupBox()
        connection_type_group.setLayout(connection_type_group_layout)

        # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges)
        connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout()
        connection_type_bridges_radio_group_layout.addWidget(self.bridges)
        self.connection_type_bridges_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_tor_bridges", True))
        self.connection_type_bridges_radio_group.setLayout(connection_type_bridges_radio_group_layout)
        self.connection_type_bridges_radio_group.hide()

        # Buttons
        self.save_button = QtWidgets.QPushButton(strings._('gui_settings_button_save', True))
        self.save_button.clicked.connect(self.save_clicked)
        self.cancel_button = QtWidgets.QPushButton(strings._('gui_settings_button_cancel', True))
        self.cancel_button.clicked.connect(self.cancel_clicked)
        version_label = QtWidgets.QLabel('OnionShare {0:s}'.format(common.get_version()))
        version_label.setStyleSheet('color: #666666')
        self.help_button = QtWidgets.QPushButton(strings._('gui_settings_button_help', True))
        self.help_button.clicked.connect(self.help_clicked)
        buttons_layout = QtWidgets.QHBoxLayout()
        buttons_layout.addWidget(version_label)
        buttons_layout.addWidget(self.help_button)
        buttons_layout.addStretch()
        buttons_layout.addWidget(self.save_button)
        buttons_layout.addWidget(self.cancel_button)

        # Tor network connection status
        self.tor_status = QtWidgets.QLabel()
        self.tor_status.setStyleSheet('background-color: #ffffff; color: #000000; padding: 10px')
        self.tor_status.hide()

        # Layout
        left_col_layout = QtWidgets.QVBoxLayout()
        left_col_layout.addWidget(sharing_group)
        left_col_layout.addWidget(stealth_group)
        left_col_layout.addWidget(autoupdate_group)
        left_col_layout.addStretch()

        right_col_layout = QtWidgets.QVBoxLayout()
        right_col_layout.addWidget(connection_type_radio_group)
        right_col_layout.addWidget(connection_type_group)
        right_col_layout.addWidget(self.connection_type_bridges_radio_group)
        right_col_layout.addWidget(self.tor_status)
        right_col_layout.addStretch()

        col_layout = QtWidgets.QHBoxLayout()
        col_layout.addLayout(left_col_layout)
        col_layout.addLayout(right_col_layout)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(col_layout)
        layout.addLayout(buttons_layout)

        self.setLayout(layout)
        self.cancel_button.setFocus()

        # Load settings, and fill them in
        self.old_settings = Settings(self.config)
        self.old_settings.load()

        close_after_first_download = self.old_settings.get('close_after_first_download')
        if close_after_first_download:
            self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Unchecked)

        systray_notifications = self.old_settings.get('systray_notifications')
        if systray_notifications:
            self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Unchecked)

        shutdown_timeout = self.old_settings.get('shutdown_timeout')
        if shutdown_timeout:
            self.shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Unchecked)

        save_private_key = self.old_settings.get('save_private_key')
        if save_private_key:
            self.save_private_key_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked)

        use_stealth = self.old_settings.get('use_stealth')
        if use_stealth:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Checked)
            if save_private_key:
                hidservauth_details.show()
                self.hidservauth_copy_button.show()
        else:
            self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked)

        use_autoupdate = self.old_settings.get('use_autoupdate')
        if use_autoupdate:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked)

        autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp')
        self._update_autoupdate_timestamp(autoupdate_timestamp)

        connection_type = self.old_settings.get('connection_type')
        if connection_type == 'bundled':
            if self.connection_type_bundled_radio.isEnabled():
                self.connection_type_bundled_radio.setChecked(True)
            else:
                # If bundled tor is disabled, fallback to automatic
                self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'automatic':
            self.connection_type_automatic_radio.setChecked(True)
        elif connection_type == 'control_port':
            self.connection_type_control_port_radio.setChecked(True)
        elif connection_type == 'socket_file':
            self.connection_type_socket_file_radio.setChecked(True)
        self.connection_type_control_port_extras_address.setText(self.old_settings.get('control_port_address'))
        self.connection_type_control_port_extras_port.setText(str(self.old_settings.get('control_port_port')))
        self.connection_type_socket_file_extras_path.setText(self.old_settings.get('socket_file_path'))
        self.connection_type_socks_address.setText(self.old_settings.get('socks_address'))
        self.connection_type_socks_port.setText(str(self.old_settings.get('socks_port')))
        auth_type = self.old_settings.get('auth_type')
        if auth_type == 'no_auth':
            self.authenticate_no_auth_radio.setChecked(True)
        elif auth_type == 'password':
            self.authenticate_password_radio.setChecked(True)
        self.authenticate_password_extras_password.setText(self.old_settings.get('auth_password'))

        if self.old_settings.get('no_bridges'):
            self.tor_bridges_no_bridges_radio.setChecked(True)
            self.tor_bridges_use_obfs4_radio.setChecked(False)
            self.tor_bridges_use_meek_lite_amazon_radio.setChecked(False)
            self.tor_bridges_use_meek_lite_azure_radio.setChecked(False)
            self.tor_bridges_use_custom_radio.setChecked(False)
        else:
            self.tor_bridges_no_bridges_radio.setChecked(False)
            self.tor_bridges_use_obfs4_radio.setChecked(self.old_settings.get('tor_bridges_use_obfs4'))
            self.tor_bridges_use_meek_lite_amazon_radio.setChecked(self.old_settings.get('tor_bridges_use_meek_lite_amazon'))
            self.tor_bridges_use_meek_lite_azure_radio.setChecked(self.old_settings.get('tor_bridges_use_meek_lite_azure'))

            if self.old_settings.get('tor_bridges_use_custom_bridges'):
                self.tor_bridges_use_custom_radio.setChecked(True)
                # Remove the 'Bridge' lines at the start of each bridge.
                # They are added automatically to provide compatibility with
                # copying/pasting bridges provided from https://bridges.torproject.org
                new_bridges = []
                bridges = self.old_settings.get('tor_bridges_use_custom_bridges').split('Bridge ')
                for bridge in bridges:
                    new_bridges.append(bridge)
                new_bridges = ''.join(new_bridges)
                self.tor_bridges_use_custom_textbox.setPlainText(new_bridges)
    def __init__(self, onion, qtapp, app, filenames, config=False):
        super(OnionShareGui, self).__init__()

        self._initSystemTray()

        common.log('OnionShareGui', '__init__')

        self.onion = onion
        self.qtapp = qtapp
        self.app = app

        self.setWindowTitle('OnionShare')
        self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png')))

        # Load settings
        self.config = config
        self.settings = Settings(self.config)
        self.settings.load()

        # File selection
        self.file_selection = FileSelection()
        if filenames:
            for filename in filenames:
                self.file_selection.file_list.add_file(filename)

        # Server status
        self.server_status = ServerStatus(self.qtapp, self.app, 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_stopped.connect(self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.stop_server)
        self.start_server_finished.connect(self.clear_message)
        self.start_server_finished.connect(self.server_status.start_server_finished)
        self.stop_server_finished.connect(self.server_status.stop_server_finished)
        self.file_selection.file_list.files_updated.connect(self.server_status.update)
        self.server_status.url_copied.connect(self.copy_url)
        self.server_status.hidservauth_copied.connect(self.copy_hidservauth)
        self.starting_server_step2.connect(self.start_server_step2)
        self.starting_server_step3.connect(self.start_server_step3)
        self.starting_server_error.connect(self.start_server_error)

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setStyleSheet('padding: 10px 0; font-weight: bold; color: #333333;')
        self.filesize_warning.hide()

        # Downloads
        self.downloads = Downloads()
        self.downloads_container = QtWidgets.QScrollArea()
        self.downloads_container.setWidget(self.downloads)
        self.downloads_container.setWidgetResizable(True)
        self.downloads_container.setMaximumHeight(200)
        self.downloads_container.setMinimumHeight(75)
        self.vbar = self.downloads_container.verticalScrollBar()
        self.downloads_container.hide() # downloads start out hidden
        self.new_download = False

        # Status bar
        self.status_bar = QtWidgets.QStatusBar()
        self.status_bar.setSizeGripEnabled(False)
        self.status_bar.setStyleSheet(
            "QStatusBar::item { border: 0px; }")
        version_label = QtWidgets.QLabel('v{0:s}'.format(common.get_version()))
        version_label.setStyleSheet('color: #666666')
        self.settings_button = QtWidgets.QPushButton()
        self.settings_button.setDefault(False)
        self.settings_button.setFlat(True)
        self.settings_button.setIcon( QtGui.QIcon(common.get_resource_path('images/settings.png')) )
        self.settings_button.clicked.connect(self.open_settings)
        self.status_bar.addPermanentWidget(version_label)
        self.status_bar.addPermanentWidget(self.settings_button)
        self.setStatusBar(self.status_bar)

        # Status bar, zip progress bar
        self._zip_progress_bar = None

        # Main layout
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addLayout(self.file_selection)
        self.layout.addLayout(self.server_status)
        self.layout.addWidget(self.filesize_warning)
        self.layout.addWidget(self.downloads_container)
        central_widget = QtWidgets.QWidget()
        central_widget.setLayout(self.layout)
        self.setCentralWidget(central_widget)
        self.show()

        # Check for requests frequently
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.check_for_requests)
        self.timer.start(500)

        # Always start with focus on file selection
        self.file_selection.setFocus()

        # The server isn't active yet
        self.set_server_active(False)

        # Start the "Connecting to Tor" dialog, which calls onion.connect()
        tor_con = TorConnectionDialog(self.qtapp, self.settings, self.onion)
        tor_con.canceled.connect(self._tor_connection_canceled)
        tor_con.open_settings.connect(self._tor_connection_open_settings)
        tor_con.start()

        # After connecting to Tor, check for updates
        self.check_for_updates()