예제 #1
0
def web_obj(common_obj, mode, num_files=0):
    """ Creates a Web object, in either share mode or receive mode, ready for testing """
    common_obj.settings = Settings(common_obj)
    strings.load_strings(common_obj)
    web = Web(common_obj, False, mode)
    web.generate_slug()
    web.stay_open = True
    web.running = True

    web.app.testing = True

    # Share mode
    if mode == 'share':
        # Add files
        files = []
        for i in range(num_files):
            with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
                tmp_file.write(b'*' * 1024)
                files.append(tmp_file.name)
        web.share_mode.set_file_info(files)
    # Receive mode
    else:
        pass

    return web
예제 #2
0
def web_obj(temp_dir, common_obj, mode, num_files=0):
    """ Creates a Web object, in either share mode or receive mode, ready for testing """
    common_obj.settings = Settings(common_obj)
    strings.load_strings(common_obj)
    mode_settings = ModeSettings(common_obj)
    web = Web(common_obj, False, mode_settings, mode)
    web.generate_password()
    web.running = True

    web.app.testing = True

    # Share mode
    if mode == "share":
        # Add files
        files = []
        for _ in range(num_files):
            with tempfile.NamedTemporaryFile(delete=False,
                                             dir=temp_dir) as tmp_file:
                tmp_file.write(b"*" * 1024)
                files.append(tmp_file.name)
        web.share_mode.set_file_info(files)
    # Receive mode
    else:
        pass

    return web
