Esempio n. 1
0
    def uninstall(self):
        """Uninstalls selected mods."""
        self.uninstall_button.setEnabled(False)

        selected = self.get_selected_rows()

        if selected:
            # sanity check
            result = QtWidgets.QMessageBox().information(
                self,
                "Confirmation",
                "This will permamentaly delete {} mod(s). Are you sure you want to continue?".format(
                    len(selected)
                ),
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                QtWidgets.QMessageBox.No,
            )
            if result == QtWidgets.QMessageBox.No:
                self.uninstall_button.setEnabled(True)
                return

        progress = progress_widget(self, self.appctxt)
        progress.set_infinite()

        for _id in self.get_selected_rows():
            # first, get the mod name and enabled status
            (mod_folder, enabled) = self.main_table.get_basic_info(_id)

            # setup uninstaller thread
            uninstaller = flight_sim.uninstall_mod_thread(
                self.sim_folder, mod_folder, enabled
            )
            uninstaller.activity_update.connect(progress.set_activity)

            def failed(err):
                typ = type(err)
                message = err

                logger.exception("Failed to uninstall mod")
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Something went terribly wrong.\n{}: {}".format(typ, message),
                )

            # start the thread
            with thread.thread_wait(
                uninstaller.finished,
                failed_signal=uninstaller.failed,
                failed_func=failed,
                update_signal=uninstaller.activity_update,
            ):
                uninstaller.start()

        # refresh the data
        self.refresh()

        self.uninstall_button.setEnabled(True)
Esempio n. 2
0
    def check_version(self):
        """Checks the application version and allows user to open browser to update."""
        installed = version.is_installed()
        return_url = version.check_version(self.appctxt, installed)

        if return_url:
            result, remember = version_check_widget(self, installed).exec_()
            if result == QtWidgets.QMessageBox.Yes:
                if installed:
                    # progress bar
                    progress = progress_widget(self, self.appctxt)
                    progress.set_percent()
                    progress.set_activity(
                        "Downloading latest version ({})".format(return_url)
                    )

                    # setup downloader thread
                    downloader = version.download_new_version_thread(return_url)
                    downloader.activity_update.connect(progress.set_percentage)

                    def failed(err):
                        typ = type(err)
                        message = err

                        logger.exception("Failed to download new version")
                        QtWidgets.QMessageBox().warning(
                            self,
                            "Error",
                            "Something went terribly wrong.\n{}: {}".format(
                                typ, message
                            ),
                        )

                    # start the thread
                    with thread.thread_wait(
                        downloader.finished,
                        finish_func=version.install_new_version,
                        failed_signal=downloader.failed,
                        failed_func=failed,
                        update_signal=downloader.activity_update,
                    ):
                        downloader.start()

                    progress.close()
                else:
                    webbrowser.open(return_url)
            elif remember:
                config.set_key_value(config.NEVER_VER_CHEK_KEY, True)
Esempio n. 3
0
    def disable(self):
        """Disables selected mods."""
        self.disable_button.setEnabled(False)

        progress = progress_widget(self, self.appctxt)
        progress.set_infinite()

        for _id in self.get_selected_rows():
            # first, get the mod name and disable status
            (mod_folder, enabled) = self.main_table.get_basic_info(_id)

            if not enabled:
                continue

            # setup disabler thread
            disabler = flight_sim.disable_mod_thread(self.sim_folder,
                                                     mod_folder)
            disabler.activity_update.connect(progress.set_activity)

            def failed(err):
                typ = type(err)
                message = err

                logger.exception("Failed to disable mod")
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Something went terribly wrong.\n{}: {}".format(
                        typ, message),
                )

            # start the thread
            with thread.thread_wait(
                    disabler.finished,
                    failed_signal=disabler.failed,
                    failed_func=failed,
                    update_signal=disabler.activity_update,
            ):
                disabler.start()

        # refresh the data
        self.refresh()

        progress.close()
        self.disable_button.setEnabled(True)
