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

            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(error):
                mapping = {
                    files.ExtractionError:
                    lambda: error_dialogs.archive_create(self, archive, error)
                }

                self.base_fail(
                    error,
                    mapping,
                    "Failed to create backup",
                )

            # start the thread, with no timeout
            with thread.thread_wait(
                    backuper.finished,
                    timeout=None,
                    finish_func=finish,
                    failed_signal=backuper.failed,
                    failed_func=failed,
                    update_signal=backuper.activity_update,
            ):
                backuper.start()
        def core(progress):
            progress.set_mode(progress.PERCENT)
            progress.set_activity(
                "Downloading latest version ({})".format(return_url))

            # setup downloader thread
            downloader = version.download_new_version_thread(return_url)
            downloader.percent_update.connect(progress.set_percent)

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

                logger.exception("Failed to download new version")
                error_dialogs.general(self, 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.percent_update,
            ):
                downloader.start()
        def core(progress):
            for i, _id in enumerate(selected):
                # first, get the mod name and disable status
                (folder, enabled) = self.main_table.get_basic_info(_id)

                if not enabled:
                    continue

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

                def failed(error):
                    self.base_fail(error, {}, "Failed to disable mod")

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

                progress.set_percent(i, total=len(selected) - 1)
        def core(progress):
            # setup mover thread
            mover = files.move_folder_thread(old_install, new_install)
            mover.activity_update.connect(progress.set_activity)

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

                logger.exception("Failed to move folder")
                error_dialogs.general(self, typ, message)

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

            config.set_key_value(config.MOD_INSTALL_FOLDER_KEY,
                                 new_install,
                                 path=True)
            information_dialogs.disabled_mods_folder(self, new_install)
        def core(progress: Callable) -> None:
            for i, _id in enumerate(selected):
                # first, get the mod name and enabled status
                (folder, enabled) = self.main_table.get_basic_info(_id)

                if enabled:
                    continue

                # setup enabler thread
                enabler = flight_sim.enable_mod_thread(self.flight_sim, folder)
                enabler.activity_update.connect(
                    progress.set_activity)  # type: ignore

                def failed(err: Exception) -> None:
                    self.base_fail(err, {}, "Failed to enable mod")

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

                progress.set_percent(i, total=len(selected) - 1)
        def core(progress: Callable) -> None:
            # setup mover thread
            mover = flight_sim.move_mod_install_folder_thread(
                self.flight_sim, old_install, new_install)
            mover.activity_update.connect(
                progress.set_activity)  # type: ignore

            def failed(err: Exception) -> None:
                typ = type(err)
                message = str(err)

                logger.exception("Failed to move mod install folder")
                error_dialogs.general(self, typ, message)

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

            # done
            information_dialogs.mod_install_folder_set(self, new_install)
Beispiel #7
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)
        def core(progress: Callable) -> None:
            # for each archive, try to install it
            for mod_archive in mod_archives:

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

                def failed(err: Exception) -> None:
                    message = str(err)

                    mapping = {
                        files.ExtractionError:
                        lambda: error_dialogs.archive_extract(
                            self, mod_archive, message),
                        flight_sim.NoManifestError:
                        lambda: warning_dialogs.mod_parsing(
                            self, [mod_archive]),
                        files.AccessError:
                        lambda: error_dialogs.permission(
                            self, mod_archive, message),
                        flight_sim.NoModsError:
                        lambda: error_dialogs.no_mods(self, mod_archive),
                    }

                    self.base_fail(
                        err,
                        mapping,
                        "Failed to install mod archive",
                    )

                # setup installer thread
                installer = flight_sim.install_mod_archive_thread(
                    self.flight_sim, mod_archive)
                installer.activity_update.connect(
                    progress.set_activity)  # type: ignore
                installer.percent_update.connect(
                    progress.set_percent)  # type: ignore

                # start the thread
                with thread.thread_wait(
                        installer.finished,
                        finish_func=finish,
                        failed_signal=installer.failed,
                        failed_func=failed,
                        update_signal=installer.activity_update,
                        timeout=1200000,
                ):
                    installer.start()
Beispiel #9
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)
    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)
Beispiel #11
0
        def core(progress):
            for i, _id in enumerate(selected):
                # first, get the mod name and enabled status
                (folder, enabled) = self.main_table.get_basic_info(_id)
                mod_folder = self.flight_sim.get_mod_folder(folder, enabled)

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

                def failed(error):
                    self.base_fail(error, {}, "Failed to uninstall mod")

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

                progress.set_percent(i, total=len(selected) - 1)
Beispiel #12
0
        def core(progress):
            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(error):
                mapping = {
                    flight_sim.NoManifestError:
                    lambda: warning_dialogs.mod_parsing(self, [mod_folder]),
                    files.AccessError:
                    lambda: error_dialogs.permission(self, mod_folder, error),
                    flight_sim.NoModsError:
                    lambda: error_dialogs.no_mods(self, mod_folder),
                }

                self.base_fail(
                    error,
                    mapping,
                    "Failed to install mod folder",
                )

            # setup installer thread
            installer = flight_sim.install_mods_thread(self.flight_sim,
                                                       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()
Beispiel #13
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
Beispiel #14
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()