예제 #3
0
    def init(self):
        """
        Custom initialization for ChatMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, self.settings, "chat")

        # Chat image
        self.image_label = QtWidgets.QLabel()
        self.image_label.setPixmap(
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path("images/mode_chat.png"))))
        self.image_label.setFixedSize(300, 300)
        image_layout = QtWidgets.QVBoxLayout()
        image_layout.addStretch()
        image_layout.addWidget(self.image_label)
        image_layout.addStretch()
        self.image = QtWidgets.QWidget()
        self.image.setLayout(image_layout)

        # Server status
        self.server_status.set_mode("chat")
        self.server_status.server_started_finished.connect(
            self.update_primary_action)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.update_primary_action)
        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Header
        header_label = QtWidgets.QLabel(strings._("gui_new_tab_chat_button"))
        header_label.setStyleSheet(self.common.gui.css["mode_header_label"])

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addStretch()

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addStretch()
        self.main_layout.addWidget(header_label)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addWidget(self.server_status)
        self.main_layout.addStretch()
        self.main_layout.addWidget(MinimumWidthWidget(700))

        # Column layout
        self.column_layout = QtWidgets.QHBoxLayout()
        self.column_layout.addWidget(self.image)
        self.column_layout.addLayout(self.main_layout)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QVBoxLayout()
        self.wrapper_layout.addLayout(self.column_layout)
        self.setLayout(self.wrapper_layout)
예제 #4
0
def web_obj(common_obj, mode, num_files=0):
    """ Creates a Web object, in either share mode or receive mode, ready for testing """
    common_obj.load_settings()
    strings.load_strings(common_obj)
    web = Web(common_obj, False, mode)
    web.generate_slug()
    web.stay_open = True
    web.running = True

    web.app.testing = True

    # Share mode
    if mode == 'share':
        # Add files
        files = []
        for i in range(num_files):
            with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
                tmp_file.write(b'*' * 1024)
                files.append(tmp_file.name)
        web.share_mode.set_file_info(files)
    # Receive mode
    else:
        pass

    return web
예제 #5
0
    def set_up(test_settings):
        """Create GUI with given settings"""
        # Create our test file
        testfile = open("/tmp/test.txt", "w")
        testfile.write("onionshare")
        testfile.close()

        # Create a test dir and files
        if not os.path.exists("/tmp/testdir"):
            testdir = os.mkdir("/tmp/testdir")
        testfile = open("/tmp/testdir/test.txt", "w")
        testfile.write("onionshare")
        testfile.close()

        common = Common()
        common.settings = Settings(common)
        common.define_css()
        strings.load_strings(common)

        # Get all of the settings in test_settings
        test_settings["connection_type"] = "automatic"
        test_settings["data_dir"] = "/tmp/OnionShare"
        for key, val in common.settings.default_settings.items():
            if key not in test_settings:
                test_settings[key] = val

        # Start the Onion
        testonion = Onion(common)
        global qtapp
        qtapp = Application(common)
        app = OnionShare(common, testonion, False, 0)

        web = Web(common, False, False)
        open("/tmp/settings.json", "w").write(json.dumps(test_settings))

        gui = OnionShareGui(
            common,
            testonion,
            qtapp,
            app,
            ["/tmp/test.txt", "/tmp/testdir"],
            "/tmp/settings.json",
            False,
        )
        return gui
예제 #6
0
    def set_up(test_settings):
        '''Create GUI with given settings'''
        # Create our test file
        testfile = open('/tmp/test.txt', 'w')
        testfile.write('onionshare')
        testfile.close()

        # Create a test dir and files
        if not os.path.exists('/tmp/testdir'):
            testdir = os.mkdir('/tmp/testdir')
        testfile = open('/tmp/testdir/test.txt', 'w')
        testfile.write('onionshare')
        testfile.close()

        common = Common()
        common.settings = Settings(common)
        common.define_css()
        strings.load_strings(common)

        # Get all of the settings in test_settings
        test_settings['connection_type'] = 'automatic'
        test_settings['data_dir'] = '/tmp/OnionShare'
        for key, val in common.settings.default_settings.items():
            if key not in test_settings:
                test_settings[key] = val

        # Start the Onion
        testonion = Onion(common)
        global qtapp
        qtapp = Application(common)
        app = OnionShare(common, testonion, False, 0)

        web = Web(common, False, False)
        open('/tmp/settings.json', 'w').write(json.dumps(test_settings))

        gui = OnionShareGui(common, testonion, qtapp, app,
                            ['/tmp/test.txt', '/tmp/testdir'],
                            '/tmp/settings.json', False)
        return gui
예제 #7
0
    def set_up(test_settings):
        """Create GUI with given settings"""
        # Create our test file
        testfile = open("/tmp/index.html", "w")
        testfile.write(
            "<html><body><p>This is a test website hosted by OnionShare</p></body></html>"
        )
        testfile.close()

        common = Common()
        common.settings = Settings(common)
        common.define_css()
        strings.load_strings(common)

        # Get all of the settings in test_settings
        test_settings["data_dir"] = "/tmp/OnionShare"
        for key, val in common.settings.default_settings.items():
            if key not in test_settings:
                test_settings[key] = val

        # Start the Onion
        testonion = Onion(common)
        global qtapp
        qtapp = Application(common)
        app = OnionShare(common, testonion, True, 0)

        web = Web(common, False, True)
        open("/tmp/settings.json", "w").write(json.dumps(test_settings))

        gui = OnionShareGui(
            common,
            testonion,
            qtapp,
            app,
            ["/tmp/index.html"],
            "/tmp/settings.json",
            True,
        )
        return gui
예제 #8
0
    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, self.settings, "website")

        # Settings
        self.disable_csp_checkbox = QtWidgets.QCheckBox()
        self.disable_csp_checkbox.clicked.connect(
            self.disable_csp_checkbox_clicked)
        self.disable_csp_checkbox.setText(
            strings._("mode_settings_website_disable_csp_checkbox"))
        if self.settings.get("website", "disable_csp"):
            self.disable_csp_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.disable_csp_checkbox.setCheckState(QtCore.Qt.Unchecked)

        self.mode_settings_widget.mode_specific_layout.addWidget(
            self.disable_csp_checkbox)

        # File selection
        self.file_selection = FileSelection(
            self.common,
            "images/mode_website.png",
            strings._("gui_new_tab_website_button"),
            self,
        )
        if self.filenames:
            for filename in self.filenames:
                self.file_selection.file_list.add_file(filename)

        # Server status
        self.server_status.set_mode("website", self.file_selection)
        self.server_status.server_started.connect(
            self.file_selection.server_started)
        self.server_status.server_stopped.connect(
            self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(
            self.file_selection.server_stopped)
        self.server_status.server_canceled.connect(self.update_primary_action)
        self.file_selection.file_list.files_updated.connect(
            self.server_status.update)
        self.file_selection.file_list.files_updated.connect(
            self.update_primary_action)
        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setWordWrap(True)
        self.filesize_warning.setStyleSheet(
            self.common.gui.css["share_filesize_warning"])
        self.filesize_warning.hide()

        # Download history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        "images/share_icon_transparent.png"))),
            strings._("gui_website_mode_no_files"),
            strings._("gui_all_modes_history"),
            "website",
        )
        self.history.in_progress_label.hide()
        self.history.completed_label.hide()
        self.history.hide()

        # Info label
        self.info_label = QtWidgets.QLabel()
        self.info_label.hide()

        # Delete all files button
        self.remove_all_button = QtWidgets.QPushButton(
            strings._("gui_file_selection_remove_all"))
        self.remove_all_button.setFlat(True)
        self.remove_all_button.setStyleSheet(
            self.common.gui.css["share_delete_all_files_button"])
        self.remove_all_button.clicked.connect(self.delete_all)
        self.remove_all_button.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common,
            self,
            self.history,
            QtGui.QIcon(
                self.common.get_resource_path("images/share_icon_toggle.png")),
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/share_icon_toggle_selected.png")),
        )

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addWidget(self.info_label)
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.remove_all_button)
        top_bar_layout.addWidget(self.toggle_history)

        # Primary action layout
        self.primary_action_layout.addWidget(self.filesize_warning)
        self.primary_action.hide()
        self.update_primary_action()

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addLayout(self.file_selection)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addWidget(self.server_status)
        self.main_layout.addWidget(MinimumWidthWidget(700))

        # Column layout
        self.column_layout = QtWidgets.QHBoxLayout()
        self.column_layout.addLayout(self.main_layout)
        self.column_layout.addWidget(self.history, stretch=1)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QVBoxLayout()
        self.wrapper_layout.addLayout(self.column_layout)
        self.setLayout(self.wrapper_layout)

        # Always start with focus on file selection
        self.file_selection.setFocus()
예제 #9
0
class WebsiteMode(Mode):
    """
    Parts of the main window UI for sharing files.
    """

    success = QtCore.pyqtSignal()
    error = QtCore.pyqtSignal(str)

    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, self.settings, "website")

        # Settings
        self.disable_csp_checkbox = QtWidgets.QCheckBox()
        self.disable_csp_checkbox.clicked.connect(
            self.disable_csp_checkbox_clicked)
        self.disable_csp_checkbox.setText(
            strings._("mode_settings_website_disable_csp_checkbox"))
        if self.settings.get("website", "disable_csp"):
            self.disable_csp_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.disable_csp_checkbox.setCheckState(QtCore.Qt.Unchecked)

        self.mode_settings_widget.mode_specific_layout.addWidget(
            self.disable_csp_checkbox)

        # File selection
        self.file_selection = FileSelection(
            self.common,
            "images/mode_website.png",
            strings._("gui_new_tab_website_button"),
            self,
        )
        if self.filenames:
            for filename in self.filenames:
                self.file_selection.file_list.add_file(filename)

        # Server status
        self.server_status.set_mode("website", self.file_selection)
        self.server_status.server_started.connect(
            self.file_selection.server_started)
        self.server_status.server_stopped.connect(
            self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(
            self.file_selection.server_stopped)
        self.server_status.server_canceled.connect(self.update_primary_action)
        self.file_selection.file_list.files_updated.connect(
            self.server_status.update)
        self.file_selection.file_list.files_updated.connect(
            self.update_primary_action)
        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setWordWrap(True)
        self.filesize_warning.setStyleSheet(
            self.common.gui.css["share_filesize_warning"])
        self.filesize_warning.hide()

        # Download history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        "images/share_icon_transparent.png"))),
            strings._("gui_website_mode_no_files"),
            strings._("gui_all_modes_history"),
            "website",
        )
        self.history.in_progress_label.hide()
        self.history.completed_label.hide()
        self.history.hide()

        # Info label
        self.info_label = QtWidgets.QLabel()
        self.info_label.hide()

        # Delete all files button
        self.remove_all_button = QtWidgets.QPushButton(
            strings._("gui_file_selection_remove_all"))
        self.remove_all_button.setFlat(True)
        self.remove_all_button.setStyleSheet(
            self.common.gui.css["share_delete_all_files_button"])
        self.remove_all_button.clicked.connect(self.delete_all)
        self.remove_all_button.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common,
            self,
            self.history,
            QtGui.QIcon(
                self.common.get_resource_path("images/share_icon_toggle.png")),
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/share_icon_toggle_selected.png")),
        )

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addWidget(self.info_label)
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.remove_all_button)
        top_bar_layout.addWidget(self.toggle_history)

        # Primary action layout
        self.primary_action_layout.addWidget(self.filesize_warning)
        self.primary_action.hide()
        self.update_primary_action()

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addLayout(self.file_selection)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addWidget(self.server_status)
        self.main_layout.addWidget(MinimumWidthWidget(700))

        # Column layout
        self.column_layout = QtWidgets.QHBoxLayout()
        self.column_layout.addLayout(self.main_layout)
        self.column_layout.addWidget(self.history, stretch=1)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QVBoxLayout()
        self.wrapper_layout.addLayout(self.column_layout)
        self.setLayout(self.wrapper_layout)

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

    def disable_csp_checkbox_clicked(self):
        """
        Save disable CSP setting to the tab settings
        """
        self.settings.set("website", "disable_csp",
                          self.disable_csp_checkbox.isChecked())

    def get_stop_server_autostop_timer_text(self):
        """
        Return the string to put on the stop server button, if there's an auto-stop timer
        """
        return strings._("gui_share_stop_server_autostop_timer")

    def autostop_timer_finished_should_stop_server(self):
        """
        The auto-stop timer expired, should we stop the server? Returns a bool
        """

        self.server_status.stop_server()
        self.server_status_label.setText(strings._("close_on_autostop_timer"))
        return True

    def start_server_custom(self):
        """
        Starting the server.
        """
        # Reset web counters
        self.web.website_mode.visit_count = 0
        self.web.reset_invalid_passwords()

        # Hide and reset the downloads if we have previously shared
        self.reset_info_counters()

        self.remove_all_button.hide()

    def start_server_step2_custom(self):
        """
        Step 2 in starting the server. Zipping up files.
        """
        self.filenames = []
        for index in range(self.file_selection.file_list.count()):
            self.filenames.append(
                self.file_selection.file_list.item(index).filename)

        # Continue
        self.starting_server_step3.emit()
        self.start_server_finished.emit()

    def start_server_step3_custom(self):
        """
        Step 3 in starting the server. Display large filesize
        warning, if applicable.
        """
        self.web.website_mode.set_file_info(self.filenames)
        self.success.emit()

    def start_server_error_custom(self):
        """
        Start server error.
        """
        if self._zip_progress_bar is not None:
            self.status_bar.removeWidget(self._zip_progress_bar)
            self._zip_progress_bar = None

    def stop_server_custom(self):
        """
        Stop server.
        """

        self.filesize_warning.hide()
        self.history.completed_count = 0
        self.file_selection.file_list.adjustSize()

        self.remove_all_button.show()

    def cancel_server_custom(self):
        """
        Log that the server has been cancelled
        """
        self.common.log("WebsiteMode", "cancel_server")

    def handle_tor_broke_custom(self):
        """
        Connection to Tor broke.
        """
        self.primary_action.hide()

    def on_reload_settings(self):
        """
        If there were some files listed for sharing, we should be ok to re-enable
        the 'Start Sharing' button now.
        """
        if self.server_status.file_selection.get_num_files() > 0:
            self.primary_action.show()
            self.info_label.show()
            self.remove_all_button.show()

    def update_primary_action(self):
        self.common.log("WebsiteMode", "update_primary_action")

        # Show or hide primary action layout
        file_count = self.file_selection.file_list.count()
        if file_count > 0:
            self.primary_action.show()
            self.info_label.show()
            self.remove_all_button.show()

            # Update the file count in the info label
            total_size_bytes = 0
            for index in range(self.file_selection.file_list.count()):
                item = self.file_selection.file_list.item(index)
                total_size_bytes += item.size_bytes
            total_size_readable = self.common.human_readable_filesize(
                total_size_bytes)

            if file_count > 1:
                self.info_label.setText(
                    strings._("gui_file_info").format(file_count,
                                                      total_size_readable))
            else:
                self.info_label.setText(
                    strings._("gui_file_info_single").format(
                        file_count, total_size_readable))

        else:
            self.primary_action.hide()
            self.info_label.hide()
            self.remove_all_button.hide()

    def reset_info_counters(self):
        """
        Set the info counters back to zero.
        """
        self.history.reset()
        self.toggle_history.indicator_count = 0
        self.toggle_history.update_indicator()

    def delete_all(self):
        """
        Delete All button clicked
        """
        self.file_selection.file_list.clear()
        self.file_selection.file_list.files_updated.emit()

        self.file_selection.file_list.setCurrentItem(None)

    @staticmethod
    def _compute_total_size(filenames):
        total_size = 0
        for filename in filenames:
            if os.path.isfile(filename):
                total_size += os.path.getsize(filename)
            if os.path.isdir(filename):
                total_size += Common.dir_size(filename)
        return total_size
예제 #10
0
class ChatMode(Mode):
    """
    Parts of the main window UI for sharing files.
    """

    success = QtCore.pyqtSignal()
    error = QtCore.pyqtSignal(str)

    def init(self):
        """
        Custom initialization for ChatMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, self.settings, "chat")

        # Chat image
        self.image_label = QtWidgets.QLabel()
        self.image_label.setPixmap(
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path("images/mode_chat.png"))))
        self.image_label.setFixedSize(300, 300)
        image_layout = QtWidgets.QVBoxLayout()
        image_layout.addStretch()
        image_layout.addWidget(self.image_label)
        image_layout.addStretch()
        self.image = QtWidgets.QWidget()
        self.image.setLayout(image_layout)

        # Server status
        self.server_status.set_mode("chat")
        self.server_status.server_started_finished.connect(
            self.update_primary_action)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.update_primary_action)
        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Header
        header_label = QtWidgets.QLabel(strings._("gui_new_tab_chat_button"))
        header_label.setStyleSheet(self.common.gui.css["mode_header_label"])

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addStretch()

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addStretch()
        self.main_layout.addWidget(header_label)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addWidget(self.server_status)
        self.main_layout.addStretch()
        self.main_layout.addWidget(MinimumWidthWidget(700))

        # Column layout
        self.column_layout = QtWidgets.QHBoxLayout()
        self.column_layout.addWidget(self.image)
        self.column_layout.addLayout(self.main_layout)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QVBoxLayout()
        self.wrapper_layout.addLayout(self.column_layout)
        self.setLayout(self.wrapper_layout)

    def get_stop_server_autostop_timer_text(self):
        """
        Return the string to put on the stop server button, if there's an auto-stop timer
        """
        return strings._("gui_share_stop_server_autostop_timer")

    def autostop_timer_finished_should_stop_server(self):
        """
        The auto-stop timer expired, should we stop the server? Returns a bool
        """

        self.server_status.stop_server()
        self.server_status_label.setText(strings._("close_on_autostop_timer"))
        return True

    def start_server_custom(self):
        """
        Starting the server.
        """
        # Reset web counters
        self.web.chat_mode.cur_history_id = 0
        self.web.reset_invalid_passwords()

    def start_server_step2_custom(self):
        """
        Step 2 in starting the server. Zipping up files.
        """
        # Continue
        self.starting_server_step3.emit()
        self.start_server_finished.emit()

    def cancel_server_custom(self):
        """
        Log that the server has been cancelled
        """
        self.common.log("ChatMode", "cancel_server")

    def handle_tor_broke_custom(self):
        """
        Connection to Tor broke.
        """
        self.primary_action.hide()

    def on_reload_settings(self):
        """
        We should be ok to re-enable the 'Start Receive Mode' button now.
        """
        self.primary_action.show()

    def update_primary_action(self):
        self.common.log("ChatMode", "update_primary_action")