Esempio n. 4
0
    def base_action(
        self,
        core_func,
        button=None,
        sanity_dialog=None,
        empty_check=False,
        empty_val=None,
        refresh=True,
    ):
        """Base function for GUI actions."""
        if empty_check and not empty_val:
            return

        if button:
            button.setEnabled(False)

        # sanity check
        if sanity_dialog:
            question = sanity_dialog()
            if not question:
                # cancel
                button.setEnabled(True)
                return

        # build progress widget
        progress = progress_widget(self, self.appctxt)
        progress.set_mode(progress.INFINITE)

        # execute the core function
        core_func(progress)
        progress.close()

        # refresh the data
        if refresh:
            self.refresh(automated=True)

        # cleanup
        if button:
            button.setEnabled(True)
Esempio n. 5
0
    def create_backup(self):
        """Creates a backup of all enabled mods."""

        archive = QtWidgets.QFileDialog.getSaveFileName(
            parent=self,
            caption="Save Backup As",
            dir=os.path.join(
                config.BASE_FOLDER,
                "msfs-mod-backup-{}.zip".format(
                    datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
                ),
            ),
            filter=ARCHIVE_FILTER,
        )[0]

        # no selection will be blank
        if not archive:
            return

        progress = progress_widget(self, self.appctxt)
        progress.set_infinite()

        # setup backuper thread
        backuper = flight_sim.create_backup_thread(self.sim_folder, archive)
        backuper.activity_update.connect(progress.set_activity)

        def failed(err):
            typ = type(err)
            message = err

            if flight_sim.ExtractionError == typ:
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Unable to create archive {}. You need to install a program which can create this, such as 7zip or WinRar.".format(
                        archive
                    ),
                )
            else:
                logger.exception("Failed to create backup")
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Something went terribly wrong.\n{}: {}".format(typ, message),
                )

        # start the thread, with extra 20 min timeout
        with thread.thread_wait(
            backuper.finished,
            timeout=1200000,
            failed_signal=backuper.failed,
            failed_func=failed,
            update_signal=backuper.activity_update,
        ):
            backuper.start()

        result = QtWidgets.QMessageBox().information(
            self,
            "Success",
            "Backup successfully saved to {}. Would you like to open this directory?".format(
                archive
            ),
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
            QtWidgets.QMessageBox.Yes,
        )
        # open resulting directory
        if result == QtWidgets.QMessageBox.Yes:
            # this will always be opening a folder and therefore is safe
            os.startfile(os.path.dirname(archive))  # nosec
Esempio n. 6
0
    def install_folder(self):
        """Installs selected mod folders."""
        # self.install_button.setEnabled(False)

        # first, let user select multiple folders
        mod_folder = QtWidgets.QFileDialog.getExistingDirectory(
            parent=self,
            caption="Select mod folder",
            dir=os.path.join(os.path.expanduser("~"), "Downloads"),
        )

        # cancel if result was empty
        if not mod_folder:
            return

        progress = progress_widget(self, self.appctxt)
        progress.set_infinite()

        succeeded = []

        def finish(result):
            # this function is required as the results will be a list,
            # which is not a hashable type
            succeeded.extend(result)

        def failed(err):
            typ = type(err)
            message = err

            if flight_sim.NoManifestError == typ:
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Unable to install mod {}. This is likely due to it missing a manifest.json file.".format(
                        mod_folder
                    ),
                )
            elif files.AccessError == typ:
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Unable to install mod {} due to a permissions issue (unable to delete file/folder {}). Relaunch the program as an administrator.".format(
                        mod_folder, message
                    ),
                )
            elif flight_sim.NoModsError == typ:
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Unable to find any mods inside {}".format(mod_folder),
                )
            else:
                logger.exception("Failed to install mod folder")
                QtWidgets.QMessageBox().warning(
                    self,
                    "Error",
                    "Something went terribly wrong.\n{}: {}".format(typ, message),
                )

        # setup installer thread
        installer = flight_sim.install_mods_thread(self.sim_folder, mod_folder)
        installer.activity_update.connect(progress.set_activity)

        # start the thread
        with thread.thread_wait(
            installer.finished,
            finish_func=finish,
            failed_signal=installer.failed,
            failed_func=failed,
            update_signal=installer.activity_update,
        ):
            installer.start()

        progress.close()

        if succeeded:
            QtWidgets.QMessageBox().information(
                self,
                "Success",
                "{} mod(s) installed!\n{}".format(
                    len(succeeded), "\n".join(["- {}".format(mod) for mod in succeeded])
                ),
            )

        # refresh the data
        self.refresh()