예제 #11
0
    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, 'receive')

        # Server status
        self.server_status.set_mode('receive')
        self.server_status.server_started_finished.connect(
            self.update_primary_action)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.update_primary_action)

        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Upload history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        'images/receive_icon_transparent.png'))),
            strings._('gui_receive_mode_no_files'),
            strings._('gui_all_modes_history'))
        self.history.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common, self, self.history,
            QtGui.QIcon(
                self.common.get_resource_path(
                    'images/receive_icon_toggle.png')),
            QtGui.QIcon(
                self.common.get_resource_path(
                    'images/receive_icon_toggle_selected.png')))

        # Receive mode warning
        receive_warning = QtWidgets.QLabel(
            strings._('gui_receive_mode_warning'))
        receive_warning.setMinimumHeight(80)
        receive_warning.setWordWrap(True)

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.toggle_history)

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addWidget(receive_warning)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addStretch()
        self.main_layout.addWidget(self.min_width_widget)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QHBoxLayout()
        self.wrapper_layout.addLayout(self.main_layout)
        self.wrapper_layout.addWidget(self.history, stretch=1)
        self.setLayout(self.wrapper_layout)
예제 #12
0
    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Threads start out as None
        self.compress_thread = None

        # Create the Web object
        self.web = Web(self.common, True, 'share')

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

        # Server status
        self.server_status.set_mode('share', self.file_selection)
        self.server_status.server_started.connect(
            self.file_selection.server_started)
        self.server_status.server_stopped.connect(
            self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(
            self.file_selection.server_stopped)
        self.server_status.server_canceled.connect(self.update_primary_action)
        self.file_selection.file_list.files_updated.connect(
            self.server_status.update)
        self.file_selection.file_list.files_updated.connect(
            self.update_primary_action)
        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setWordWrap(True)
        self.filesize_warning.setStyleSheet(
            self.common.css['share_filesize_warning'])
        self.filesize_warning.hide()

        # Download history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        'images/share_icon_transparent.png'))),
            strings._('gui_share_mode_no_files'),
            strings._('gui_all_modes_history'))
        self.history.hide()

        # Info label
        self.info_label = QtWidgets.QLabel()
        self.info_label.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common, self, self.history,
            QtGui.QIcon(
                self.common.get_resource_path('images/share_icon_toggle.png')),
            QtGui.QIcon(
                self.common.get_resource_path(
                    'images/share_icon_toggle_selected.png')))

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addWidget(self.info_label)
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.toggle_history)

        # Primary action layout
        self.primary_action_layout.addWidget(self.filesize_warning)
        self.primary_action.hide()
        self.update_primary_action()

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

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addLayout(self.file_selection)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addWidget(self.min_width_widget)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QHBoxLayout()
        self.wrapper_layout.addLayout(self.main_layout)
        self.wrapper_layout.addWidget(self.history, stretch=1)
        self.setLayout(self.wrapper_layout)

        # Always start with focus on file selection
        self.file_selection.setFocus()
예제 #13
0
class ShareMode(Mode):
    """
    Parts of the main window UI for sharing files.
    """
    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Threads start out as None
        self.compress_thread = None

        # Create the Web object
        self.web = Web(self.common, True, self.settings, "share")

        # Settings
        self.autostop_sharing_checkbox = QtWidgets.QCheckBox()
        self.autostop_sharing_checkbox.clicked.connect(
            self.autostop_sharing_checkbox_clicked)
        self.autostop_sharing_checkbox.setText(
            strings._("mode_settings_share_autostop_sharing_checkbox"))
        if self.settings.get("share", "autostop_sharing"):
            self.autostop_sharing_checkbox.setCheckState(QtCore.Qt.Checked)
        else:
            self.autostop_sharing_checkbox.setCheckState(QtCore.Qt.Unchecked)

        self.mode_settings_widget.mode_specific_layout.addWidget(
            self.autostop_sharing_checkbox)

        # File selection
        self.file_selection = FileSelection(
            self.common,
            "images/mode_share.png",
            strings._("gui_new_tab_share_button"),
            self,
        )
        if self.filenames:
            for filename in self.filenames:
                self.file_selection.file_list.add_file(filename)

        # Server status
        self.server_status.set_mode("share", self.file_selection)
        self.server_status.server_started.connect(
            self.file_selection.server_started)
        self.server_status.server_stopped.connect(
            self.file_selection.server_stopped)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(
            self.file_selection.server_stopped)
        self.server_status.server_canceled.connect(self.update_primary_action)
        self.file_selection.file_list.files_updated.connect(
            self.server_status.update)
        self.file_selection.file_list.files_updated.connect(
            self.update_primary_action)
        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Filesize warning
        self.filesize_warning = QtWidgets.QLabel()
        self.filesize_warning.setWordWrap(True)
        self.filesize_warning.setStyleSheet(
            self.common.gui.css["share_filesize_warning"])
        self.filesize_warning.hide()

        # Download history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        "images/share_icon_transparent.png"))),
            strings._("gui_share_mode_no_files"),
            strings._("gui_all_modes_history"),
        )
        self.history.hide()

        # Info label
        self.info_label = QtWidgets.QLabel()
        self.info_label.hide()

        # Delete all files button
        self.remove_all_button = QtWidgets.QPushButton(
            strings._("gui_file_selection_remove_all"))
        self.remove_all_button.setFlat(True)
        self.remove_all_button.setStyleSheet(
            self.common.gui.css["share_delete_all_files_button"])
        self.remove_all_button.clicked.connect(self.delete_all)
        self.remove_all_button.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common,
            self,
            self.history,
            QtGui.QIcon(
                self.common.get_resource_path("images/share_icon_toggle.png")),
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/share_icon_toggle_selected.png")),
        )

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addWidget(self.info_label)
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.remove_all_button)
        top_bar_layout.addWidget(self.toggle_history)

        # Primary action layout
        self.primary_action_layout.addWidget(self.filesize_warning)
        self.primary_action.hide()
        self.update_primary_action()

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

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addLayout(self.file_selection)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addWidget(self.server_status)
        self.main_layout.addWidget(MinimumWidthWidget(700))

        # Column layout
        self.column_layout = QtWidgets.QHBoxLayout()
        self.column_layout.addLayout(self.main_layout)
        self.column_layout.addWidget(self.history, stretch=1)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QVBoxLayout()
        self.wrapper_layout.addLayout(self.column_layout)
        self.setLayout(self.wrapper_layout)

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

    def autostop_sharing_checkbox_clicked(self):
        """
        Save autostop sharing setting to the tab settings
        """
        self.settings.set("share", "autostop_sharing",
                          self.autostop_sharing_checkbox.isChecked())

    def get_stop_server_autostop_timer_text(self):
        """
        Return the string to put on the stop server button, if there's an auto-stop timer
        """
        return strings._("gui_share_stop_server_autostop_timer")

    def autostop_timer_finished_should_stop_server(self):
        """
        The auto-stop timer expired, should we stop the server? Returns a bool
        """
        # If there were no attempts to download the share, or all downloads are done, we can stop
        if self.history.in_progress_count == 0 or self.web.done:
            self.server_status.stop_server()
            self.server_status_label.setText(
                strings._("close_on_autostop_timer"))
            return True
        # A download is probably still running - hold off on stopping the share
        else:
            self.server_status_label.setText(
                strings._("gui_share_mode_autostop_timer_waiting"))
            return False

    def start_server_custom(self):
        """
        Starting the server.
        """
        # Reset web counters
        self.web.share_mode.cur_history_id = 0
        self.web.reset_invalid_passwords()

        # Hide and reset the downloads if we have previously shared
        self.reset_info_counters()

        self.remove_all_button.hide()

    def start_server_step2_custom(self):
        """
        Step 2 in starting the server. Zipping up files.
        """
        # Add progress bar to the status bar, indicating the compressing of files.
        self._zip_progress_bar = ZipProgressBar(self.common, 0)
        self.filenames = self.file_selection.get_filenames()

        self._zip_progress_bar.total_files_size = ShareMode._compute_total_size(
            self.filenames)
        self.status_bar.insertWidget(0, self._zip_progress_bar)

        # prepare the files for sending in a new thread
        self.compress_thread = CompressThread(self)
        self.compress_thread.success.connect(self.starting_server_step3.emit)
        self.compress_thread.success.connect(self.start_server_finished.emit)
        self.compress_thread.error.connect(self.starting_server_error.emit)
        self.server_status.server_canceled.connect(self.compress_thread.cancel)
        self.compress_thread.start()

    def start_server_step3_custom(self):
        """
        Step 3 in starting the server. Remove zip progess bar, and display large filesize
        warning, if applicable.
        """
        # Remove zip progress bar
        if self._zip_progress_bar is not None:
            self.status_bar.removeWidget(self._zip_progress_bar)
            self._zip_progress_bar = None

        # Warn about sending large files over Tor
        if self.web.share_mode.download_filesize >= 157286400:  # 150mb
            self.filesize_warning.setText(strings._("large_filesize"))
            self.filesize_warning.show()

    def start_server_error_custom(self):
        """
        Start server error.
        """
        if self._zip_progress_bar is not None:
            self.status_bar.removeWidget(self._zip_progress_bar)
            self._zip_progress_bar = None

    def stop_server_custom(self):
        """
        Stop server.
        """
        # Remove the progress bar
        if self._zip_progress_bar is not None:
            self.status_bar.removeWidget(self._zip_progress_bar)
            self._zip_progress_bar = None

        self.filesize_warning.hide()
        self.history.in_progress_count = 0
        self.history.completed_count = 0
        self.history.update_in_progress()
        self.file_selection.file_list.adjustSize()

        self.remove_all_button.show()

    def cancel_server_custom(self):
        """
        Stop the compression thread on cancel
        """
        if self.compress_thread:
            self.common.log("ShareMode",
                            "cancel_server: quitting compress thread")
            self.compress_thread.quit()

    def handle_tor_broke_custom(self):
        """
        Connection to Tor broke.
        """
        self.primary_action.hide()

    def handle_request_started(self, event):
        """
        Handle REQUEST_STARTED event.
        """
        if event["data"]["use_gzip"]:
            filesize = self.web.share_mode.gzip_filesize
        else:
            filesize = self.web.share_mode.download_filesize

        item = ShareHistoryItem(self.common, event["data"]["id"], filesize)
        self.history.add(event["data"]["id"], item)
        self.toggle_history.update_indicator(True)
        self.history.in_progress_count += 1
        self.history.update_in_progress()

        self.system_tray.showMessage(
            strings._("systray_share_started_title"),
            strings._("systray_share_started_message"),
        )

    def handle_request_progress(self, event):
        """
        Handle REQUEST_PROGRESS event.
        """
        self.history.update(event["data"]["id"], event["data"]["bytes"])

        # Is the download complete?
        if event["data"]["bytes"] == self.web.share_mode.filesize:
            self.system_tray.showMessage(
                strings._("systray_share_completed_title"),
                strings._("systray_share_completed_message"),
            )

            # Update completed and in progress labels
            self.history.completed_count += 1
            self.history.in_progress_count -= 1
            self.history.update_completed()
            self.history.update_in_progress()

            # Close on finish?
            if self.settings.get("share", "autostop_sharing"):
                self.server_status.stop_server()
                self.status_bar.clearMessage()
                self.server_status_label.setText(
                    strings._("closing_automatically"))
        else:
            if self.server_status.status == self.server_status.STATUS_STOPPED:
                self.history.cancel(event["data"]["id"])
                self.history.in_progress_count = 0
                self.history.update_in_progress()

    def handle_request_canceled(self, event):
        """
        Handle REQUEST_CANCELED event.
        """
        self.history.cancel(event["data"]["id"])

        # Update in progress count
        self.history.in_progress_count -= 1
        self.history.update_in_progress()
        self.system_tray.showMessage(
            strings._("systray_share_canceled_title"),
            strings._("systray_share_canceled_message"),
        )

    def on_reload_settings(self):
        """
        If there were some files listed for sharing, we should be ok to re-enable
        the 'Start Sharing' button now.
        """
        if self.server_status.file_selection.get_num_files() > 0:
            self.primary_action.show()
            self.info_label.show()
            self.remove_all_button.show()

    def update_primary_action(self):
        self.common.log("ShareMode", "update_primary_action")

        # Show or hide primary action layout
        file_count = self.file_selection.file_list.count()
        if file_count > 0:
            self.primary_action.show()
            self.info_label.show()
            self.remove_all_button.show()

            # Update the file count in the info label
            total_size_bytes = 0
            for index in range(self.file_selection.file_list.count()):
                item = self.file_selection.file_list.item(index)
                total_size_bytes += item.size_bytes
            total_size_readable = self.common.human_readable_filesize(
                total_size_bytes)

            if file_count > 1:
                self.info_label.setText(
                    strings._("gui_file_info").format(file_count,
                                                      total_size_readable))
            else:
                self.info_label.setText(
                    strings._("gui_file_info_single").format(
                        file_count, total_size_readable))

        else:
            self.primary_action.hide()
            self.info_label.hide()
            self.remove_all_button.hide()

    def reset_info_counters(self):
        """
        Set the info counters back to zero.
        """
        self.history.reset()
        self.toggle_history.indicator_count = 0
        self.toggle_history.update_indicator()

    def delete_all(self):
        """
        Delete All button clicked
        """
        self.file_selection.file_list.clear()
        self.file_selection.file_list.files_updated.emit()

        self.file_selection.file_list.setCurrentItem(None)

    @staticmethod
    def _compute_total_size(filenames):
        total_size = 0
        for filename in filenames:
            if os.path.isfile(filename):
                total_size += os.path.getsize(filename)
            if os.path.isdir(filename):
                total_size += Common.dir_size(filename)
        return total_size
예제 #14
0
class ReceiveMode(Mode):
    """
    Parts of the main window UI for receiving files.
    """
    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, "receive")

        # Server status
        self.server_status.set_mode("receive")
        self.server_status.server_started_finished.connect(
            self.update_primary_action)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.update_primary_action)

        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Upload history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        "images/receive_icon_transparent.png"))),
            strings._("gui_receive_mode_no_files"),
            strings._("gui_all_modes_history"),
        )
        self.history.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common,
            self,
            self.history,
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/receive_icon_toggle.png")),
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/receive_icon_toggle_selected.png")),
        )

        # Receive mode warning
        receive_warning = QtWidgets.QLabel(
            strings._("gui_receive_mode_warning"))
        receive_warning.setMinimumHeight(80)
        receive_warning.setWordWrap(True)

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.toggle_history)

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addWidget(receive_warning)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addStretch()
        self.main_layout.addWidget(self.min_width_widget)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QHBoxLayout()
        self.wrapper_layout.addLayout(self.main_layout)
        self.wrapper_layout.addWidget(self.history, stretch=1)
        self.setLayout(self.wrapper_layout)

    def get_stop_server_autostop_timer_text(self):
        """
        Return the string to put on the stop server button, if there's an auto-stop timer
        """
        return strings._("gui_receive_stop_server_autostop_timer")

    def autostop_timer_finished_should_stop_server(self):
        """
        The auto-stop timer expired, should we stop the server? Returns a bool
        """
        # If there were no attempts to upload files, or all uploads are done, we can stop
        if (self.web.receive_mode.cur_history_id == 0
                or not self.web.receive_mode.uploads_in_progress):
            self.server_status.stop_server()
            self.server_status_label.setText(
                strings._("close_on_autostop_timer"))
            return True
        # An upload is probably still running - hold off on stopping the share, but block new shares.
        else:
            self.server_status_label.setText(
                strings._("gui_receive_mode_autostop_timer_waiting"))
            self.web.receive_mode.can_upload = False
            return False

    def start_server_custom(self):
        """
        Starting the server.
        """
        # Reset web counters
        self.web.receive_mode.cur_history_id = 0
        self.web.reset_invalid_passwords()

        # Hide and reset the uploads if we have previously shared
        self.reset_info_counters()

    def start_server_step2_custom(self):
        """
        Step 2 in starting the server.
        """
        # Continue
        self.starting_server_step3.emit()
        self.start_server_finished.emit()

    def handle_tor_broke_custom(self):
        """
        Connection to Tor broke.
        """
        self.primary_action.hide()

    def handle_request_load(self, event):
        """
        Handle REQUEST_LOAD event.
        """
        self.system_tray.showMessage(
            strings._("systray_page_loaded_title"),
            strings._("systray_page_loaded_message"),
        )

    def handle_request_started(self, event):
        """
        Handle REQUEST_STARTED event.
        """
        item = ReceiveHistoryItem(self.common, event["data"]["id"],
                                  event["data"]["content_length"])
        self.history.add(event["data"]["id"], item)
        self.toggle_history.update_indicator(True)
        self.history.in_progress_count += 1
        self.history.update_in_progress()

        self.system_tray.showMessage(
            strings._("systray_receive_started_title"),
            strings._("systray_receive_started_message"),
        )

    def handle_request_progress(self, event):
        """
        Handle REQUEST_PROGRESS event.
        """
        self.history.update(
            event["data"]["id"],
            {
                "action": "progress",
                "progress": event["data"]["progress"]
            },
        )

    def handle_request_upload_file_renamed(self, event):
        """
        Handle REQUEST_UPLOAD_FILE_RENAMED event.
        """
        self.history.update(
            event["data"]["id"],
            {
                "action": "rename",
                "old_filename": event["data"]["old_filename"],
                "new_filename": event["data"]["new_filename"],
            },
        )

    def handle_request_upload_set_dir(self, event):
        """
        Handle REQUEST_UPLOAD_SET_DIR event.
        """
        self.history.update(
            event["data"]["id"],
            {
                "action": "set_dir",
                "filename": event["data"]["filename"],
                "dir": event["data"]["dir"],
            },
        )

    def handle_request_upload_finished(self, event):
        """
        Handle REQUEST_UPLOAD_FINISHED event.
        """
        self.history.update(event["data"]["id"], {"action": "finished"})
        self.history.completed_count += 1
        self.history.in_progress_count -= 1
        self.history.update_completed()
        self.history.update_in_progress()

    def handle_request_upload_canceled(self, event):
        """
        Handle REQUEST_UPLOAD_CANCELED event.
        """
        self.history.update(event["data"]["id"], {"action": "canceled"})
        self.history.in_progress_count -= 1
        self.history.update_in_progress()

    def on_reload_settings(self):
        """
        We should be ok to re-enable the 'Start Receive Mode' button now.
        """
        self.primary_action.show()

    def reset_info_counters(self):
        """
        Set the info counters back to zero.
        """
        self.history.reset()
        self.toggle_history.indicator_count = 0
        self.toggle_history.update_indicator()

    def update_primary_action(self):
        self.common.log("ReceiveMode", "update_primary_action")
예제 #15
0
    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, self.settings, "receive")

        # Receive image
        self.image_label = QtWidgets.QLabel()
        self.image_label.setPixmap(
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path("images/mode_receive.png"))))
        self.image_label.setFixedSize(300, 300)
        image_layout = QtWidgets.QVBoxLayout()
        image_layout.addStretch()
        image_layout.addWidget(self.image_label)
        image_layout.addStretch()
        self.image = QtWidgets.QWidget()
        self.image.setLayout(image_layout)

        # Settings
        data_dir_label = QtWidgets.QLabel(
            strings._("mode_settings_receive_data_dir_label"))
        self.data_dir_lineedit = QtWidgets.QLineEdit()
        self.data_dir_lineedit.setReadOnly(True)
        self.data_dir_lineedit.setText(self.settings.get(
            "receive", "data_dir"))
        data_dir_button = QtWidgets.QPushButton(
            strings._("mode_settings_receive_data_dir_browse_button"))
        data_dir_button.clicked.connect(self.data_dir_button_clicked)
        data_dir_layout = QtWidgets.QHBoxLayout()
        data_dir_layout.addWidget(data_dir_label)
        data_dir_layout.addWidget(self.data_dir_lineedit)
        data_dir_layout.addWidget(data_dir_button)

        self.mode_settings_widget.mode_specific_layout.addLayout(
            data_dir_layout)

        # Server status
        self.server_status.set_mode("receive")
        self.server_status.server_started_finished.connect(
            self.update_primary_action)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.update_primary_action)

        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Upload history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        "images/receive_icon_transparent.png"))),
            strings._("gui_receive_mode_no_files"),
            strings._("gui_all_modes_history"),
        )
        self.history.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common,
            self,
            self.history,
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/receive_icon_toggle.png")),
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/receive_icon_toggle_selected.png")),
        )

        # Header
        header_label = QtWidgets.QLabel(
            strings._("gui_new_tab_receive_button"))
        header_label.setStyleSheet(self.common.gui.css["mode_header_label"])

        # Receive mode warning
        receive_warning = QtWidgets.QLabel(
            strings._("gui_receive_mode_warning"))
        receive_warning.setMinimumHeight(80)
        receive_warning.setWordWrap(True)

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.toggle_history)

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addStretch()
        self.main_layout.addWidget(header_label)
        self.main_layout.addWidget(receive_warning)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addStretch()
        self.main_layout.addWidget(MinimumWidthWidget(700))

        # Column layout
        self.column_layout = QtWidgets.QHBoxLayout()
        self.column_layout.addWidget(self.image)
        self.column_layout.addLayout(self.main_layout)
        self.column_layout.addWidget(self.history, stretch=1)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QVBoxLayout()
        self.wrapper_layout.addLayout(self.column_layout)
        self.setLayout(self.wrapper_layout)
예제 #16
0
class ReceiveMode(Mode):
    """
    Parts of the main window UI for receiving files.
    """
    def init(self):
        """
        Custom initialization for ReceiveMode.
        """
        # Create the Web object
        self.web = Web(self.common, True, self.settings, "receive")

        # Receive image
        self.image_label = QtWidgets.QLabel()
        self.image_label.setPixmap(
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path("images/mode_receive.png"))))
        self.image_label.setFixedSize(300, 300)
        image_layout = QtWidgets.QVBoxLayout()
        image_layout.addStretch()
        image_layout.addWidget(self.image_label)
        image_layout.addStretch()
        self.image = QtWidgets.QWidget()
        self.image.setLayout(image_layout)

        # Settings
        data_dir_label = QtWidgets.QLabel(
            strings._("mode_settings_receive_data_dir_label"))
        self.data_dir_lineedit = QtWidgets.QLineEdit()
        self.data_dir_lineedit.setReadOnly(True)
        self.data_dir_lineedit.setText(self.settings.get(
            "receive", "data_dir"))
        data_dir_button = QtWidgets.QPushButton(
            strings._("mode_settings_receive_data_dir_browse_button"))
        data_dir_button.clicked.connect(self.data_dir_button_clicked)
        data_dir_layout = QtWidgets.QHBoxLayout()
        data_dir_layout.addWidget(data_dir_label)
        data_dir_layout.addWidget(self.data_dir_lineedit)
        data_dir_layout.addWidget(data_dir_button)

        self.mode_settings_widget.mode_specific_layout.addLayout(
            data_dir_layout)

        # Server status
        self.server_status.set_mode("receive")
        self.server_status.server_started_finished.connect(
            self.update_primary_action)
        self.server_status.server_stopped.connect(self.update_primary_action)
        self.server_status.server_canceled.connect(self.update_primary_action)

        # Tell server_status about web, then update
        self.server_status.web = self.web
        self.server_status.update()

        # Upload history
        self.history = History(
            self.common,
            QtGui.QPixmap.fromImage(
                QtGui.QImage(
                    self.common.get_resource_path(
                        "images/receive_icon_transparent.png"))),
            strings._("gui_receive_mode_no_files"),
            strings._("gui_all_modes_history"),
        )
        self.history.hide()

        # Toggle history
        self.toggle_history = ToggleHistory(
            self.common,
            self,
            self.history,
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/receive_icon_toggle.png")),
            QtGui.QIcon(
                self.common.get_resource_path(
                    "images/receive_icon_toggle_selected.png")),
        )

        # Header
        header_label = QtWidgets.QLabel(
            strings._("gui_new_tab_receive_button"))
        header_label.setStyleSheet(self.common.gui.css["mode_header_label"])

        # Receive mode warning
        receive_warning = QtWidgets.QLabel(
            strings._("gui_receive_mode_warning"))
        receive_warning.setMinimumHeight(80)
        receive_warning.setWordWrap(True)

        # Top bar
        top_bar_layout = QtWidgets.QHBoxLayout()
        top_bar_layout.addStretch()
        top_bar_layout.addWidget(self.toggle_history)

        # Main layout
        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addLayout(top_bar_layout)
        self.main_layout.addStretch()
        self.main_layout.addWidget(header_label)
        self.main_layout.addWidget(receive_warning)
        self.main_layout.addWidget(self.primary_action)
        self.main_layout.addStretch()
        self.main_layout.addWidget(MinimumWidthWidget(700))

        # Column layout
        self.column_layout = QtWidgets.QHBoxLayout()
        self.column_layout.addWidget(self.image)
        self.column_layout.addLayout(self.main_layout)
        self.column_layout.addWidget(self.history, stretch=1)

        # Wrapper layout
        self.wrapper_layout = QtWidgets.QVBoxLayout()
        self.wrapper_layout.addLayout(self.column_layout)
        self.setLayout(self.wrapper_layout)

    def data_dir_button_clicked(self):
        """
        Browse for a new OnionShare data directory, and save to tab settings
        """
        data_dir = self.data_dir_lineedit.text()
        selected_dir = QtWidgets.QFileDialog.getExistingDirectory(
            self, strings._("mode_settings_receive_data_dir_label"), data_dir)

        if selected_dir:
            # If we're running inside a flatpak package, the data dir must be inside ~/OnionShare
            if self.common.gui.is_flatpak:
                if not selected_dir.startswith(
                        os.path.expanduser("~/OnionShare")):
                    Alert(self.common,
                          strings._("gui_receive_flatpak_data_dir"))
                    return

            self.common.log(
                "ReceiveMode",
                "data_dir_button_clicked",
                f"selected dir: {selected_dir}",
            )
            self.data_dir_lineedit.setText(selected_dir)
            self.settings.set("receive", "data_dir", selected_dir)

    def get_stop_server_autostop_timer_text(self):
        """
        Return the string to put on the stop server button, if there's an auto-stop timer
        """
        return strings._("gui_receive_stop_server_autostop_timer")

    def autostop_timer_finished_should_stop_server(self):
        """
        The auto-stop timer expired, should we stop the server? Returns a bool
        """
        # If there were no attempts to upload files, or all uploads are done, we can stop
        if (self.web.receive_mode.cur_history_id == 0
                or not self.web.receive_mode.uploads_in_progress):
            self.server_status.stop_server()
            self.server_status_label.setText(
                strings._("close_on_autostop_timer"))
            return True
        # An upload is probably still running - hold off on stopping the share, but block new shares.
        else:
            self.server_status_label.setText(
                strings._("gui_receive_mode_autostop_timer_waiting"))
            self.web.receive_mode.can_upload = False
            return False

    def start_server_custom(self):
        """
        Starting the server.
        """
        # Reset web counters
        self.web.receive_mode.cur_history_id = 0
        self.web.reset_invalid_passwords()

        # Hide and reset the uploads if we have previously shared
        self.reset_info_counters()

    def start_server_step2_custom(self):
        """
        Step 2 in starting the server.
        """
        # Continue
        self.starting_server_step3.emit()
        self.start_server_finished.emit()

    def handle_tor_broke_custom(self):
        """
        Connection to Tor broke.
        """
        self.primary_action.hide()

    def handle_request_load(self, event):
        """
        Handle REQUEST_LOAD event.
        """
        self.system_tray.showMessage(
            strings._("systray_page_loaded_title"),
            strings._("systray_page_loaded_message"),
        )

    def handle_request_started(self, event):
        """
        Handle REQUEST_STARTED event.
        """
        item = ReceiveHistoryItem(self.common, event["data"]["id"],
                                  event["data"]["content_length"])
        self.history.add(event["data"]["id"], item)
        self.toggle_history.update_indicator(True)
        self.history.in_progress_count += 1
        self.history.update_in_progress()

        self.system_tray.showMessage(
            strings._("systray_receive_started_title"),
            strings._("systray_receive_started_message"),
        )

    def handle_request_progress(self, event):
        """
        Handle REQUEST_PROGRESS event.
        """
        self.history.update(
            event["data"]["id"],
            {
                "action": "progress",
                "progress": event["data"]["progress"]
            },
        )

    def handle_request_upload_file_renamed(self, event):
        """
        Handle REQUEST_UPLOAD_FILE_RENAMED event.
        """
        self.history.update(
            event["data"]["id"],
            {
                "action": "rename",
                "old_filename": event["data"]["old_filename"],
                "new_filename": event["data"]["new_filename"],
            },
        )

    def handle_request_upload_set_dir(self, event):
        """
        Handle REQUEST_UPLOAD_SET_DIR event.
        """
        self.history.update(
            event["data"]["id"],
            {
                "action": "set_dir",
                "filename": event["data"]["filename"],
                "dir": event["data"]["dir"],
            },
        )

    def handle_request_upload_finished(self, event):
        """
        Handle REQUEST_UPLOAD_FINISHED event.
        """
        self.history.update(event["data"]["id"], {"action": "finished"})
        self.history.completed_count += 1
        self.history.in_progress_count -= 1
        self.history.update_completed()
        self.history.update_in_progress()

    def handle_request_upload_canceled(self, event):
        """
        Handle REQUEST_UPLOAD_CANCELED event.
        """
        self.history.update(event["data"]["id"], {"action": "canceled"})
        self.history.in_progress_count -= 1
        self.history.update_in_progress()

    def on_reload_settings(self):
        """
        We should be ok to re-enable the 'Start Receive Mode' button now.
        """
        self.primary_action.show()

    def reset_info_counters(self):
        """
        Set the info counters back to zero.
        """
        self.history.reset()
        self.toggle_history.indicator_count = 0
        self.toggle_history.update_indicator()

    def update_primary_action(self):
        self.common.log("ReceiveMode", "update_primary_action")