From 7c71b60fb5ce04cb3acdef8c7697eba71944c312 Mon Sep 17 00:00:00 2001 From: xgui4 <134389196+xgui4@users.noreply.github.com> Date: Sat, 16 May 2026 00:10:28 -0400 Subject: [PATCH] formated with uv format --- hatch_build.py | 3 +- packages.py | 2 +- .../io.github.xgui4.lce_qt_launcher.yml | 7 - run.py | 2 +- src/lce_qt_launcher/__init__.py | 11 +- src/lce_qt_launcher/app.py | 34 ++- src/lce_qt_launcher/app_context.py | 77 ++--- src/lce_qt_launcher/build_info.py | 20 +- src/lce_qt_launcher/features.py | 181 +++++++---- src/lce_qt_launcher/main.py | 87 +++--- .../managers/display_manager.py | 34 ++- src/lce_qt_launcher/managers/downloader.py | 42 +-- .../managers/import_managers.py | 7 +- .../managers/instance_manager.py | 241 +++++++++------ src/lce_qt_launcher/managers/mod_manager.py | 116 ++++--- src/lce_qt_launcher/managers/steam_manager.py | 109 ++++--- .../managers/system_manager.py | 57 ++-- src/lce_qt_launcher/models/app_data.py | 53 ++-- src/lce_qt_launcher/models/preferences.py | 116 ++++--- src/lce_qt_launcher/models/theme.py | 50 +-- src/lce_qt_launcher/utils/__init__.py | 4 +- src/lce_qt_launcher/utils/holiday.py | 83 +++-- src/lce_qt_launcher/utils/json_trans.py | 16 +- src/lce_qt_launcher/views/browser_dialog.py | 10 +- src/lce_qt_launcher/views/cli.py | 19 +- src/lce_qt_launcher/views/cmd_arg.py | 32 +- .../views/content_installer_dialog.py | 12 +- src/lce_qt_launcher/views/launcher.py | 287 +++++++++++------- src/lce_qt_launcher/views/setting_dialog.py | 42 ++- src/lce_qt_launcher/views/term_service.py | 19 +- 30 files changed, 1076 insertions(+), 697 deletions(-) diff --git a/hatch_build.py b/hatch_build.py index e43003d..d554afa 100644 --- a/hatch_build.py +++ b/hatch_build.py @@ -3,6 +3,7 @@ import os from hatchling.builders.hooks.plugin.interface import BuildHookInterface + class CustomBuildHook(BuildHookInterface): # pyright: ignore[reportMissingTypeArgument] def clean(self, versions) -> None: # pyright: ignore[reportMissingParameterType] if os.name == "posix": @@ -16,4 +17,4 @@ class CustomBuildHook(BuildHookInterface): # pyright: ignore[reportMissingTypeA _ = subprocess.run("./scripts/build.sh", check=True) if os.name == "nt": _ = subprocess.run("scripts\\build.cmd", check=True, shell=True) - return super().initialize(version, build_data) \ No newline at end of file + return super().initialize(version, build_data) diff --git a/packages.py b/packages.py index a205f9a..f2546ae 100644 --- a/packages.py +++ b/packages.py @@ -4,4 +4,4 @@ import subprocess if os.name == "posix": _ = subprocess.run("./scripts/packages.sh", check=True) if os.name == "nt": - _ = subprocess.run("scripts\\packages.cmd", check=True, shell=True) \ No newline at end of file + _ = subprocess.run("scripts\\packages.cmd", check=True, shell=True) diff --git a/packages/flatpak/io.github.xgui4.lce_qt_launcher.yml b/packages/flatpak/io.github.xgui4.lce_qt_launcher.yml index 7d1e546..a0b99e9 100644 --- a/packages/flatpak/io.github.xgui4.lce_qt_launcher.yml +++ b/packages/flatpak/io.github.xgui4.lce_qt_launcher.yml @@ -6,12 +6,6 @@ base: io.qt.PySide.BaseApp base-version: '6.8' command: lce-qt-launcher -name: LCE Qt Launcher -summary: A Minecraft Legacy Console Launcher for GNU/Linux -description: | - This is a custom Minecraft LCE Launcher written in - Python and Qt with Freedom and with GNU/Linux support in mind. - finish-args: - --device=dri - --share=network @@ -24,7 +18,6 @@ cleanup-commands: - /app/cleanup-BaseApp.sh modules: - - name: python3-backports-zstd buildsystem: simple build-commands: diff --git a/run.py b/run.py index e83de08..b0630c5 100644 --- a/run.py +++ b/run.py @@ -4,4 +4,4 @@ import subprocess if os.name == "posix": _ = subprocess.run("./scripts/run.sh", check=True) if os.name == "nt": - _ = subprocess.run("scripts\\run.cmd", check=True, shell=True) \ No newline at end of file + _ = subprocess.run("scripts\\run.cmd", check=True, shell=True) diff --git a/src/lce_qt_launcher/__init__.py b/src/lce_qt_launcher/__init__.py index 15dca34..250da7c 100644 --- a/src/lce_qt_launcher/__init__.py +++ b/src/lce_qt_launcher/__init__.py @@ -1,7 +1,7 @@ from enum import StrEnum FALLBACK_APP_NAME = "LCE Qt Launcher" -FALLBACK_VERSION_NUMBER = "0.0.20b0" +FALLBACK_VERSION_NUMBER = "0.0.20b0" FALLBACK_LICENSE = "GPLv3" FALLBACK_LICENSE_LINK = "https://www.gnu.org/licenses/gpl-3.0" FALLBACK_GIT_REPO_URL = "https://github.com/xgui4/LCE-QT-Launcher" @@ -10,12 +10,15 @@ VERSION_TYPE = "alpha" INSTANCE_EXTENSION = ".lce_inst" AUTHORS = "Xgui4" -class Languages(StrEnum): - """ _summary_ : "Language Codes for JsonTrans """ + +class Languages(StrEnum): + """_summary_ : "Language Codes for JsonTrans""" + FALLBACK = "translations.json" ENGLISH = "en" FRENCH = "fr" + license_str = r""" # GNU GENERAL PUBLIC LICENSE @@ -692,4 +695,4 @@ library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . -""" \ No newline at end of file +""" diff --git a/src/lce_qt_launcher/app.py b/src/lce_qt_launcher/app.py index 9891e2c..9a717fe 100644 --- a/src/lce_qt_launcher/app.py +++ b/src/lce_qt_launcher/app.py @@ -9,13 +9,14 @@ from lce_qt_launcher.views.launcher import LauncherView from lce_qt_launcher.models.theme import StrTheme import lce_qt_launcher.views.term_service as term_service + class App(QApplication): """QApplication Main Instance""" - def __init__(self, - theme : StrTheme, - appContext : AppContext, - argv : list[str] ) -> None: - super().__init__(argv) + + def __init__( + self, theme: StrTheme, appContext: AppContext, argv: list[str] + ) -> None: + super().__init__(argv) self.appContext: AppContext = appContext self.appData: AppData = AppData() @@ -25,23 +26,30 @@ class App(QApplication): self.widget.show() self.set_theme(theme) - - def set_theme(self, theme : StrTheme) -> None: + + def set_theme(self, theme: StrTheme) -> None: """#Set Application Theme using a pretermined theme #TODO To Upgrade! """ try: - theme_file : str = theme + theme_file: str = theme file = QFile(theme_file) if file.open(QIODevice.OpenModeFlag.ReadOnly | QIODevice.OpenModeFlag.Text): content: QByteArray = file.readAll() - stylesheet: str = str(content, encoding='utf-8') # pyright: ignore[reportArgumentType] + stylesheet: str = str(content, encoding="utf-8") # pyright: ignore[reportArgumentType] self.setStyleSheet(stylesheet) except FileNotFoundError: print(FileNotFoundError.with_traceback) - term_service.print_warning(f"Theme ({theme}) not found in ressource, searching in the local storage.") - try: - with open(os.path.join(self.appData.assetsDirs, "styles", "minecraft.qss"), "r") as file: + term_service.print_warning( + f"Theme ({theme}) not found in ressource, searching in the local storage." + ) + try: + with open( + os.path.join(self.appData.assetsDirs, "styles", "minecraft.qss"), + "r", + ) as file: self.setStyleSheet(file.read()) except FileNotFoundError: - _ = QMessageBox.warning(None,"Error", f"{theme} file not found. Reverting to default theme") \ No newline at end of file + _ = QMessageBox.warning( + None, "Error", f"{theme} file not found. Reverting to default theme" + ) diff --git a/src/lce_qt_launcher/app_context.py b/src/lce_qt_launcher/app_context.py index 04b03e5..4281839 100644 --- a/src/lce_qt_launcher/app_context.py +++ b/src/lce_qt_launcher/app_context.py @@ -1,4 +1,4 @@ -from __future__ import annotations +from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: @@ -12,35 +12,40 @@ from lce_qt_launcher.managers.instance_manager import InstanceManager, Instance from lce_qt_launcher.models.theme import StrTheme from lce_qt_launcher.utils.json_trans import JsonTrans -_default_instance : Instance = Instance() -_default_theme : StrTheme = StrTheme.MINECRAFT -_default_language : str = "en" +_default_instance: Instance = Instance() +_default_theme: StrTheme = StrTheme.MINECRAFT +_default_language: str = "en" -class AppContext(): - """_summary_ The App Main Context - """ - def __init__(self, - appData: AppData, - theme : StrTheme = _default_theme, - instance : Instance = _default_instance, - lang : str = _default_language) -> None: + +class AppContext: + """_summary_ The App Main Context""" + + def __init__( + self, + appData: AppData, + theme: StrTheme = _default_theme, + instance: Instance = _default_instance, + lang: str = _default_language, + ) -> None: self.buildInfo: BuildInfo = BuildInfo() self.sys_man: SystemManager = SystemManager() self.userPref: UserPref = UserPref(self.buildInfo) - self.instanceMan: InstanceManager = InstanceManager(instance, self.buildInfo, self) + self.instanceMan: InstanceManager = InstanceManager( + instance, self.buildInfo, self + ) self.theme: StrTheme = theme self.translator: JsonTrans = JsonTrans(appData, lang) - self.accesibleModeEnabled : bool = self.userPref.default_accesibility_mode - self.devModeEnabled : bool = self.userPref.default_developper_mode - self.showHolidayEnabled : bool = self.userPref.default_show_holiday - self.currentLang : str = Languages.FALLBACK.value - - self.BACKGROUND_PIXMAP_IMG : str = ":/assets/background.png" - self.ICON : str = ":/assets/launcher_small.png" - self.MINECRAFT_WEBSITE : str = "https://minecraft.net" - self.MINECRAFT_LCE_WEBSITE : str = "https://minecraftlegacy.com/" + self.accesibleModeEnabled: bool = self.userPref.default_accesibility_mode + self.devModeEnabled: bool = self.userPref.default_developper_mode + self.showHolidayEnabled: bool = self.userPref.default_show_holiday + self.currentLang: str = Languages.FALLBACK.value - def updateTheme(self, theme : StrTheme) -> None: + self.BACKGROUND_PIXMAP_IMG: str = ":/assets/background.png" + self.ICON: str = ":/assets/launcher_small.png" + self.MINECRAFT_WEBSITE: str = "https://minecraft.net" + self.MINECRAFT_LCE_WEBSITE: str = "https://minecraftlegacy.com/" + + def updateTheme(self, theme: StrTheme) -> None: """_summary_ Update the theme Args: @@ -49,7 +54,7 @@ class AppContext(): self.theme = theme self.userPref.set_theme_pref(theme.value) - def updateInstance(self, instance : Instance) -> None: + def updateInstance(self, instance: Instance) -> None: """_summary_ #TODO : TBW Args: @@ -57,44 +62,44 @@ class AppContext(): """ self.instanceMan.instance = instance - def updateLanguage(self, lang : str) -> None: - """_summary_ update the language + def updateLanguage(self, lang: str) -> None: + """_summary_ update the language Args: lang (str): _description_ """ self.currentLang = lang self.translator.load_lang(lang) - - def updateShowHolidayStatus(self, request : str) -> None: + + def updateShowHolidayStatus(self, request: str) -> None: """_summary_ Update the show holiday status via boolean string "request" Args: - request (str): _description_ the boolean string request to update the show holiday option. + request (str): _description_ the boolean string request to update the show holiday option. """ if request == "true": self.showHolidayEnabled = True else: self.showHolidayEnabled = False - - def updateSetDevMoodeStatus(self, request : str) -> None: + + def updateSetDevMoodeStatus(self, request: str) -> None: """_summary_ Update the dev mode status via boolean string "request" Args: - request (str): _description_ the boolean string request to update the developper mode option. + request (str): _description_ the boolean string request to update the developper mode option. """ if request == "true": self.devModeEnabled = True else: self.devModeEnabled = False - - def updateSetAccesbilityMoodeStatus(self, request : str) -> None: + + def updateSetAccesbilityMoodeStatus(self, request: str) -> None: """_summary_ Update the dev mode status via boolean string "request" Args: - request (str): _description_ the boolean string request to update the developper mode option. + request (str): _description_ the boolean string request to update the developper mode option. """ if request == "true": self.accesibleModeEnabled = True else: - self.accesibleModeEnabled = False \ No newline at end of file + self.accesibleModeEnabled = False diff --git a/src/lce_qt_launcher/build_info.py b/src/lce_qt_launcher/build_info.py index 220457e..024444f 100644 --- a/src/lce_qt_launcher/build_info.py +++ b/src/lce_qt_launcher/build_info.py @@ -15,14 +15,16 @@ from lce_qt_launcher import ( ) import lce_qt_launcher.views.term_service as term_service + class BuildInfo: """Application Information and Metadata Information""" + def __init__(self) -> None: - self.version : str = FALLBACK_VERSION_NUMBER + self.version: str = FALLBACK_VERSION_NUMBER self.app_name: str = FALLBACK_APP_NAME - self.git_repo_url: str = FALLBACK_GIT_REPO_URL - self.license_link: str = FALLBACK_LICENSE_LINK - self.license : str = FALLBACK_LICENSE + self.git_repo_url: str = FALLBACK_GIT_REPO_URL + self.license_link: str = FALLBACK_LICENSE_LINK + self.license: str = FALLBACK_LICENSE try: app_metadata: PackageMetadata = metadata("LCE-Qt-Launcher") @@ -42,7 +44,7 @@ class BuildInfo: self.license_link = license_url_metadata if license_metadata: self.license = license_metadata - + except PackageNotFoundError as e: term_service.print_error(f"Package not found! More info : {e.msg}") except RuntimeError as e: @@ -50,7 +52,7 @@ class BuildInfo: except KeyError as e: term_service.print_error(f"Metadata not found! More info : {e}") - self.qt_version : str = qVersion() - self.authors : str = AUTHORS - self.version_type : str = VERSION_TYPE - self.instance_extension : str = INSTANCE_EXTENSION \ No newline at end of file + self.qt_version: str = qVersion() + self.authors: str = AUTHORS + self.version_type: str = VERSION_TYPE + self.instance_extension: str = INSTANCE_EXTENSION diff --git a/src/lce_qt_launcher/features.py b/src/lce_qt_launcher/features.py index 3663fca..31458cc 100644 --- a/src/lce_qt_launcher/features.py +++ b/src/lce_qt_launcher/features.py @@ -27,91 +27,128 @@ import lce_qt_launcher.views.term_service as term_service import os -def install_game(parent : QWidget, instance : Instance, instanceManager : InstanceManager) -> None: + +def install_game( + parent: QWidget, instance: Instance, instanceManager: InstanceManager +) -> None: """Features : Install the game instance selected #TODO : Separe the GUI with the logic of the model # ARGS: - parent : The QWidget parent - instance : The selected Instance - instanceManager : The instance manager to use""" - button_reply = QMessageBox.question(parent, 'Confirm Installation', - "Do you really want to re-install the game? " + - "This version does not support update a installation yet," + - " so a backup is recommended.", - QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) + button_reply = QMessageBox.question( + parent, + "Confirm Installation", + "Do you really want to re-install the game? " + + "This version does not support update a installation yet," + + " so a backup is recommended.", + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, + ) if button_reply == QMessageBox.StandardButton.Yes: term_service.print_information("Starting Installation") - progressLabel : QLabel = parent.ui.progressLabel - progressBar : QProgressBar = parent.ui.progressBar + progressLabel: QLabel = parent.ui.progressLabel + progressBar: QProgressBar = parent.ui.progressBar try: reply: QNetworkReply = instanceManager.install_instance() _ = progressLabel.setVisible(True) - _ = progressBar.setVisible(True) - _ = progressBar.setEnabled(True) + _ = progressBar.setVisible(True) + _ = progressBar.setEnabled(True) _ = progressLabel.setText(f"Downloading {instance.name} Progress") - #TODO - Verify this methodd + # TODO - Verify this methodd def update_progress_bar(bytes_received, bytes_total) -> None: # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] if bytes_total > 0: _ = progressBar.setMaximum(bytes_total) # pyright: ignore[reportUnknownArgumentType] _ = progressBar.setValue(bytes_received) # pyright: ignore[reportUnknownArgumentType] else: - _ = progressBar.setRange(0, 0) + _ = progressBar.setRange(0, 0) + _ = reply.downloadProgress.connect(update_progress_bar) # pyright: ignore[reportUnknownArgumentType] except RuntimeError as e: - _ = progressLabel.setVisible(True) - _ = progressBar.setVisible(True) - _ = progressBar.setEnabled(True) - _ = progressLabel.setText(f"Downloading {instance.name} Cancelled due to a error.") - _ = QMessageBox.critical(parent, "Minecraft LCE Qt Launcher", f"There were a error during the installation \n traceback : {e.args}", QMessageBox.StandardButton.Ok) + _ = progressLabel.setVisible(True) + _ = progressBar.setVisible(True) + _ = progressBar.setEnabled(True) + _ = progressLabel.setText( + f"Downloading {instance.name} Cancelled due to a error." + ) + _ = QMessageBox.critical( + parent, + "Minecraft LCE Qt Launcher", + f"There were a error during the installation \n traceback : {e.args}", + QMessageBox.StandardButton.Ok, + ) else: - _ = QMessageBox.information(parent, "Minecraft LCE Qt Launcher", "Installation Cancelled", QMessageBox.StandardButton.Ok) + _ = QMessageBox.information( + parent, + "Minecraft LCE Qt Launcher", + "Installation Cancelled", + QMessageBox.StandardButton.Ok, + ) -def launch_game(instanceManager : InstanceManager, starting_game_msg_str : str) -> None: + +def launch_game(instanceManager: InstanceManager, starting_game_msg_str: str) -> None: """Features : Launch the game instance selected""" term_service.print_information(starting_game_msg_str) print(instanceManager.play()) -def show_setting(parent : QWidget, setting_ui : Ui_settingDialog, appContext : AppContext) -> None: + +def show_setting( + parent: QWidget, setting_ui: Ui_settingDialog, appContext: AppContext +) -> None: """Features : Open the Setting Pages""" _ = SettingDialog(parent, setting_ui, appContext) -def show_system_info(parent : QWidget) -> None: + +def show_system_info(parent: QWidget) -> None: """Features : Open the System Info Pages""" - parent.sysinfo_dialog.show() + parent.sysinfo_dialog.show() -def show_instance_editor(parent : QWidget) -> None: + +def show_instance_editor(parent: QWidget) -> None: """Features : Open the Instance Editor""" - parent.instance_window.show() + parent.instance_window.show() -def load_instance_from_file(parent : QWidget, - instanceManager : InstanceManager, - appContext: AppContext, - buildInfo : BuildInfo, - appData : AppData) -> None: + +def load_instance_from_file( + parent: QWidget, + instanceManager: InstanceManager, + appContext: AppContext, + buildInfo: BuildInfo, + appData: AppData, +) -> None: """Features : Load the Selected Instance""" file_name: tuple[str, str] = QFileDialog.getOpenFileName( - parent, "Load Instance File", - appContext.sys_man.found_default_save_path(), - f"{buildInfo.app_name} Instance (*{buildInfo.instance_extension})") + parent, + "Load Instance File", + appContext.sys_man.found_default_save_path(), + f"{buildInfo.app_name} Instance (*{buildInfo.instance_extension})", + ) instanceManager.load_instance(file_name[0]) try: import_managers.import_inst_file_to_app_data(file_name[0], appData) except FileExistsError: - term_service.print_information("Instance already in data folder. Skipping making symlink. ") + term_service.print_information( + "Instance already in data folder. Skipping making symlink. " + ) -def load_instance_from_instance(instanceManager : InstanceManager, instance : Instance) -> None: + +def load_instance_from_instance( + instanceManager: InstanceManager, instance: Instance +) -> None: """Features : Load the Selected Instance""" instanceManager.instance = instance -def show_about_qt(parent : QWidget) -> None: + +def show_about_qt(parent: QWidget) -> None: """Features : Load the Selected Instance""" print("Show About Qt popup.") QMessageBox.aboutQt(parent, "About Qt") -def show_about_app(parent : QWidget) -> None: + +def show_about_app(parent: QWidget) -> None: """_summary_ Features : Show About This App Dialog Args: @@ -119,7 +156,8 @@ def show_about_app(parent : QWidget) -> None: """ parent.aboutDialog.show() -def open_url_at(sysMan : SystemManager, url : str): + +def open_url_at(sysMan: SystemManager, url: str): """_summary_ Open Url with system Args: @@ -128,7 +166,8 @@ def open_url_at(sysMan : SystemManager, url : str): """ sysMan.open_url_with_system(url) -def new_instance_from_form(mainWindow : QMainWindow) -> Instance: + +def new_instance_from_form(mainWindow: QMainWindow) -> Instance: """_summary_ : Create With Instance From Form #TODO : Make this feature less dependant on the GUI @@ -138,13 +177,15 @@ def new_instance_from_form(mainWindow : QMainWindow) -> Instance: Returns: Instance: _description_ : the returned Instance created with the Form """ - form:QMainWindow = mainWindow.ui - username_str :str = form.usernameInputBox.text() - path_str : str = form.pathInputBox.text() - server_ip_str: str = form.serverIPInputBox.text() - server_name_str : str = form.serverNameInputBox.text() + form: QMainWindow = mainWindow.ui + username_str: str = form.usernameInputBox.text() + path_str: str = form.pathInputBox.text() + server_ip_str: str = form.serverIPInputBox.text() + server_name_str: str = form.serverNameInputBox.text() repo_url_str: str = form.repoURLInputBox.text() - instance_name: str = QInputDialog.getText(mainWindow, "Name your instance", "Set the name of the instance")[0] + instance_name: str = QInputDialog.getText( + mainWindow, "Name your instance", "Set the name of the instance" + )[0] newInstance = Instance() if instance_name: @@ -158,9 +199,10 @@ def new_instance_from_form(mainWindow : QMainWindow) -> Instance: if repo_url_str: newInstance.repo_url = repo_url_str - return newInstance; + return newInstance -def show_webbrowser(parent : QWidget, url : str, buildInfo : BuildInfo): + +def show_webbrowser(parent: QWidget, url: str, buildInfo: BuildInfo): """_summary_ Create and show a Webbrowser view Args: @@ -170,23 +212,31 @@ def show_webbrowser(parent : QWidget, url : str, buildInfo : BuildInfo): """ _ = BrowserDialog(parent, url, buildInfo) -def save_instance_to_file(parent : QWidget, instanceManager : InstanceManager, appContext: AppContext, buildInfo : BuildInfo) -> None: + +def save_instance_to_file( + parent: QWidget, + instanceManager: InstanceManager, + appContext: AppContext, + buildInfo: BuildInfo, +) -> None: """_summary_ Save the instance to a file Args: parent (QWidget): _description_ : the parent of the save dialog instanceManager (InstanceManager): _description_ Instance Manager to use to save the instance - appContext (AppContext): _description_ #TODO : To be determined + appContext (AppContext): _description_ #TODO : To be determined buildInfo (BuildInfo): _description_ The Build info of the app info """ file_name: str = QFileDialog.getSaveFileName( - parent, - "Save Instance option to a file", - appContext.sys_man.found_default_save_path(), - f"{buildInfo.app_name} Instance File (*{buildInfo.instance_extension})")[0] + parent, + "Save Instance option to a file", + appContext.sys_man.found_default_save_path(), + f"{buildInfo.app_name} Instance File (*{buildInfo.instance_extension})", + )[0] instanceManager.save_instance(file_name) -def launch_cli_interface(instance_man : InstanceManager) -> None: + +def launch_cli_interface(instance_man: InstanceManager) -> None: """_summary_ Launch the cli version of the app Args: @@ -195,7 +245,8 @@ def launch_cli_interface(instance_man : InstanceManager) -> None: """ cli.launch_cli(instance_man) -def generate_user_config(userPref : UserPref) -> None: + +def generate_user_config(userPref: UserPref) -> None: """_summary_ Generate the default config Args: @@ -203,24 +254,29 @@ def generate_user_config(userPref : UserPref) -> None: """ userPref.generate_default_config() -def display_license(buildInfo : BuildInfo) -> None: + +def display_license(buildInfo: BuildInfo) -> None: """_summary_ Display the license of the app on the console Args: - buildInfo (BuildInfo): _description_ : The Build info for the App Info + buildInfo (BuildInfo): _description_ : The Build info for the App Info """ - term_service.print_information(f"{buildInfo.app_name} is licensed via the {buildInfo.license} License.") + term_service.print_information( + f"{buildInfo.app_name} is licensed via the {buildInfo.license} License." + ) term_service.print_information(f"See {buildInfo.license_link} for more info") -def display_help(help_str : str) -> None: + +def display_help(help_str: str) -> None: """_summary_ Display the help string of the app for the cli on the console Args: - help_str (str): _description_ help string to show on the console + help_str (str): _description_ help string to show on the console """ term_service.print_pretty(help_str) -def display_about(about_str : str) -> None: + +def display_about(about_str: str) -> None: """_summary_ Display the about string of the app on the console Args: @@ -228,8 +284,9 @@ def display_about(about_str : str) -> None: """ term_service.print_pretty(about_str) -def display_version(buildInfo : BuildInfo) -> None: - """_summary_ Display the string version on the console + +def display_version(buildInfo: BuildInfo) -> None: + """_summary_ Display the string version on the console Args: buildInfo (BuildInfo): _description_ Display the help string of the app for the cli on the console diff --git a/src/lce_qt_launcher/main.py b/src/lce_qt_launcher/main.py index dad182a..2926b68 100755 --- a/src/lce_qt_launcher/main.py +++ b/src/lce_qt_launcher/main.py @@ -13,38 +13,38 @@ # nuitka-project: --copyright="Copyleft Xgui4 2026 (GPLv3)" """ - LCE Qt Launcher Manager - Copyright (C) 2026 Xgui4 +LCE Qt Launcher Manager +Copyright (C) 2026 Xgui4 - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see https://www.gnu.org/licenses/. +You should have received a copy of the GNU General Public License +along with this program. If not, see https://www.gnu.org/licenses/. """ from lce_qt_launcher.models.preferences import UserPref -from PySide6.QtWidgets import ( - QMessageBox, - QFileDialog -) +from PySide6.QtWidgets import QMessageBox, QFileDialog -from PySide6.QtGui import ( - QFontDatabase -) +from PySide6.QtGui import QFontDatabase from lce_qt_launcher.models.app_data import AppData from lce_qt_launcher.views import term_service -from lce_qt_launcher.views.cmd_arg import CmdArgAction, parse_args, argsDetected, launch_cmd_action +from lce_qt_launcher.views.cmd_arg import ( + CmdArgAction, + parse_args, + argsDetected, + launch_cmd_action, +) from lce_qt_launcher.app_context import AppContext from lce_qt_launcher.app import App from lce_qt_launcher.managers.system_manager import SystemManager @@ -54,23 +54,23 @@ import lce_qt_launcher.models.theme as theme import sys import os -def main() -> None: - """_summary_ Main Function - """ - appData : AppData = AppData() +def main() -> None: + """_summary_ Main Function""" + + appData: AppData = AppData() appContext: AppContext = AppContext(appData) sys_man: SystemManager = appContext.sys_man try: sys_man.adapt_qt_system_theme() userPref: UserPref = appContext.userPref - #user_language: str = userPref.get_language_pref() + # user_language: str = userPref.get_language_pref() user_theme: str = userPref.get_theme_pref() show_holiday: str = userPref.get_show_holiday() developer_mode: str = userPref.get_developper_mode() accessible_mode: str = userPref.get_accesible_mode() - try: + try: selected_theme: StrTheme = theme.from_str_to_strTheme(user_theme) appContext.updateTheme(selected_theme) appContext.updateShowHolidayStatus(show_holiday) @@ -80,21 +80,35 @@ def main() -> None: term_service.print_error(str(err)) # appContext.updateLanguage(user_language) except: - term_service.print_error("They were a error while loading the system theme or user preference.") - + term_service.print_error( + "They were a error while loading the system theme or user preference." + ) + def about_to_quit_event() -> None: - instance_manager_label: str = appContext.translator.translate("instance_manager_label") - save_instance_msg_box_label: str = appContext.translator.translate("save_instance_msg_box_label") - save_filedialog_title: str = appContext.translator.translate("save_filedialog_title") - question_options = QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No - anwser = QMessageBox.question(None, instance_manager_label, save_instance_msg_box_label, question_options) + instance_manager_label: str = appContext.translator.translate( + "instance_manager_label" + ) + save_instance_msg_box_label: str = appContext.translator.translate( + "save_instance_msg_box_label" + ) + save_filedialog_title: str = appContext.translator.translate( + "save_filedialog_title" + ) + question_options = ( + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No + ) + anwser = QMessageBox.question( + None, instance_manager_label, save_instance_msg_box_label, question_options + ) if anwser == QMessageBox.StandardButton.Yes: file_name: str = QFileDialog.getSaveFileName( - None, save_filedialog_title, - f"{appContext.sys_man.found_default_save_path()}(\"LCE Instance Save File\" (*{appContext.buildInfo.instance_extension}))")[0] + None, + save_filedialog_title, + f'{appContext.sys_man.found_default_save_path()}("LCE Instance Save File" (*{appContext.buildInfo.instance_extension}))', + )[0] appContext.instanceMan.save_instance(file_name) - action : CmdArgAction = parse_args(sys.argv) + action: CmdArgAction = parse_args(sys.argv) if argsDetected(action): launch_cmd_action(action, appContext) else: @@ -114,5 +128,6 @@ def main() -> None: sys.exit(app.exec()) + if __name__ == "__main__": main() diff --git a/src/lce_qt_launcher/managers/display_manager.py b/src/lce_qt_launcher/managers/display_manager.py index 533361a..d244812 100644 --- a/src/lce_qt_launcher/managers/display_manager.py +++ b/src/lce_qt_launcher/managers/display_manager.py @@ -1,4 +1,4 @@ -#TODO : doctstring and more functions +# TODO : doctstring and more functions from enum import Enum @@ -6,31 +6,39 @@ import lce_qt_launcher.views.term_service as term_service from PySide6.QtWidgets import QMessageBox, QWidget + class DisplayType(Enum): CONSOLE = 0 QMESSAGE_BOX = 1 MIXED = 2 -class DisplayManager(): - def __init__(self, type : DisplayType, parentWindow : QWidget | None = None) -> None: + +class DisplayManager: + def __init__(self, type: DisplayType, parentWindow: QWidget | None = None) -> None: self.type: DisplayType = type if parentWindow != None: - self.parentWindow : QWidget = parentWindow - - def displayInfo(self, msg : str, title : str | None = None)-> None: + self.parentWindow: QWidget = parentWindow + + def displayInfo(self, msg: str, title: str | None = None) -> None: if self.type == DisplayType.CONSOLE or DisplayType.MIXED: term_service.print_information(msg) if self.type == DisplayType.QMESSAGE_BOX or DisplayType.MIXED: - QMessageBox.information(self.parentWindow, title if not None else "Information", msg) # pyright: ignore[reportArgumentType, reportUnusedCallResult] - - def displayWarn(self, msg : str, title : str | None = None)-> None: + QMessageBox.information( + self.parentWindow, title if not None else "Information", msg + ) # pyright: ignore[reportArgumentType, reportUnusedCallResult] + + def displayWarn(self, msg: str, title: str | None = None) -> None: if self.type == DisplayType.CONSOLE or DisplayType.MIXED: term_service.print_warning(msg) if self.type == DisplayType.QMESSAGE_BOX or DisplayType.MIXED: - QMessageBox.warning(self.parentWindow, title if not None else "⚠️ Warning!", msg) # pyright: ignore[reportArgumentType, reportUnusedCallResult] - - def displayError(self, msg : str, title : str | None = None)-> None: + QMessageBox.warning( + self.parentWindow, title if not None else "⚠️ Warning!", msg + ) # pyright: ignore[reportArgumentType, reportUnusedCallResult] + + def displayError(self, msg: str, title: str | None = None) -> None: if self.type == DisplayType.CONSOLE or DisplayType.MIXED: term_service.print_error(msg) if self.type == DisplayType.QMESSAGE_BOX or DisplayType.MIXED: - QMessageBox.critical(self.parentWindow, title if not None else "❗ Error", msg) # pyright: ignore[reportArgumentType, reportUnusedCallResult] \ No newline at end of file + QMessageBox.critical( + self.parentWindow, title if not None else "❗ Error", msg + ) # pyright: ignore[reportArgumentType, reportUnusedCallResult] diff --git a/src/lce_qt_launcher/managers/downloader.py b/src/lce_qt_launcher/managers/downloader.py index b2d6365..42ed2af 100644 --- a/src/lce_qt_launcher/managers/downloader.py +++ b/src/lce_qt_launcher/managers/downloader.py @@ -5,19 +5,13 @@ if TYPE_CHECKING: from lce_qt_launcher.managers.instance_manager import Instance from lce_qt_launcher.app_context import AppContext -import lce_qt_launcher.views.term_service as term_service +import lce_qt_launcher.views.term_service as term_service from lce_qt_launcher.managers.system_manager import SystemManager -from zipfile import ( - ZipFile, BadZipFile -) +from zipfile import ZipFile, BadZipFile -from PySide6.QtNetwork import ( - QNetworkAccessManager, - QNetworkRequest, - QNetworkReply -) +from PySide6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply from PySide6.QtCore import ( QUrl, @@ -32,19 +26,21 @@ START_DOWNLOAD_REQUEST_MSG_STR = "Starting Download Request" SUCCESS_STATUS_CODE = 200 + class Downloader(QObject): """_summary_ Downloader Manager to download stuff from the internet Args: QObject (_type_): _description_ Inherit from the QObject """ - def __init__(self, appContext : AppContext) -> None: + + def __init__(self, appContext: AppContext) -> None: super().__init__() self.manager: QNetworkAccessManager = QNetworkAccessManager() - self.appContext : AppContext = appContext + self.appContext: AppContext = appContext def download_inst_async(self, instance: Instance) -> QNetworkReply: - """ _summary_ Download and install the selected Instance + """_summary_ Download and install the selected Instance Args: instance : The selected instance to install or Update @@ -63,12 +59,16 @@ class Downloader(QObject): try: with ZipFile(BytesIO(data)) as archive: _ = self.extract_inst_async(archive, instance) - term_service.print_success(f"Installation of {instance.name} was a success") + term_service.print_success( + f"Installation of {instance.name} was a success" + ) if os.name == "posix": - exe_path = os.path.join(instance.installation_path, instance.exe_name) + exe_path = os.path.join( + instance.installation_path, instance.exe_name + ) _ = self.appContext.sys_man.set_file_permission(exe_path) - except BadZipFile as e: - error_msg : str = f"Extraction Error : {e}" + except BadZipFile as e: + error_msg: str = f"Extraction Error : {e}" term_service.print_error(error_msg) raise RuntimeError(error_msg) except Exception as e: @@ -77,20 +77,22 @@ class Downloader(QObject): raise RuntimeError(error_msg) else: if os.name == "posix": - exe_abs_path: str = os.path.join(instance.installation_path, instance.exe_name) + exe_abs_path: str = os.path.join( + instance.installation_path, instance.exe_name + ) system: SystemManager = self.appContext.sys_man _ = system.set_file_permission(exe_abs_path) _ = reply.finished.connect(_when_finished) return reply - - def extract_inst_async(self, data : ZipFile, instance : Instance) -> None: + + def extract_inst_async(self, data: ZipFile, instance: Instance) -> None: """ _summary_ : extract the zipfile of the downloaded instance Args: data : the zip file itself - instance : the specified instance + instance : the specified instance #TODO Make Async """ data.extractall(instance.installation_path) diff --git a/src/lce_qt_launcher/managers/import_managers.py b/src/lce_qt_launcher/managers/import_managers.py index 6ed6550..ee49dd6 100644 --- a/src/lce_qt_launcher/managers/import_managers.py +++ b/src/lce_qt_launcher/managers/import_managers.py @@ -4,9 +4,12 @@ from pathlib import Path import os -def import_inst_file_to_app_data(instance_file_path : str, appData : AppData, filename : str = ""): + +def import_inst_file_to_app_data( + instance_file_path: str, appData: AppData, filename: str = "" +): if filename == "": filename_Path = Path(f"{instance_file_path}") filename = filename_Path.name destinations = os.path.join(appData.appDataDirs[0], "instances", filename) - os.symlink(instance_file_path, destinations) \ No newline at end of file + os.symlink(instance_file_path, destinations) diff --git a/src/lce_qt_launcher/managers/instance_manager.py b/src/lce_qt_launcher/managers/instance_manager.py index 50b7097..bd4cfe8 100644 --- a/src/lce_qt_launcher/managers/instance_manager.py +++ b/src/lce_qt_launcher/managers/instance_manager.py @@ -1,5 +1,5 @@ -#TODO : Make Instance mode indpendant -from __future__ import annotations +# TODO : Make Instance mode indpendant +from __future__ import annotations from typing import TYPE_CHECKING from PySide6.QtWidgets import QMessageBox @@ -11,9 +11,7 @@ from lce_qt_launcher.build_info import BuildInfo import lce_qt_launcher.views.term_service as term_service -from PySide6.QtNetwork import ( - QNetworkReply -) +from PySide6.QtNetwork import QNetworkReply from PySide6.QtCore import QObject @@ -26,16 +24,18 @@ import os SCHEME_VERSION = "https://raw.githubusercontent.com/xgui4/LCE-Qt-Launcher/refs/heads/beta/schemas/x-application-lce_inst.json" + class InstanceSource(Enum): - """_summary_ The 4 Type of Instances (2 functional, the othes coming soon) - """ + """_summary_ The 4 Type of Instances (2 functional, the othes coming soon)""" + GITHUB_RELEASE = 0 FORGEJO_RELEASE = 1 REMOTE_GIT_SOURCE = 2 LOCAL_INSTALLATION = 3 LOCAL_SOURCE_CODE = 4 -def from_int_to_InstanceSource(value : int)-> InstanceSource: + +def from_int_to_InstanceSource(value: int) -> InstanceSource: """_summary_ Convert Into to Instance Source Args: @@ -53,14 +53,16 @@ def from_int_to_InstanceSource(value : int)-> InstanceSource: case 1: return InstanceSource.FORGEJO_RELEASE case 2: - return InstanceSource.REMOTE_GIT_SOURCE + return InstanceSource.REMOTE_GIT_SOURCE case 3: return InstanceSource.LOCAL_INSTALLATION case 4: return InstanceSource.LOCAL_SOURCE_CODE - case _: raise RuntimeError(f"{value} is an Incorrect InstanceSource Type") + case _: + raise RuntimeError(f"{value} is an Incorrect InstanceSource Type") -def from_str_to_InstanceSource(string : str)-> InstanceSource: + +def from_str_to_InstanceSource(string: str) -> InstanceSource: """_summary_ Convert str to Instance Source Args: @@ -78,22 +80,25 @@ def from_str_to_InstanceSource(string : str)-> InstanceSource: case "InstanceSource.FORGEJO_RELEASE": return InstanceSource.FORGEJO_RELEASE case "InstanceSource.REMOTE_GIT_SOURCE": - return InstanceSource.REMOTE_GIT_SOURCE + return InstanceSource.REMOTE_GIT_SOURCE case "InstanceSource.LOCAL_INSTALLATION": return InstanceSource.LOCAL_INSTALLATION case "InstanceSource.LOCAL_SOURCE_CODE": return InstanceSource.LOCAL_SOURCE_CODE - case _: raise RuntimeError(f"{string} is an Incorrect InstanceSource Type") + case _: + raise RuntimeError(f"{string} is an Incorrect InstanceSource Type") + class InstanceType(Enum): - """_summary_ The instance Type (no function yet) - """ + """_summary_ The instance Type (no function yet)""" + CLIENT_VANILLA = 0 CLENT_MODDED = 1 SERVER_VANILLA = 2 SERVER_MODDED = 3 -def from_int_to_InstanceType(value : int)-> InstanceType: + +def from_int_to_InstanceType(value: int) -> InstanceType: """_summary_ Convert Into to Instance Type Args: @@ -114,9 +119,11 @@ def from_int_to_InstanceType(value : int)-> InstanceType: return InstanceType.SERVER_VANILLA case 3: return InstanceType.SERVER_MODDED - case _: raise RuntimeError(f"{value} is an Incorrect InstanceType Type") + case _: + raise RuntimeError(f"{value} is an Incorrect InstanceType Type") -def from_str_to_InstanceType(string : str)-> InstanceType: + +def from_str_to_InstanceType(string: str) -> InstanceType: """_summary_ Convert str to Instance Type Args: @@ -137,7 +144,9 @@ def from_str_to_InstanceType(string : str)-> InstanceType: return InstanceType.SERVER_VANILLA case "InstanceType.SERVER_MODDED": return InstanceType.SERVER_MODDED - case _: raise RuntimeError(f"{string} is an Incorrect Instance Type") + case _: + raise RuntimeError(f"{string} is an Incorrect Instance Type") + _DEFAULT_INST_NAME = "Default (MCLCE - Git Source)" _DEFAULT_INSTALLATION_PATH = ".default" @@ -150,27 +159,31 @@ _DEFAULT_INST_TYPE = InstanceType.CLIENT_VANILLA _DEFAULT_INST_SOURCE_STRING = "InstanceSource.REMOTE_GIT_SOURCE" _DEFAULT_INST_TYPE_STRING = "InstanceType.CLIENT_VANILLA" _DEFAULT_IMAGE = ":/assets/minecraft.png" -_DEFAULT_NEWS_FEED = "https://git.minecraftlegacy.com/backups/MinecraftConsoles/commits/branch/main" +_DEFAULT_NEWS_FEED = ( + "https://git.minecraftlegacy.com/backups/MinecraftConsoles/commits/branch/main" +) _DEFAULT_VERSION = "main" + class Instance(QObject): - """_summary_ An config and inform an instance of Minecraft LCE Installed or to install - """ - def __init__(self, - name : str = _DEFAULT_INST_NAME, - installation_path : str = _DEFAULT_INSTALLATION_PATH, - username : str = _DEFAULT_USERNAME, - exe_name : str = _DEFAULT_EXE_NAME, - archive_file : str = _DEFAULT_ARCHIVE_FILE, - repo_url : str = _DEFAULT_REPO_URL, - image : str = _DEFAULT_IMAGE, - instance_source : InstanceSource = _DEFAULT_INST_SOURCE, - instance_type : InstanceType = _DEFAULT_INST_TYPE, - news_feed : str = _DEFAULT_NEWS_FEED, - version : str = _DEFAULT_VERSION, - steam_link : str = "N/A" - ) -> None: - super().__init__(parent = None, objectName="Instance") + """_summary_ An config and inform an instance of Minecraft LCE Installed or to install""" + + def __init__( + self, + name: str = _DEFAULT_INST_NAME, + installation_path: str = _DEFAULT_INSTALLATION_PATH, + username: str = _DEFAULT_USERNAME, + exe_name: str = _DEFAULT_EXE_NAME, + archive_file: str = _DEFAULT_ARCHIVE_FILE, + repo_url: str = _DEFAULT_REPO_URL, + image: str = _DEFAULT_IMAGE, + instance_source: InstanceSource = _DEFAULT_INST_SOURCE, + instance_type: InstanceType = _DEFAULT_INST_TYPE, + news_feed: str = _DEFAULT_NEWS_FEED, + version: str = _DEFAULT_VERSION, + steam_link: str = "N/A", + ) -> None: + super().__init__(parent=None, objectName="Instance") self.name: str = name self.installation_path: str = installation_path self.username: str = username @@ -178,26 +191,32 @@ class Instance(QObject): self.exe_name: str = exe_name self.repo_url: str = repo_url self.instance_source: InstanceSource = instance_source - self.instance_type : InstanceType = instance_type - self.image : str = image - self.news_feed : str = news_feed + self.instance_type: InstanceType = instance_type + self.image: str = image + self.news_feed: str = news_feed self.version: str = version - self.steam_link : str = steam_link + self.steam_link: str = steam_link def load_inst_from_dict(self, inst_dict: dict[str, str]) -> None: """_summary_ Load A JSON to a empty Instance Object to import it Args: - inst_dict (dict[str, str]): _description_ + inst_dict (dict[str, str]): _description_ """ self.name = inst_dict.get("name", _DEFAULT_INST_NAME) - self.installation_path = inst_dict.get("installation_path",_DEFAULT_INSTALLATION_PATH) + self.installation_path = inst_dict.get( + "installation_path", _DEFAULT_INSTALLATION_PATH + ) self.username = inst_dict.get("username", _DEFAULT_USERNAME) self.exe_name = inst_dict.get("exe_name", _DEFAULT_EXE_NAME) self.archive_file = inst_dict.get("archive_file", _DEFAULT_ARCHIVE_FILE) self.repo_url = inst_dict.get("repo_url", _DEFAULT_REPO_URL) - self.instance_source = from_str_to_InstanceSource(inst_dict.get("instances_source", _DEFAULT_INST_SOURCE_STRING)) - self.instance_type = from_str_to_InstanceType(inst_dict.get("instance_type", _DEFAULT_INST_TYPE_STRING)) + self.instance_source = from_str_to_InstanceSource( + inst_dict.get("instances_source", _DEFAULT_INST_SOURCE_STRING) + ) + self.instance_type = from_str_to_InstanceType( + inst_dict.get("instance_type", _DEFAULT_INST_TYPE_STRING) + ) self.image = inst_dict.get("image", _DEFAULT_IMAGE) self.news_feed = inst_dict.get("news_feed", _DEFAULT_NEWS_FEED) self.version = inst_dict.get("version", _DEFAULT_VERSION) @@ -214,39 +233,47 @@ class Instance(QObject): str: _description_ """ download_release_url = "/releases/download/" - if self.instance_source == InstanceSource.GITHUB_RELEASE or self.instance_source == InstanceSource.FORGEJO_RELEASE: - return self.repo_url + \ - download_release_url + \ - self.version + "/" + \ - self.archive_file + if ( + self.instance_source == InstanceSource.GITHUB_RELEASE + or self.instance_source == InstanceSource.FORGEJO_RELEASE + ): + return ( + self.repo_url + + download_release_url + + self.version + + "/" + + self.archive_file + ) if self.instance_source == InstanceSource.REMOTE_GIT_SOURCE: return f"{self.repo_url}.git" if self.instance_source == InstanceSource.LOCAL_INSTALLATION: - raise RuntimeError("Error ! Local Installation does not have a download URL") + raise RuntimeError( + "Error ! Local Installation does not have a download URL" + ) else: raise RuntimeError("Not implemented yet!") - + def to_dict(self) -> dict[str, str]: - dict_to_return : dict[str, str ] = { - "$schema" : SCHEME_VERSION, - "name" : self.name, - "installation_path" : self.installation_path, - "username" : self.username, - "exe_name" : self.exe_name, - "archive_file" : self.archive_file, - "repo_url" : self.repo_url, - "instance_source" : self.instance_source.name, - "instance_type" : self.instance_type.name, - "image" : self.image, - "news_feed" : self.news_feed, - "version" : self.version, - "steam_link": self.version + dict_to_return: dict[str, str] = { + "$schema": SCHEME_VERSION, + "name": self.name, + "installation_path": self.installation_path, + "username": self.username, + "exe_name": self.exe_name, + "archive_file": self.archive_file, + "repo_url": self.repo_url, + "instance_source": self.instance_source.name, + "instance_type": self.instance_type.name, + "image": self.image, + "news_feed": self.news_feed, + "version": self.version, + "steam_link": self.version, } return dict_to_return - + def display(self) -> None: - print(f"Name : {self.name}") - print(f"=============================") + print(f"Name : {self.name}") + print(f"=============================") print(f"installation path : {self.installation_path}") print(f"username : {self.username}") print(f"executable name : {self.exe_name}") @@ -260,11 +287,16 @@ class Instance(QObject): print(f"steam link : {self.steam_link}") # print(f"servers : {self.servers}") + class InstanceManager: """_summary_ The Manager for Instances objects""" - def __init__(self, instance : Instance, build_info : BuildInfo, appContext : AppContext): + + def __init__( + self, instance: Instance, build_info: BuildInfo, appContext: AppContext + ): self.instance: Instance = instance from lce_qt_launcher.managers.downloader import Downloader + self._downloader: Downloader = Downloader(appContext) self._build_info: BuildInfo = build_info @@ -274,27 +306,37 @@ class InstanceManager: Returns: str: _description_ error message or status and exit codes """ - return_code :int = 0 + return_code: int = 0 try: - client_path : str = os.path.join(self.instance.installation_path, self.instance.exe_name) - try : - game_process_temp = subprocess.run([client_path, "-name", self.instance.username]) + client_path: str = os.path.join( + self.instance.installation_path, self.instance.exe_name + ) + try: + game_process_temp = subprocess.run( + [client_path, "-name", self.instance.username] + ) return_code = game_process_temp.returncode except subprocess.SubprocessError as e: if os.name == "posix": - game_process_temp = subprocess.run(["wine", client_path, "-name", self.instance.username]) + game_process_temp = subprocess.run( + ["wine", client_path, "-name", self.instance.username] + ) return_code = game_process_temp.returncode else: QMessageBox.critical(None, "Instance Error", str(e.args)) - except TimeoutExpired as err: - term_service.print_error(f"process of lauching instance {self.instance.name} Failed. Reason : Timeout Expired.\n traceback : {err.with_traceback}") + except TimeoutExpired as err: + term_service.print_error( + f"process of lauching instance {self.instance.name} Failed. Reason : Timeout Expired.\n traceback : {err.with_traceback}" + ) return f"process of lauching instance {self.instance.name} Failed. Reason : Timeout Expired.\n traceback : {err.with_traceback}" except PermissionError as err: - term_service.print_error(f"Cannot launch {self.instance.name}. Reason : Permission Denied.\n traceback : {err.with_traceback}") + term_service.print_error( + f"Cannot launch {self.instance.name}. Reason : Permission Denied.\n traceback : {err.with_traceback}" + ) return f"Cannot launch {self.instance.name}. Reason : Permission Denied.\n traceback : {err.with_traceback}" else: return f"Client closed with code {return_code}" - + def install_instance(self) -> QNetworkReply: """_summary_ Install the selected Instance @@ -306,47 +348,58 @@ class InstanceManager: QNetworkReply: _description_ : the QtNetwork Reply Object of the download process """ try: - if self.instance.instance_source in [InstanceSource.GITHUB_RELEASE, InstanceSource.FORGEJO_RELEASE]: + if self.instance.instance_source in [ + InstanceSource.GITHUB_RELEASE, + InstanceSource.FORGEJO_RELEASE, + ]: return self._downloader.download_inst_async(self.instance) else: - raise RuntimeWarning("Not implemented YET") #TODO : implementing other type + raise RuntimeWarning( + "Not implemented YET" + ) # TODO : implementing other type except RuntimeError as e: raise e - def save_instance(self, save_file : str) -> None: + def save_instance(self, save_file: str) -> None: """_summary_ Save the install with a specified save file and location Args: save_file (str): _description_ specified save file and location """ full_save_file = save_file - json_string : str = "" + json_string: str = "" try: - json_string = json.dumps(vars(self.instance), indent=4,) + json_string = json.dumps( + vars(self.instance), + indent=4, + ) except: json_string = json.dumps(obj=vars(self.instance), indent=4, default=str) if not save_file.endswith(self._build_info.instance_extension): full_save_file: str = save_file + self._build_info.instance_extension - with open(file=full_save_file, mode='w') as f: + with open(file=full_save_file, mode="w") as f: _ = f.write(json_string) - - def load_instance(self, save_file : str) -> None: + + def load_instance(self, save_file: str) -> None: """_summary_ Load an instance with a specified save file and location - #TODO : Check for the any report + #TODO : Check for the any report Args: save_file (str): _description_ specified save file and location """ - with open(file=save_file, mode='r') as json_file: + with open(file=save_file, mode="r") as json_file: json_data = json.load(json_file) - inst_dict : dict[str, str] = json_data + inst_dict: dict[str, str] = json_data self.instance.load_inst_from_dict(inst_dict) def is_installable(self) -> bool: - """_summary_ #TODO - """ - #Note : Right now the remote git location is not installable via this launcher, it will added in the next version - if self.instance.instance_source in [InstanceSource.LOCAL_INSTALLATION, InstanceSource.LOCAL_SOURCE_CODE, InstanceSource.REMOTE_GIT_SOURCE]: + """_summary_ #TODO""" + # Note : Right now the remote git location is not installable via this launcher, it will added in the next version + if self.instance.instance_source in [ + InstanceSource.LOCAL_INSTALLATION, + InstanceSource.LOCAL_SOURCE_CODE, + InstanceSource.REMOTE_GIT_SOURCE, + ]: return False return True diff --git a/src/lce_qt_launcher/managers/mod_manager.py b/src/lce_qt_launcher/managers/mod_manager.py index 725fad8..7d8992a 100755 --- a/src/lce_qt_launcher/managers/mod_manager.py +++ b/src/lce_qt_launcher/managers/mod_manager.py @@ -1,21 +1,22 @@ #!/usr/bin/env python """ - LCE Mods Manager - Copyright (C) 2026 Xgui4 +LCE Mods Manager +Copyright (C) 2026 Xgui4 - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . +You should have received a copy of the GNU General Public License +along with this program. If not, see . """ + import sys import os import argparse @@ -26,16 +27,18 @@ from zipfile import ZipFile, BadZipFile DLC_LOCATION: str = os.path.join("Windows64Media", "DLC") WORLD_LOCATION: str = os.path.join("Windows64", "GameHDD") MOD_LOCATION: str = os.path.join("Windows64", "Media") -CUSTOM_SKIN_LOCATION: str = os.path.join("Common","res","mob") +CUSTOM_SKIN_LOCATION: str = os.path.join("Common", "res", "mob") + class ContentType(StrEnum): DLC = DLC_LOCATION WORLD = WORLD_LOCATION MOD = MOD_LOCATION - CUSTOM_SKIN = CUSTOM_SKIN_LOCATION + CUSTOM_SKIN = CUSTOM_SKIN_LOCATION NONE = "0" -def from_str_to_enum(string : str) -> ContentType: + +def from_str_to_enum(string: str) -> ContentType: print(string) match string: case "DLC": @@ -48,9 +51,10 @@ def from_str_to_enum(string : str) -> ContentType: return ContentType.CUSTOM_SKIN case "None": return ContentType.NONE - case _ : + case _: raise RuntimeError("Invalid Argument") + LEGAL_TEXT = """ LCE Mods Managers Copyright (C) 2026 Xgui4 @@ -59,7 +63,8 @@ LEGAL_TEXT = """ under certain conditions; type `show c' for details. """ -def extract_zip(data : ZipFile, extraction_path : str) -> None: + +def extract_zip(data: ZipFile, extraction_path: str) -> None: """ _summary_ : extract the zipfile of the content to the desired path @@ -70,46 +75,64 @@ def extract_zip(data : ZipFile, extraction_path : str) -> None: """ data.extractall(extraction_path) -def install_content(instance_path : str, contentType : ContentType, archive_file : str): + +def install_content(instance_path: str, contentType: ContentType, archive_file: str): """_summary_ #TODO docstring Args: - instance_path (str): _description_ - contentType (ContentType): _description_ - archive_file (str): _description_ + instance_path (str): _description_ + contentType (ContentType): _description_ + archive_file (str): _description_ """ try: zipFile = ZipFile(archive_file) - content_path : str = os.path.join(instance_path, contentType.value) + content_path: str = os.path.join(instance_path, contentType.value) extract_zip(zipFile, content_path) except BadZipFile as e: - print(f"Could not extract content to destination, zipfile was bad. More Info : {e}") + print( + f"Could not extract content to destination, zipfile was bad. More Info : {e}" + ) except FileNotFoundError as e: - print(f"Could not extract content to destination, archive do not exist. More Info : {e.filename} : {e}") + print( + f"Could not extract content to destination, archive do not exist. More Info : {e.filename} : {e}" + ) except FileExistsError as e: - print(f"Could not extract content to destination, file(s) already exist. More Info : {e.filename} : {e}") + print( + f"Could not extract content to destination, file(s) already exist. More Info : {e.filename} : {e}" + ) except RuntimeError as e: print(f"An unexpected error occured. More info {e.args}") else: - print(f"Successully extracted the {contentType.name} ({archive_file}) at instance : {instance_path}") + print( + f"Successully extracted the {contentType.name} ({archive_file}) at instance : {instance_path}" + ) -def main(): + +def main(): parser = argparse.ArgumentParser( prog="LCE Mods Manager", - description="Manage DLC, World and Mods for Minecraft LCE" + description="Manage DLC, World and Mods for Minecraft LCE", ) - file : str = "" - contentType : str = "" - instance_path : str = "" - contentTypeEnum : ContentType = ContentType.NONE + file: str = "" + contentType: str = "" + instance_path: str = "" + contentTypeEnum: ContentType = ContentType.NONE if len(sys.argv) > 1: parser.add_help = True parser.epilog = LEGAL_TEXT - parser.add_argument("--instance_path", type=str, help="Path of the instance to install the content on") - parser.add_argument("--content_type", type=str, help="Content Type, possible valie : DLC, World and Mod") + parser.add_argument( + "--instance_path", + type=str, + help="Path of the instance to install the content on", + ) + parser.add_argument( + "--content_type", + type=str, + help="Content Type, possible valie : DLC, World and Mod", + ) parser.add_argument("--file", type=str, help="The Archive file to install") parsed_cmd_args = parser.parse_known_intermixed_args() @@ -126,7 +149,7 @@ def main(): 4. Install Custom Skin 5. Cancel """) - + user_input = input("Choose a option") if user_input == "1": @@ -139,18 +162,18 @@ def main(): contentTypeEnum = ContentType.CUSTOM_SKIN else: exit("Operation Canceled") - - if (contentType == "DLC"): + + if contentType == "DLC": contentTypeEnum = ContentType.DLC - if (contentType == "World"): + if contentType == "World": contentTypeEnum = ContentType.WORLD - if (contentType == "Mod"): + if contentType == "Mod": contentTypeEnum = ContentType.MOD - if (contentType == "Custom Skin"): - contentTypeEnum = ContentType.CUSTOM_SKIN + if contentType == "Custom Skin": + contentTypeEnum = ContentType.CUSTOM_SKIN else: pass - + instance_path = parsed_cmd_args[0].instance_path if instance_path == "None": @@ -160,7 +183,7 @@ def main(): if file == "None": file = input(f"Enter the archive of the {contentTypeEnum.name}") - + else: print(r""" 1. Install Maps/World @@ -169,7 +192,7 @@ def main(): 4. Install Custom Skin 5. Cancel """) - + user_input = input("Choose a option") if user_input == "1": @@ -182,7 +205,7 @@ def main(): contentTypeEnum = ContentType.CUSTOM_SKIN else: exit("Operation Canceled") - + instance_path = input("Enter the Instance path.") file = input(f"Enter the archive of the {contentTypeEnum.name}") @@ -193,7 +216,8 @@ def main(): Content Type : {contentTypeEnum.value} Instance_Path : {instance_path}""") - install_content(instance_path, contentTypeEnum, file) + install_content(instance_path, contentTypeEnum, file) + if __name__ == "__main__": main() diff --git a/src/lce_qt_launcher/managers/steam_manager.py b/src/lce_qt_launcher/managers/steam_manager.py index 026bb55..9080b0d 100644 --- a/src/lce_qt_launcher/managers/steam_manager.py +++ b/src/lce_qt_launcher/managers/steam_manager.py @@ -1,25 +1,23 @@ #!/usr/bin/env python """ - LCE Instances Steam Manager - Copyright (C) 2026 Xgui4 +LCE Instances Steam Manager +Copyright (C) 2026 Xgui4 - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . +You should have received a copy of the GNU General Public License +along with this program. If not, see . """ -from PySide6.QtWidgets import ( - QMessageBox -) +from PySide6.QtWidgets import QMessageBox import argparse import subprocess @@ -34,8 +32,9 @@ LEGAL_TEXT = """ under certain conditions; type `show c' for details. """ -def add_instance_to_steam(abs_instance_exe_path : str, instance_name : str, icon : str): - """#TODO _summary_ + +def add_instance_to_steam(abs_instance_exe_path: str, instance_name: str, icon: str): + """#TODO _summary_ #TODO Args: instance_exe_path (str): _description_ @@ -44,35 +43,52 @@ def add_instance_to_steam(abs_instance_exe_path : str, instance_name : str, icon """ try: try: - QMessageBox.warning(None, "Warning", "For this operation, it is recommended to close steam. ") + QMessageBox.warning( + None, + "Warning", + "For this operation, it is recommended to close steam. ", + ) except RuntimeError: input("Warning : For this operation, it is recommended to close steam.") - QMessageBox.warning(None, "Warning", "For this operation, it is recommended to close steam. ") + QMessageBox.warning( + None, "Warning", "For this operation, it is recommended to close steam. " + ) if platform.uname().system == "Linux": - subprocess.run(["steamtinkerlaunch", "ansg", - f"-an=\"Minecraft LCE ({instance_name}\"", - f"-ep=\"{abs_instance_exe_path}\"", - f"-ip={icon}"]) + subprocess.run( + [ + "steamtinkerlaunch", + "ansg", + f'-an="Minecraft LCE ({instance_name}"', + f'-ep="{abs_instance_exe_path}"', + f"-ip={icon}", + ] + ) try: - QMessageBox.warning(None, "Warning", "This function is in work in progress and the id is not saved in the launcher. \n" \ - "Until this is added, a manual intervention is needed to found the id and put in the save file. ") - except RuntimeError: - print("Warning : This function is in work in progress and the id is not saved in the launcher. \n" \ - "Until this is added, a manual intervention is needed to found the id and put in the save file. ") - else : + QMessageBox.warning( + None, + "Warning", + "This function is in work in progress and the id is not saved in the launcher. \n" + "Until this is added, a manual intervention is needed to found the id and put in the save file. ", + ) + except RuntimeError: + print( + "Warning : This function is in work in progress and the id is not saved in the launcher. \n" + "Until this is added, a manual intervention is needed to found the id and put in the save file. " + ) + else: QMessageBox.critical(None, "Critical Error", "Not Implemented Yet!") except RuntimeError as err: print(f"Error while adding program to steam : {err}") - + + def main(): parser = argparse.ArgumentParser( - prog="LCE Instances Steam Manager", - description="Add LCE instance to Steam" + prog="LCE Instances Steam Manager", description="Add LCE instance to Steam" ) - instance_exe_path : str = "" - instance_name : str = "" - icon : str = "" + instance_exe_path: str = "" + instance_name: str = "" + icon: str = "" print(LEGAL_TEXT) @@ -80,14 +96,22 @@ def main(): parser.add_help = True parser.epilog = LEGAL_TEXT - parser.add_argument("--exe_path", type=str, help="Path of the instance exe to add to Steam") - parser.add_argument("--name", type=str, help="Instance Name of the instance to add to Steam") - parser.add_argument("--icon", type=str, help="The icon of the instance to add to Steam") + parser.add_argument( + "--exe_path", type=str, help="Path of the instance exe to add to Steam" + ) + parser.add_argument( + "--name", type=str, help="Instance Name of the instance to add to Steam" + ) + parser.add_argument( + "--icon", type=str, help="The icon of the instance to add to Steam" + ) parsed_cmd_args = parser.parse_known_intermixed_args() if parsed_cmd_args[0].intance_exe_path == "None": - instance_exe_path = input("Enter the instance of path of the exe to add on steam") + instance_exe_path = input( + "Enter the instance of path of the exe to add on steam" + ) if parsed_cmd_args[0].intance_name == "None": instance_name = input("Enter the name of instance to add on steam") if parsed_cmd_args[0].icon == "None": @@ -95,10 +119,13 @@ def main(): add_instance_to_steam(instance_exe_path, instance_name, icon) else: - instance_exe_path = input("Enter the instance of path of the exe to add on steam") + instance_exe_path = input( + "Enter the instance of path of the exe to add on steam" + ) instance_name = input("Enter the name of instance to add on steam") icon = input("Enter the path of the icon of the instance to add on steam") add_instance_to_steam(instance_exe_path, instance_name, icon) + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/src/lce_qt_launcher/managers/system_manager.py b/src/lce_qt_launcher/managers/system_manager.py index 8b8b305..2fe0663 100644 --- a/src/lce_qt_launcher/managers/system_manager.py +++ b/src/lce_qt_launcher/managers/system_manager.py @@ -10,6 +10,7 @@ import stat import lce_qt_launcher.views.term_service as term_service + class OperatingSystemType(StrEnum): WINDOWS = "Microsoft Windows" MACOS = "MacOS" @@ -18,34 +19,36 @@ class OperatingSystemType(StrEnum): ANDROID = "Android" UNKNOWN = "Unknown" -class SystemManager(): - """_summary_ Multiples Utilises to interact with the system """ + +class SystemManager: + """_summary_ Multiples Utilises to interact with the system""" + def __init__(self) -> None: - self.type : OperatingSystemType = OperatingSystemType.UNKNOWN - self.name : str = "Unknown" - self.version : str = "Unknown" - + self.type: OperatingSystemType = OperatingSystemType.UNKNOWN + self.name: str = "Unknown" + self.version: str = "Unknown" + self.determine_os_info() - def determine_os_info(self) -> None: - """_summary_ Assert the OS and its Info """ - if (platform.system() == "Linux") : - self.type = OperatingSystemType.LINUX + def determine_os_info(self) -> None: + """_summary_ Assert the OS and its Info""" + if platform.system() == "Linux": + self.type = OperatingSystemType.LINUX self.name = self.type.name self.version = platform.version() - elif (platform.system() == "Darwin") : - self.type = OperatingSystemType.MACOS + elif platform.system() == "Darwin": + self.type = OperatingSystemType.MACOS self.name = self.type.name self.version = str(platform.mac_ver()) - elif (platform.system() == "Windows") : + elif platform.system() == "Windows": self.type = OperatingSystemType.WINDOWS self.name = self.type.name self.version = str(platform.win32_ver()) - elif (platform.system() == "FreeBSD"): - self.type = OperatingSystemType.FREEBSD + elif platform.system() == "FreeBSD": + self.type = OperatingSystemType.FREEBSD self.name = self.type.name self.version = platform.version() - elif (platform.system() == "Android") : + elif platform.system() == "Android": self.type = OperatingSystemType.ANDROID self.name = self.type.name self.version = platform.version() @@ -53,20 +56,20 @@ class SystemManager(): self.type = OperatingSystemType.UNKNOWN self.name = self.type.name self.version = platform.version() - + def adapt_qt_system_theme(self) -> None: """_summary_ Set the Qt Theme to the System on GNU/Linux and FreeBSD""" - if platform.system() == "Linux": + if platform.system() == "Linux": _LINUX_QT6_PATH = "/usr/lib/qt6/plugins" os.environ["QT_PLUGIN_PATH"] = _LINUX_QT6_PATH - if platform.system() == "FreeBSD": + if platform.system() == "FreeBSD": _FREEBSD_QT6_PATH = "/usr/local/lib/qt6/plugins" os.environ["QT_PLUGIN_PATH"] = _FREEBSD_QT6_PATH def set_file_permission(self, file_abs_path: str) -> str: """ _summary_ Makes the file executable on POSIX systems. Do Nothing on NT (Windows) - + Args: file_abs_path : str = "The absolute file path to change the permissions" """ @@ -75,10 +78,12 @@ class SystemManager(): os.chmod(file_abs_path, st.st_mode | stat.S_IEXEC) return "Permissions updated." else: - term_service.print_information("No POSIX system detected, skipping file permission management.") + term_service.print_information( + "No POSIX system detected, skipping file permission management." + ) return "Non POSIX System." - - def open_url_with_system(self, url_str : str) -> None: + + def open_url_with_system(self, url_str: str) -> None: """_summary_ Open a URL/file with the system Args: @@ -87,11 +92,11 @@ class SystemManager(): url = QUrl(url_str) service = QDesktopServices() _ = service.openUrl(url) - + def found_default_save_path(self) -> str: - """ + """ #! DEPRECIATED FIXME - REMOVE THIS FUNCTION AND REPLACE IT WITH OTHERS """ - return os.path.join(pathlib.Path.home(), "lce-qt-launcher") + return os.path.join(pathlib.Path.home(), "lce-qt-launcher") diff --git a/src/lce_qt_launcher/models/app_data.py b/src/lce_qt_launcher/models/app_data.py index bbd79a5..5cf3963 100644 --- a/src/lce_qt_launcher/models/app_data.py +++ b/src/lce_qt_launcher/models/app_data.py @@ -11,36 +11,45 @@ import os from lce_qt_launcher.views import term_service + def _is_compiled() -> bool: return "__compiled__" in globals() + def _is_installed() -> bool: current_dir = os.path.dirname(os.path.abspath(__file__)) return "site-packages" in current_dir or "dist-packages" in current_dir + class AppData(QObject): changed: Signal = Signal() - def __init__(self) -> None: - super().__init__(parent = None, objectName="App Data") - self.instsList : list[Instance] = [] - self.sourceDir : str = self._get_source_dir() - self.projectRootDir : str = self._get_project_root_dir() - self.appConfigDir : str = self._get_app_config_dir() - self.localesDir : str = self._get_locales_dir() - self.assetsDirs : str = self._get_assets_dir() - self.appDataDirs: tuple[str, str] = ( self._get_user_app_data_dir(), self._get_site_app_data_dir() ) - self.appCacheDir : str = self._get_app_cache_dir() - self.appLogDir : str = self._get_app_log_dir() + def __init__(self) -> None: + super().__init__(parent=None, objectName="App Data") + + self.instsList: list[Instance] = [] + self.sourceDir: str = self._get_source_dir() + self.projectRootDir: str = self._get_project_root_dir() + self.appConfigDir: str = self._get_app_config_dir() + self.localesDir: str = self._get_locales_dir() + self.assetsDirs: str = self._get_assets_dir() + self.appDataDirs: tuple[str, str] = ( + self._get_user_app_data_dir(), + self._get_site_app_data_dir(), + ) + self.appCacheDir: str = self._get_app_cache_dir() + self.appLogDir: str = self._get_app_log_dir() self.load_insts_list_into_mem() def load_insts_list_into_mem(self) -> None: - """#TODO : make it so it also work on both user and system (site) dir if needed. + """#TODO : make it so it also work on both user and system (site) dir if needed. #TODO : docstring """ - defaults_insts_dir : Path = Path(os.path.join(self.appDataDirs[0], "instances")) + defaults_insts_dir: Path = Path(os.path.join(self.appDataDirs[0], "instances")) if not defaults_insts_dir.exists(): - term_service.print_information(f"{defaults_insts_dir} did not exist. Trying to recreate it.") + term_service.print_information( + f"{defaults_insts_dir} did not exist. Trying to recreate it." + ) try: os.makedirs(defaults_insts_dir) except OSError: @@ -48,17 +57,19 @@ class AppData(QObject): except RuntimeError: term_service.print_error("An une error have occured : {RuntineError}") return - instancesLists : list[Instance] = [] + instancesLists: list[Instance] = [] for file_path in defaults_insts_dir.iterdir(): if file_path.is_file(): try: - with open(file=file_path, mode="r", encoding="utf-8") as file: - context_dict:dict[str, str] = json.load(file) # pyright: ignore[reportAny] + with open(file=file_path, mode="r", encoding="utf-8") as file: + context_dict: dict[str, str] = json.load(file) # pyright: ignore[reportAny] new_inst = Instance() new_inst.load_inst_from_dict(context_dict) instancesLists.append(new_inst) except (json.JSONDecodeError, OSError, ValueError): - term_service.print_error(f"Cannot decode JSON {OSError} {ValueError} {json.JSONDecodeError}") + term_service.print_error( + f"Cannot decode JSON {OSError} {ValueError} {json.JSONDecodeError}" + ) else: term_service.print_information(f"{file_path} was not a file.") self.instsList = instancesLists @@ -93,7 +104,7 @@ class AppData(QObject): Returns: str: _description_ """ - return os.path.join(self._get_project_root_dir(),"assets", "languages") + return os.path.join(self._get_project_root_dir(), "assets", "languages") def _get_assets_dir(self) -> str: """_summary_ TODO : docstring @@ -138,7 +149,7 @@ class AppData(QObject): """ dirs: PlatformDirs = PlatformDirs("LCE-Qt-Launcher", "Xgui4") return dirs.user_log_dir - + def _get_app_config_dir(self) -> str: """_summary_ TODO : docstring @@ -146,4 +157,4 @@ class AppData(QObject): str: _description_ """ dirs: PlatformDirs = PlatformDirs("LCE-Qt-Launcher", "Xgui4") - return dirs.user_config_dir \ No newline at end of file + return dirs.user_config_dir diff --git a/src/lce_qt_launcher/models/preferences.py b/src/lce_qt_launcher/models/preferences.py index e021014..6e4c290 100644 --- a/src/lce_qt_launcher/models/preferences.py +++ b/src/lce_qt_launcher/models/preferences.py @@ -1,37 +1,44 @@ -#TODO : Need to finish some python docstring +# TODO : Need to finish some python docstring from PySide6.QtCore import QSettings from lce_qt_launcher.build_info import BuildInfo from lce_qt_launcher.models.theme import StrTheme -_THEME_OPTION : str = "customisation/theme" -_INSTANCE_PATH_OPTION : str = "preferences/default_path" -_LANGUAGE_OPTION : str = "preferences/language" -_SHOW_HOLIDAY_OPTION : str = "views/show_hoyday_enabled" -_DEVELOPPER_MODE_OPTION : str = "developper/dev_mode_enabled" -_ACCESIBLE_MODE_OPTION : str = "accesibility/accesibility_mode_enabled" -_EXPERIMENTAL_MODE_OPTION : str = "preferences/experimental_mode_enabled" -_USERNAME_OPTION : str = "user_profile/username" +_THEME_OPTION: str = "customisation/theme" +_INSTANCE_PATH_OPTION: str = "preferences/default_path" +_LANGUAGE_OPTION: str = "preferences/language" +_SHOW_HOLIDAY_OPTION: str = "views/show_hoyday_enabled" +_DEVELOPPER_MODE_OPTION: str = "developper/dev_mode_enabled" +_ACCESIBLE_MODE_OPTION: str = "accesibility/accesibility_mode_enabled" +_EXPERIMENTAL_MODE_OPTION: str = "preferences/experimental_mode_enabled" +_USERNAME_OPTION: str = "user_profile/username" -class UserPref (QSettings): + +class UserPref(QSettings): """_summary_ The UserPref managed by QtSettings Args: QSettings (_type_): _description_ : Inherit QtSettings """ - def __init__(self, buildInfo : BuildInfo) -> None: - super().__init__(QSettings.Format.IniFormat, QSettings.Scope.UserScope, "Xgui4", buildInfo.app_name) - self.default_theme : StrTheme = StrTheme.MINECRAFT - self.default_instance_path : str = "{appData}/instances" - self.default_language : str = "en" - self.default_show_holiday : bool = True - self.default_accesibility_mode : bool = False - self.default_developper_mode : bool = False - self.default_experiment_mode : bool = False - self.default_username : str = "Steve" - def set_theme_pref(self, theme : str) -> None: + def __init__(self, buildInfo: BuildInfo) -> None: + super().__init__( + QSettings.Format.IniFormat, + QSettings.Scope.UserScope, + "Xgui4", + buildInfo.app_name, + ) + self.default_theme: StrTheme = StrTheme.MINECRAFT + self.default_instance_path: str = "{appData}/instances" + self.default_language: str = "en" + self.default_show_holiday: bool = True + self.default_accesibility_mode: bool = False + self.default_developper_mode: bool = False + self.default_experiment_mode: bool = False + self.default_username: str = "Steve" + + def set_theme_pref(self, theme: str) -> None: """_summary_ Theme Setter Args: @@ -39,11 +46,12 @@ class UserPref (QSettings): """ super().setValue(_THEME_OPTION, theme) super().sync() + def get_theme_pref(self) -> str: """_summary_ Theme Getter""" return str(self.value(_THEME_OPTION, self.default_theme, type=str)) - def set_language_pref(self, language : str) -> None: + def set_language_pref(self, language: str) -> None: """_summary_ Language Setter Args: @@ -51,11 +59,12 @@ class UserPref (QSettings): """ super().setValue(_LANGUAGE_OPTION, language) super().sync() + def get_language_pref(self) -> str: """_summary_ Language Getter""" return str(self.value(_LANGUAGE_OPTION, self.default_theme, type=str)) - - def set_instance_path_pref(self, instance_path : str) -> None: + + def set_instance_path_pref(self, instance_path: str) -> None: """_summary_ Default Instance Path Setter Args: @@ -63,41 +72,48 @@ class UserPref (QSettings): """ super().setValue(_INSTANCE_PATH_OPTION, instance_path) super().sync() + def get_instance_path(self) -> str: - """_summary_ Default Instance Path Getter - """ - return str(self.value(_INSTANCE_PATH_OPTION, self.default_instance_path, type=str)) - - def set_show_holiday(self, show_holiday_bool : bool) -> None: - """_summary_ Show Holiday Toggle Setter - """ + """_summary_ Default Instance Path Getter""" + return str( + self.value(_INSTANCE_PATH_OPTION, self.default_instance_path, type=str) + ) + + def set_show_holiday(self, show_holiday_bool: bool) -> None: + """_summary_ Show Holiday Toggle Setter""" super().setValue(_SHOW_HOLIDAY_OPTION, show_holiday_bool) super().sync() + def get_show_holiday(self) -> str: """_summary_ Show Holiday Toggle Getter Returns: str: _description_ show holyday preference """ - return str(self.value(_SHOW_HOLIDAY_OPTION, self.default_show_holiday, type=str)) + return str( + self.value(_SHOW_HOLIDAY_OPTION, self.default_show_holiday, type=str) + ) - def set_accesible_mode(self, accesbility_mode_bool : bool) -> None: - """_summary_ Accessiblty Mode Sette + def set_accesible_mode(self, accesbility_mode_bool: bool) -> None: + """_summary_ Accessiblty Mode Sette Args: accesbility_mode_bool (bool): _description_ #TODO DOCSTRINGS """ super().setValue(_ACCESIBLE_MODE_OPTION, accesbility_mode_bool) super().sync() + def get_accesible_mode(self) -> str: """_summary_ Accesiblity Toggle Getter Returns: - str: _description_ + str: _description_ """ - return str(self.value(_ACCESIBLE_MODE_OPTION, self.default_accesibility_mode, type=str)) - - def set_developper_mode(self, developper_mode_bool : bool) -> None: + return str( + self.value(_ACCESIBLE_MODE_OPTION, self.default_accesibility_mode, type=str) + ) + + def set_developper_mode(self, developper_mode_bool: bool) -> None: """_summary_ Dev Mode Setter Args: @@ -105,15 +121,18 @@ class UserPref (QSettings): """ super().setValue(_DEVELOPPER_MODE_OPTION, developper_mode_bool) super().sync() + def get_developper_mode(self) -> str: """_summary_ Dev Mode Getter Returns: str: _description_ #TODO DOCSTRINGS """ - return str(self.value(_DEVELOPPER_MODE_OPTION, self.default_developper_mode, type=str)) - - def set_experimental_mode(self, experimental_mode_bool : bool) -> None: + return str( + self.value(_DEVELOPPER_MODE_OPTION, self.default_developper_mode, type=str) + ) + + def set_experimental_mode(self, experimental_mode_bool: bool) -> None: """_summary_ Experimental Mode Setter Args: @@ -121,15 +140,20 @@ class UserPref (QSettings): """ super().setValue(_EXPERIMENTAL_MODE_OPTION, experimental_mode_bool) super().sync() + def get_experimental_mode(self) -> str: """_summary_ Experimental Mode Getter Returns: str: _description_ #TODO DOCSTRINGS """ - return str(self.value(_EXPERIMENTAL_MODE_OPTION, self.default_experiment_mode, type=str)) - - def set_username(self, new_username : str) -> None: + return str( + self.value( + _EXPERIMENTAL_MODE_OPTION, self.default_experiment_mode, type=str + ) + ) + + def set_username(self, new_username: str) -> None: """_summary_ Username Setter Args: @@ -137,6 +161,7 @@ class UserPref (QSettings): """ super().setValue(_USERNAME_OPTION, new_username) super().sync() + def get_username(self) -> str: """_summary_ Experimental Mode Getter @@ -146,8 +171,7 @@ class UserPref (QSettings): return str(self.value(_USERNAME_OPTION, self.default_username, type=str)) def generate_default_config(self) -> None: - """_summary_ Generate the default config for the users - """ + """_summary_ Generate the default config for the users""" self.set_theme_pref(self.default_theme) self.set_language_pref(self.default_language) self.set_instance_path_pref(self.default_instance_path) diff --git a/src/lce_qt_launcher/models/theme.py b/src/lce_qt_launcher/models/theme.py index 445ea3a..c61abad 100644 --- a/src/lce_qt_launcher/models/theme.py +++ b/src/lce_qt_launcher/models/theme.py @@ -1,28 +1,33 @@ from ctypes import ArgumentError from enum import StrEnum, Enum + class StrTheme(StrEnum): """_summary_ The QtApp Stylesheet theme""" + MINECRAFT = ":/styles/minecraft.qss" DARK = ":/styles/dark.qss" LIGHT = ":/sytles/light.qss" SYSTEM = "SYSTEM" + class ThemeEntity(Enum): - """ TODO _summary_ + """TODO _summary_ Args: Enum (_type_): _description_ """ + DEFAULT = 0 MINECRAFT = 1 LIGHT = 2 DARK = 3 SYSTEM = 4 -def from_entity_to_strTheme(entity : ThemeEntity) -> StrTheme: + +def from_entity_to_strTheme(entity: ThemeEntity) -> StrTheme: match entity: - case ThemeEntity.DEFAULT | ThemeEntity.MINECRAFT: + case ThemeEntity.DEFAULT | ThemeEntity.MINECRAFT: return StrTheme.MINECRAFT case ThemeEntity.LIGHT: return StrTheme.LIGHT @@ -31,8 +36,9 @@ def from_entity_to_strTheme(entity : ThemeEntity) -> StrTheme: case ThemeEntity.SYSTEM: return StrTheme.SYSTEM -def get_theme_file_name(strTheme : StrTheme) -> str: - """ TODO _summary_ + +def get_theme_file_name(strTheme: StrTheme) -> str: + """TODO _summary_ Args: strTheme (StrTheme): _description_ @@ -41,13 +47,18 @@ def get_theme_file_name(strTheme : StrTheme) -> str: _type_: _description_ """ match strTheme: - case StrTheme.MINECRAFT : return "minecraft.qss" - case StrTheme.DARK : return "dark.qss" - case StrTheme.LIGHT : return "light.qss" - case StrTheme.SYSTEM : return "SYSTEM" - -def from_str_to_strTheme(string : str) -> StrTheme: - """ TODO _summary_ + case StrTheme.MINECRAFT: + return "minecraft.qss" + case StrTheme.DARK: + return "dark.qss" + case StrTheme.LIGHT: + return "light.qss" + case StrTheme.SYSTEM: + return "SYSTEM" + + +def from_str_to_strTheme(string: str) -> StrTheme: + """TODO _summary_ Args: string (str): _description_ @@ -59,8 +70,13 @@ def from_str_to_strTheme(string : str) -> StrTheme: StrTheme: _description_ """ match string: - case ":/styles/minecraft.qss": return StrTheme.MINECRAFT - case ":/styles/dark.qss": return StrTheme.DARK - case ":/sytles/light.qss" : return StrTheme.LIGHT - case "": return StrTheme.SYSTEM - case _ : raise ArgumentError(f"{string} is not a valid theme") \ No newline at end of file + case ":/styles/minecraft.qss": + return StrTheme.MINECRAFT + case ":/styles/dark.qss": + return StrTheme.DARK + case ":/sytles/light.qss": + return StrTheme.LIGHT + case "": + return StrTheme.SYSTEM + case _: + raise ArgumentError(f"{string} is not a valid theme") diff --git a/src/lce_qt_launcher/utils/__init__.py b/src/lce_qt_launcher/utils/__init__.py index b87dc0c..18a44ec 100644 --- a/src/lce_qt_launcher/utils/__init__.py +++ b/src/lce_qt_launcher/utils/__init__.py @@ -1,7 +1,9 @@ import platformdirs + def get_user_doc_folder() -> str: return platformdirs.user_documents_dir() + def get_user_download_folder() -> str: - return platformdirs.user_downloads_dir() \ No newline at end of file + return platformdirs.user_downloads_dir() diff --git a/src/lce_qt_launcher/utils/holiday.py b/src/lce_qt_launcher/utils/holiday.py index 45fb67e..b984202 100644 --- a/src/lce_qt_launcher/utils/holiday.py +++ b/src/lce_qt_launcher/utils/holiday.py @@ -1,36 +1,53 @@ from datetime import datetime from enum import Enum + class MONTH(Enum): """_summary_ The 12 Month as Enum (Start from 1 and go to 12) d""" + JANUARY = 1 FEBRURAY = 2 MARCH = 3 APRIL = 4 MAY = 5 - JUNE = 6 - JULY = 7 + JUNE = 6 + JULY = 7 AUGUST = 8 - SEPTEMBER = 9 + SEPTEMBER = 9 OCTOBER = 10 NOVEMBER = 11 DECEMBER = 12 -def monthEnumToStr(enum : MONTH) -> str : + +def monthEnumToStr(enum: MONTH) -> str: match enum: - case 1 : return "January", - case 2 : return "February", - case 3 : return "March", - case 4 : return "April", - case 5 : return "May", - case 6 : return "June", - case 7 : return "July", - case 8 : return "August", - case 9 : return "September", - case 10 : return "October", - case 11 : return "November", - case 12 : return "December", - case _ : return "" + case 1: + return ("January",) + case 2: + return ("February",) + case 3: + return ("March",) + case 4: + return ("April",) + case 5: + return ("May",) + case 6: + return ("June",) + case 7: + return ("July",) + case 8: + return ("August",) + case 9: + return ("September",) + case 10: + return ("October",) + case 11: + return ("November",) + case 12: + return ("December",) + case _: + return "" + HOLIDAYS: dict[str, str] = { f"{MONTH.JANUARY.value}-1": "Happy New Years Day! 🎇", @@ -43,38 +60,40 @@ HOLIDAYS: dict[str, str] = { f"{MONTH.OCTOBER.value}-31": "Halloween 🎃", f"{MONTH.DECEMBER.value}-24": "Xmas Eve 🎄", f"{MONTH.DECEMBER.value}-25": "Xmas 🎅", - f"{MONTH.DECEMBER.value}-31": "New Year Eve 🎆" + f"{MONTH.DECEMBER.value}-31": "New Year Eve 🎆", } HOLIDAYS_FRENCH: dict[str, str] = { -f"{MONTH.JANUARY.value}-1": "Bonne année ! 🎇", -f"{MONTH.FEBRURAY.value}-14": "Bonne Saint-Valentin ! 💘", -f"{MONTH.APRIL.value}-1": "Poisson d'avril 🐟", -f"{MONTH.APRIL.value}-2": "Célébrons la Journée de sensibilisation à l'autisme aujourd'hui ! 🎉🌈♾️", -f"{MONTH.APRIL.value}": "Joyeux mois de sensibilisation à l'autisme ! 🎉🌈♾️", -f"{MONTH.MAY.value}-4": "Journée Star Wars 🌟", -f"{MONTH.MAY.value}-17": "Anniversaire de Minecraft 🎂", -f"{MONTH.OCTOBER.value}-31": "Halloween 🎃", -f"{MONTH.DECEMBER.value}-24": "Veille de Noël 🎄", -f"{MONTH.DECEMBER.value}-25": "Noël 🎅", -f"{MONTH.DECEMBER.value}-31": "Veille du Nouvel An 🎆" + f"{MONTH.JANUARY.value}-1": "Bonne année ! 🎇", + f"{MONTH.FEBRURAY.value}-14": "Bonne Saint-Valentin ! 💘", + f"{MONTH.APRIL.value}-1": "Poisson d'avril 🐟", + f"{MONTH.APRIL.value}-2": "Célébrons la Journée de sensibilisation à l'autisme aujourd'hui ! 🎉🌈♾️", + f"{MONTH.APRIL.value}": "Joyeux mois de sensibilisation à l'autisme ! 🎉🌈♾️", + f"{MONTH.MAY.value}-4": "Journée Star Wars 🌟", + f"{MONTH.MAY.value}-17": "Anniversaire de Minecraft 🎂", + f"{MONTH.OCTOBER.value}-31": "Halloween 🎃", + f"{MONTH.DECEMBER.value}-24": "Veille de Noël 🎄", + f"{MONTH.DECEMBER.value}-25": "Noël 🎅", + f"{MONTH.DECEMBER.value}-31": "Veille du Nouvel An 🎆", } NO_HOLIDAY = "" + def get_holidays_list() -> str: - holidays_str : str = "" + holidays_str: str = "" for key, value in HOLIDAYS.items(): holidays_str = f"{key} - {value}" return holidays_str + def get_holiday() -> str: - """_summary_ Check for a holday and then return it or empty str if there is no holiday + """_summary_ Check for a holday and then return it or empty str if there is no holiday Returns: str: _description_ The current holiday or an empty str """ today: datetime = datetime.now() - month_key: str = str(today.month) + month_key: str = str(today.month) day_key: str = f"{month_key}-{today.day}" return HOLIDAYS.get(day_key, HOLIDAYS.get(month_key, NO_HOLIDAY)) diff --git a/src/lce_qt_launcher/utils/json_trans.py b/src/lce_qt_launcher/utils/json_trans.py index 97bfd36..1b0b0f7 100644 --- a/src/lce_qt_launcher/utils/json_trans.py +++ b/src/lce_qt_launcher/utils/json_trans.py @@ -5,19 +5,23 @@ import os import lce_qt_launcher.models.app_data as AppData import lce_qt_launcher.views.term_service as term_service + class JsonTrans(QObject): """_summary_ The JSON Translators. Translating str with a json locales file Args: QObject (_type_): _description_ inherited from QObject """ + languageChanged: Signal = Signal() - def __init__(self, appData : AppData.AppData, lang_code : str = "translations") -> None: + def __init__( + self, appData: AppData.AppData, lang_code: str = "translations" + ) -> None: super().__init__() self.json_data: dict[str, str] = {} self._current_lang: str = lang_code - self.appDataManager : AppData.AppData = appData + self.appDataManager: AppData.AppData = appData self.load_lang(lang_code=self._current_lang) def load_lang(self, lang_code: str) -> None: @@ -26,7 +30,9 @@ class JsonTrans(QObject): Args: lang_code (str): _description_ : the language code of the language to enabled """ - file_path: str = os.path.join(self.appDataManager.localesDir, f"{lang_code}.json") + file_path: str = os.path.join( + self.appDataManager.localesDir, f"{lang_code}.json" + ) if not os.path.exists(file_path): term_service.print_error(f"{file_path} introuvable.") return @@ -34,7 +40,7 @@ class JsonTrans(QObject): with open(file=file_path, mode="r", encoding="utf-8") as f: self.json_data = json.load(f) self._current_lang = lang_code - self.languageChanged.emit() + self.languageChanged.emit() except Exception as e: term_service.print_error(f"lors du chargement JSON: {e}") @@ -42,7 +48,7 @@ class JsonTrans(QObject): """_summary_ Get the localized Text from a key and a fallback (attr default) Args: - key (str): _description_ : the key of the locaziled text + key (str): _description_ : the key of the locaziled text default (str, optional): _description_. Defaults to "". : the fallback tr Returns: diff --git a/src/lce_qt_launcher/views/browser_dialog.py b/src/lce_qt_launcher/views/browser_dialog.py index ce7991f..b014e54 100644 --- a/src/lce_qt_launcher/views/browser_dialog.py +++ b/src/lce_qt_launcher/views/browser_dialog.py @@ -1,16 +1,18 @@ -from PySide6.QtWidgets import QDialog, QHBoxLayout, QWidget +from PySide6.QtWidgets import QDialog, QHBoxLayout, QWidget from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtCore import QUrl from lce_qt_launcher.build_info import BuildInfo + class BrowserDialog(QDialog): - """_summary_ An QWebEngine Dialog + """_summary_ An QWebEngine Dialog Args: QDialog (_type_): _description_ inherited from QDialog """ - def __init__(self, parent : QWidget, url : str, build_info : BuildInfo) -> None: + + def __init__(self, parent: QWidget, url: str, build_info: BuildInfo) -> None: super().__init__() browser_dialog = QDialog(parent) webview = QWebEngineView() @@ -19,4 +21,4 @@ class BrowserDialog(QDialog): layout = QHBoxLayout() layout.addWidget(webview) browser_dialog.setLayout(layout) - browser_dialog.show() \ No newline at end of file + browser_dialog.show() diff --git a/src/lce_qt_launcher/views/cli.py b/src/lce_qt_launcher/views/cli.py index d510b45..931ea7b 100644 --- a/src/lce_qt_launcher/views/cli.py +++ b/src/lce_qt_launcher/views/cli.py @@ -3,21 +3,24 @@ from sys import argv from lce_qt_launcher.managers.instance_manager import InstanceManager import lce_qt_launcher.views.term_service as term_service -def launch_cli(instance_man : InstanceManager) -> None: - """ - _summary_ : launch the cli interface - Args: - instance_man : the instancer Manager object +def launch_cli(instance_man: InstanceManager) -> None: + """ + _summary_ : launch the cli interface + + Args: + instance_man : the instancer Manager object buildInfo (FIXME : unused) : an BuildInfo class """ - + MENU_STR = """ 1. [bold green] Play [/bold green] 2. [bold green] Install [/bold green] 3. [bold red] Others : Coming Soon ! [/bold red] """ - term_service.print_warning("CLI mode is currently untested and might be working correctly and will be reworked soon.") + term_service.print_warning( + "CLI mode is currently untested and might be working correctly and will be reworked soon." + ) term_service.print_pretty(""" LCE Qt Launcher Copyright (C) 2026 Xgui4 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. @@ -26,7 +29,7 @@ under certain conditions; type `show c' for details. """) term_service.print_pretty(MENU_STR) - user_output: str = input() + user_output: str = input() if len(argv) < 1: user_output = input() diff --git a/src/lce_qt_launcher/views/cmd_arg.py b/src/lce_qt_launcher/views/cmd_arg.py index 9c7c396..29d4697 100644 --- a/src/lce_qt_launcher/views/cmd_arg.py +++ b/src/lce_qt_launcher/views/cmd_arg.py @@ -4,8 +4,10 @@ from lce_qt_launcher.app_context import AppContext import lce_qt_launcher.features as features -class CmdArgAction(Enum): + +class CmdArgAction(Enum): """_summary_ The CMD flags Actions""" + GEN_CONFIG = 0 PRINT_VERSION = 1 PRINT_LICENSE = 2 @@ -14,12 +16,15 @@ class CmdArgAction(Enum): CLI_VERSION = 5 NO_ARGS = 6 -def argsDetected(action :CmdArgAction) -> bool: + +def argsDetected(action: CmdArgAction) -> bool: """Return True if there is a Args detected, Else Return False""" return action.value < CmdArgAction.NO_ARGS.value + class CmdArg(StrEnum): """_summary_ The list of command lines args str""" + GEN_CONFIG_CMD_ARG = "--gen-config" GEN_CONFIG_CMD_ARG_SHORT = "-g" VERSION_CMD_ARG = "--version" @@ -33,7 +38,8 @@ class CmdArg(StrEnum): HELP_CMD_ARG = "--help" HELP_CMD_ARG_SHORT = "-h" -def parse_args(argv : list[str]) -> CmdArgAction: + +def parse_args(argv: list[str]) -> CmdArgAction: """_summary_ Parse the cmd_args to get it actions Args: @@ -42,7 +48,7 @@ def parse_args(argv : list[str]) -> CmdArgAction: Returns: CmdArgAction: _description_ The Action of the flags/cmd_args to launch/activated """ - match argv: + match argv: case CmdArg.GEN_CONFIG_CMD_ARG | CmdArg.GEN_CONFIG_CMD_ARG_SHORT: return CmdArgAction.GEN_CONFIG case CmdArg.VERSION_CMD_ARG | CmdArg.VERSION_CMD_ARG_SHORT: @@ -57,11 +63,13 @@ def parse_args(argv : list[str]) -> CmdArgAction: return CmdArgAction.CLI_VERSION case _: return CmdArgAction.NO_ARGS - + + FALLBACK_ABOUT_MESSAGE = "This is a custom Minecraft LCE Launcher written in Python and Qt with Freedom and GNU/Linux support in mind." FALLBACK_HELP_MESSAGE = "-h or --help to get this help \n -v or --version to get the app version \n -L or --license to get the license information \n -a or --about to get information about the app \n -cl or --cli to launch the cli version \n -g or --gen-config to generate or update the app config" -def launch_cmd_action(action : CmdArgAction, appContext : AppContext) -> None: + +def launch_cmd_action(action: CmdArgAction, appContext: AppContext) -> None: """_summary_ Do the action with an provided AppContext Args: @@ -73,12 +81,16 @@ def launch_cmd_action(action : CmdArgAction, appContext : AppContext) -> None: elif action == CmdArgAction.PRINT_LICENSE: features.display_license(appContext.buildInfo) elif action == CmdArgAction.PRINT_HELP: - features.display_help(appContext.translator.translate("help-message", FALLBACK_HELP_MESSAGE)) + features.display_help( + appContext.translator.translate("help-message", FALLBACK_HELP_MESSAGE) + ) elif action == CmdArgAction.PRINT_ABOUT_INFO: - features.display_about(appContext.translator.translate("about_message", FALLBACK_ABOUT_MESSAGE)) - elif action == CmdArgAction.PRINT_VERSION: + features.display_about( + appContext.translator.translate("about_message", FALLBACK_ABOUT_MESSAGE) + ) + elif action == CmdArgAction.PRINT_VERSION: features.display_version(appContext.buildInfo) elif action == CmdArgAction.CLI_VERSION: features.launch_cli_interface(appContext.instanceMan) else: - pass \ No newline at end of file + pass diff --git a/src/lce_qt_launcher/views/content_installer_dialog.py b/src/lce_qt_launcher/views/content_installer_dialog.py index 4d2ef20..56cbe85 100644 --- a/src/lce_qt_launcher/views/content_installer_dialog.py +++ b/src/lce_qt_launcher/views/content_installer_dialog.py @@ -1,4 +1,4 @@ -from PySide6.QtWidgets import QDialog +from PySide6.QtWidgets import QDialog from lce_qt_launcher.managers import mod_manager from lce_qt_launcher.ui_contentInstaller import Ui_contentInstallerDialog @@ -6,11 +6,12 @@ from lce_qt_launcher.views import term_service class ContentInstallerView(QDialog): - """ #TODO _summary_ + """#TODO _summary_ Args: QDialog (_type_): _description_ inherited from QDialog """ + def __init__(self) -> None: super().__init__() self.ui_dialog: Ui_contentInstallerDialog = Ui_contentInstallerDialog() @@ -29,9 +30,12 @@ class ContentInstallerView(QDialog): self.contentToInstallPath = self.ui_dialog.contentToInstallInputBox.text() self.contentTypeStr = self.ui_dialog.contentTypeComboBox.currentText() self.instancePath = self.ui_dialog.instamcePathInputPath.text() - mod_manager.install_content(self.instancePath, mod_manager.from_str_to_enum(self.contentTypeStr), self.contentToInstallPath) + mod_manager.install_content( + self.instancePath, + mod_manager.from_str_to_enum(self.contentTypeStr), + self.contentToInstallPath, + ) self.ui_dialog.mainButtonBox.clicked.connect(installContentCommand) self.dialog.show() - diff --git a/src/lce_qt_launcher/views/launcher.py b/src/lce_qt_launcher/views/launcher.py index 76ee51f..51919fd 100644 --- a/src/lce_qt_launcher/views/launcher.py +++ b/src/lce_qt_launcher/views/launcher.py @@ -1,26 +1,17 @@ -from PySide6.QtWidgets import ( +from PySide6.QtWidgets import ( QApplication, - QFileDialog, - QMainWindow, - QLabel, + QFileDialog, + QMainWindow, + QLabel, QDialog, QListWidgetItem, QInputDialog, - QMessageBox + QMessageBox, ) -from PySide6.QtGui import ( - QPalette, - QPixmap, - QBrush -) +from PySide6.QtGui import QPalette, QPixmap, QBrush -from PySide6.QtCore import ( - qVersion, - Qt, - QFile, - QIODevice -) +from PySide6.QtCore import qVersion, Qt, QFile, QIODevice from PySide6.QtWebEngineCore import QWebEngineProfile, QWebEngineDownloadRequest @@ -52,17 +43,20 @@ import lce_qt_launcher.features as features import lce_qt_launcher.utils.holiday as holiday import lce_qt_launcher.res_rc # pyright: ignore[reportUnusedImport] + class LauncherView(QMainWindow): """_summary_ The Main Window / launcher of the QApplcation Args: QMainWindow (_type_): _description_ Inherited/is a QMainWindow - """ - def __init__(self, - appContext : AppContext, - appData : AppData, - app : QApplication, - ) -> None: + """ + + def __init__( + self, + appContext: AppContext, + appData: AppData, + app: QApplication, + ) -> None: super().__init__(None) translator: JsonTrans = appContext.translator @@ -83,36 +77,32 @@ class LauncherView(QMainWindow): instanceManager.instance = features.new_instance_from_form(self) def confirmChangesButtonCommand() -> None: - """_summary_ Generate An Instance From the Form for confirming the changes - """ + """_summary_ Generate An Instance From the Form for confirming the changes""" generateInstanceFromForm() def playButtonCommand() -> None: - """_summary_ playButtonCommand the Game - """ + """_summary_ playButtonCommand the Game""" features.launch_game(instanceManager, STARTING_GAME_MSG) def installButtonCommand() -> None: - """_summary_ Install the Game - """ + """_summary_ Install the Game""" features.install_game(self, instanceManager.instance, instanceManager) def showSettingDialogCommand() -> None: - """_summary_ Show the setting Dialog - """ + """_summary_ Show the setting Dialog""" features.show_setting(self, Ui_settingDialog(), appContext) def saveInstanceButtonCommand() -> None: - """_summary_ Save the instance on a file on disk - """ + """_summary_ Save the instance on a file on disk""" features.save_instance_to_file(self, instanceManager, appContext, buildInfo) def changeInstanceIconButtonCommand() -> None: file_name: str = QFileDialog.getOpenFileName( - self, - "Select the image file for the instance", - appContext.sys_man.found_default_save_path(), - f"{buildInfo.app_name} Instance File (*{buildInfo.instance_extension})")[0] + self, + "Select the image file for the instance", + appContext.sys_man.found_default_save_path(), + f"{buildInfo.app_name} Instance File (*{buildInfo.instance_extension})", + )[0] instanceManager.instance.image = file_name self.ui.instance_img.setPixmap(QPixmap(file_name)) @@ -120,44 +110,38 @@ class LauncherView(QMainWindow): features.show_instance_editor(self) def showAboutMinecraftActionCommand() -> None: - """_summary_ Open an QWebEngine at the Minecraft Website - """ + """_summary_ Open an QWebEngine at the Minecraft Website""" features.show_webbrowser(self, appContext.MINECRAFT_WEBSITE, buildInfo) def showMoreLCEProjectsActionCommand() -> None: - """_summary_ Open An QWebEngine at the Minecraft LCE collection website (not by me) - """ - features.show_webbrowser(self, appContext.MINECRAFT_LCE_WEBSITE, buildInfo) + """_summary_ Open An QWebEngine at the Minecraft LCE collection website (not by me)""" + features.show_webbrowser(self, appContext.MINECRAFT_LCE_WEBSITE, buildInfo) def updateActionCommand() -> None: - """_summary_ "Show the Update Page in a QWebEngine Popup - """ + """_summary_ "Show the Update Page in a QWebEngine Popup""" features.show_webbrowser(self, buildInfo.git_repo_url, buildInfo) - + def loadInstanceActionCommand() -> None: - """_summary_ Open the Load Save File Dialog - """ - features.load_instance_from_file(self, instanceManager, appContext, buildInfo, appData) - self.loadInstanceInForm(instanceManager) + """_summary_ Open the Load Save File Dialog""" + features.load_instance_from_file( + self, instanceManager, appContext, buildInfo, appData + ) + self.loadInstanceInForm(instanceManager) def showSystemInformationActionCommand() -> None: - """_summary_ Show the system info dialog - """ + """_summary_ Show the system info dialog""" features.show_system_info(self) def showAboutQtActionCommand() -> None: - """_summary_ Show the About Qt Dialog - """ + """_summary_ Show the About Qt Dialog""" features.show_about_qt(self) def showAboutActionCommand() -> None: - """_summary_ Show About App dialog - """ + """_summary_ Show About App dialog""" features.show_about_app(self) def installContentActionCommand() -> None: - """_summary_ Open the Content Installer Window - """ + """_summary_ Open the Content Installer Window""" ContentInstallerView() background_pixmap = QPixmap(appContext.BACKGROUND_PIXMAP_IMG) @@ -168,20 +152,22 @@ class LauncherView(QMainWindow): self.setAutoFillBackground(True) else: term_service.print_error("Cannot set the background") - + self.ui: Ui_launcher = Ui_launcher() self.ui.setupUi(self) - - arguments: list[str] = QApplication.instance().arguments() if not None else "Error" # pyright: ignore[reportOptionalMemberAccess] + + arguments: list[str] = ( + QApplication.instance().arguments() if not None else "Error" + ) # pyright: ignore[reportOptionalMemberAccess] for inst in appData.instsList: self.instances.append(inst) - item = QListWidgetItem() + item = QListWidgetItem() item.setText(inst.name) item.setIcon(QPixmap(inst.image)) item.setData(Qt.ItemDataRole.FileInfoRole, inst) self.ui.listWidget.addItem(item) - + if len(arguments) > 1: file_arg: str = arguments[1] try: @@ -192,21 +178,31 @@ class LauncherView(QMainWindow): instanceManager.instance.load_inst_from_dict(inst_dict) instanceManager.instance.display() else: - term_service.print_information("No file argument given or file not found. Loading default instance.") + term_service.print_information( + "No file argument given or file not found. Loading default instance." + ) except json.JSONDecodeError as err: - term_service.print_error(f"Invalid or corrupted Save File (JSON syntax) : {err.msg} at line {err.lineno}") + term_service.print_error( + f"Invalid or corrupted Save File (JSON syntax) : {err.msg} at line {err.lineno}" + ) except (ValueError, TypeError) as err: - term_service.print_error(f"Data structure error in Save File : {err}") + term_service.print_error(f"Data structure error in Save File : {err}") except PermissionError: - term_service.print_error("System Error : Permission denied when reading the file.") + term_service.print_error( + "System Error : Permission denied when reading the file." + ) except RecursionError: - term_service.print_error("System Error : The JSON structure is too deep to be processed.") + term_service.print_error( + "System Error : The JSON structure is too deep to be processed." + ) except Exception as err: term_service.print_error(f"An unexpected error occurred : {err}") else: - term_service.print_information("No argument given, start with default instance.") - - self.sysinfo_dialog: QDialog = QDialog() + term_service.print_information( + "No argument given, start with default instance." + ) + + self.sysinfo_dialog: QDialog = QDialog() self.dialog_ui: Ui_sys_info_dialog = Ui_sys_info_dialog() self.dialog_ui.setupUi(self.sysinfo_dialog) @@ -221,9 +217,12 @@ class LauncherView(QMainWindow): self.about.urlLabel.setText(appContext.buildInfo.git_repo_url) self.about.creditsText.setText("Xgui4") self.about.copyLabel.setText("Copyleft (C) GPLv3 Xgui4") - self.about.channelLabel.setText(f"**Channel** : {appContext.buildInfo.version_type}") + self.about.channelLabel.setText( + f"**Channel** : {appContext.buildInfo.version_type}" + ) self.about.platformLabel.setText(f"**Platform** : {platform.release()}") from lce_qt_launcher import license_str + self.about.licenseText.setMarkdown(license_str) self.about.aboutQt.clicked.connect(showAboutQtActionCommand) self.about.closeButton.clicked.connect(self.aboutDialog.close) @@ -235,10 +234,14 @@ class LauncherView(QMainWindow): systemManager: SystemManager = appContext.sys_man - self.dialog_ui.appVersionLabel.setText(f"**App Version** : {buildInfo.app_name} {buildInfo.version_type} {buildInfo.version}") + self.dialog_ui.appVersionLabel.setText( + f"**App Version** : {buildInfo.app_name} {buildInfo.version_type} {buildInfo.version}" + ) self.dialog_ui.qVersionLabel.setText(f"**Qt Version** : {qVersion()}") self.dialog_ui.pyVersionLabel.setText(f"**Python Version** : {sys.version}") - self.dialog_ui.osInfoLabel.setText(f"**System Name** : {systemManager.name} \n**System Version** : {systemManager.version}") + self.dialog_ui.osInfoLabel.setText( + f"**System Name** : {systemManager.name} \n**System Version** : {systemManager.version}" + ) self.dialog_ui.pluginsInfoLabel.setText("") self.dialog_ui.runnersLabel.setText("") @@ -252,44 +255,62 @@ class LauncherView(QMainWindow): self.ui.savetInstanceButton.clicked.connect(saveInstanceButtonCommand) self.ui.confirmChangesButton.clicked.connect(confirmChangesButtonCommand) self.ui.openInstanceEditor.clicked.connect(showInstanceEditorButtonCommand) - self.ui.changeInstanceIconButton.clicked.connect(changeInstanceIconButtonCommand) + self.ui.changeInstanceIconButton.clicked.connect( + changeInstanceIconButtonCommand + ) self.ui.actionSetting.triggered.connect(showSettingDialogCommand) self.ui.actionSetting_2.triggered.connect(showSettingDialogCommand) self.ui.actionSetting_3.triggered.connect(showSettingDialogCommand) self.ui.actionQuit.triggered.connect(app.quit) self.ui.actionUpdate.triggered.connect(updateActionCommand) - self.ui.actionSystem_Information.triggered.connect(showSystemInformationActionCommand) + self.ui.actionSystem_Information.triggered.connect( + showSystemInformationActionCommand + ) self.ui.actionAbout.triggered.connect(showAboutActionCommand) self.ui.actionAbout_QT.triggered.connect(showAboutQtActionCommand) self.ui.actionAbout_Minecraft.triggered.connect(showAboutMinecraftActionCommand) - self.ui.actionMore_Minecraft_LCE_Projects.triggered.connect(showMoreLCEProjectsActionCommand) + self.ui.actionMore_Minecraft_LCE_Projects.triggered.connect( + showMoreLCEProjectsActionCommand + ) self.ui.actionSave.triggered.connect(saveInstanceButtonCommand) self.ui.actionImport_Instance.triggered.connect(loadInstanceActionCommand) self.ui.actionInstall_Content.triggered.connect(installContentActionCommand) - loadSteam = lambda : subprocess.run(["steam", instanceManager.instance.steam_link]) + loadSteam = lambda: subprocess.run( + ["steam", instanceManager.instance.steam_link] + ) self.ui.playOnSteamButton.clicked.connect(loadSteam) - openAppInstancesData = lambda : systemManager.open_url_with_system(os.path.join(appData.appDataDirs[0], "instances")) + openAppInstancesData = lambda: systemManager.open_url_with_system( + os.path.join(appData.appDataDirs[0], "instances") + ) self.ui.actionInstances.triggered.connect(openAppInstancesData) - open_workshop = lambda : features.show_webbrowser(self, "https://lce-hub.github.io/piston/", buildInfo); + open_workshop = lambda: features.show_webbrowser( + self, "https://lce-hub.github.io/piston/", buildInfo + ) self.ui.actionLCE_Hub_Workshop.triggered.connect(open_workshop) - open_legacymods = lambda : features.show_webbrowser(self, "https://legacymods.org/", buildInfo); + open_legacymods = lambda: features.show_webbrowser( + self, "https://legacymods.org/", buildInfo + ) self.ui.actionLegacyMods_Coming_Soon.triggered.connect(open_legacymods) - openAppRoot = lambda : systemManager.open_url_with_system(appData.projectRootDir); + openAppRoot = lambda: systemManager.open_url_with_system(appData.projectRootDir) self.ui.actionApp_Root.triggered.connect(openAppRoot) - openAppConfig = lambda : systemManager.open_url_with_system(appData.appConfigDir); + openAppConfig = lambda: systemManager.open_url_with_system(appData.appConfigDir) self.ui.actionApp_Root.triggered.connect(openAppConfig) - open_github_issues = lambda : webbrowser.open(appContext.buildInfo.git_repo_url + "/issues") - self.ui.actionReport_a_Bugs_or_Sugess_a_feature.triggered.connect(open_github_issues) + open_github_issues = lambda: webbrowser.open( + appContext.buildInfo.git_repo_url + "/issues" + ) + self.ui.actionReport_a_Bugs_or_Sugess_a_feature.triggered.connect( + open_github_issues + ) - loadDefaultInstance = lambda : self.loadInstanceCommand(dict(), instanceManager) + loadDefaultInstance = lambda: self.loadInstanceCommand(dict(), instanceManager) self.ui.actionLoadDefaultInstance.triggered.connect(loadDefaultInstance) neoLegacyJson = QFile(":/instances/neoLegacy.lce_inst") @@ -297,27 +318,41 @@ class LauncherView(QMainWindow): term_service.print_error("Cannot found or open NeoLegacy Instance") self.ui.actionLoadNeoLegacyInstance.setEnabled(False) return None - else: - raw_text_neo = bytes(neoLegacyJson.readAll().data()).decode('utf-8') + else: + raw_text_neo = bytes(neoLegacyJson.readAll().data()).decode("utf-8") data_neo = json.loads(raw_text_neo) - loadNeoLegacyInstance = lambda : self.loadInstanceCommand(data_neo, instanceManager) + loadNeoLegacyInstance = lambda: self.loadInstanceCommand( + data_neo, instanceManager + ) self.ui.actionLoadNeoLegacyInstance.triggered.connect(loadNeoLegacyInstance) - self.ui.actionLoadHellishEndsInstance.setEnabled(False) # Due to dcma it is disabled - self.ui.actionLoadHellishEndsInstance.setText("HellishEnd (Disabled due to DMCA)") + self.ui.actionLoadHellishEndsInstance.setEnabled( + False + ) # Due to dcma it is disabled + self.ui.actionLoadHellishEndsInstance.setText( + "HellishEnd (Disabled due to DMCA)" + ) - self.ui.actionLoad360RevivedInstance.setEnabled(False) # Due to dcma it is disabled - self.ui.actionLoad360RevivedInstance.setText("360Revived (Disabled due to DMCA)") + self.ui.actionLoad360RevivedInstance.setEnabled( + False + ) # Due to dcma it is disabled + self.ui.actionLoad360RevivedInstance.setText( + "360Revived (Disabled due to DMCA)" + ) - self.ui.actionLoadRevelationsInstance.setEnabled(False) # Due to dcma it is disabled - self.ui.actionLoadRevelationsInstance.setText("Revelations (Disabled due to DMCA)") + self.ui.actionLoadRevelationsInstance.setEnabled( + False + ) # Due to dcma it is disabled + self.ui.actionLoadRevelationsInstance.setText( + "Revelations (Disabled due to DMCA)" + ) # hellishEndsJson = QFile(":/instances/hellishends.lce_inst") # if not hellishEndsJson.open(QIODevice.OpenModeFlag.ReadOnly): # term_service.print_error("Cannot found or open Helish Ends Instance") # self.ui.actionLoadHellishEndsInstance.setEnabled(False) # return None - # else: + # else: # raw_text_hellish_end = bytes(hellishEndsJson.readAll().data()).decode('utf-8') # data_hellish_end = json.loads(raw_text_hellish_end) # loadhellishEndsInstance = lambda : self.loadInstanceCommand(data_hellish_end, instanceManager) @@ -328,7 +363,7 @@ class LauncherView(QMainWindow): # term_service.print_error("Cannot found or open 360Revived Instance") # self.ui.actionLoad360RevivedInstance.setEnabled(False) # return None - # else: + # else: # raw_text_360 = bytes(i360RevivedJson.readAll().data()).decode('utf-8') # data_360 = json.loads(raw_text_360) # load360RevivedInstance = lambda : self.loadInstanceCommand(data_360, instanceManager) @@ -339,7 +374,7 @@ class LauncherView(QMainWindow): # term_service.print_error("Cannot found or open revelations Instance") # self.ui.actionLoadRevelationsInstance.setEnabled(False) # return None - # else: + # else: # raw_text_rev = bytes(revelationJson.readAll().data()).decode('utf-8') # data_rev = json.loads(raw_text_rev) # loadRevelationInstance = lambda : self.loadInstanceCommand(data_rev, instanceManager) @@ -350,25 +385,40 @@ class LauncherView(QMainWindow): term_service.print_error("Cannot found or open Aether Instance") self.ui.actionLoadAetherInstance.setEnabled(False) return None - else: - raw_text_aether = bytes(aetherJson.readAll().data()).decode('utf-8') + else: + raw_text_aether = bytes(aetherJson.readAll().data()).decode("utf-8") data_aether = json.loads(raw_text_aether) - loadAetherInstance = lambda : self.loadInstanceCommand(data_aether, instanceManager) + loadAetherInstance = lambda: self.loadInstanceCommand( + data_aether, instanceManager + ) self.ui.actionLoadAetherInstance.triggered.connect(loadAetherInstance) def addSteamLinkIntegrationButtonCommand(): steamIntegrationDialog = QInputDialog(self) - value = steamIntegrationDialog.getText(self, "Add Steam Integration", "steamid") + value = steamIntegrationDialog.getText( + self, "Add Steam Integration", "steamid" + ) if value[1] == True: self.ui.steamLinkValue.setText(value[0]) question = QMessageBox() - answer = question.question(self, "Add Instance to Steam Non-Steam Game Shortcuts ?", "Add ") + answer = question.question( + self, "Add Instance to Steam Non-Steam Game Shortcuts ?", "Add " + ) if answer == QMessageBox.StandardButton.Yes: - full_extention_path = os.path.join(instanceManager.instance.installation_path, instanceManager.instance.exe_name) - add_instance_to_steam(full_extention_path, instanceManager.instance.name, instanceManager.instance.image) + full_extention_path = os.path.join( + instanceManager.instance.installation_path, + instanceManager.instance.exe_name, + ) + add_instance_to_steam( + full_extention_path, + instanceManager.instance.name, + instanceManager.instance.image, + ) instanceManager.instance.steam_link = value[0] - self.ui.addSteamLinkIntegration.clicked.connect(addSteamLinkIntegrationButtonCommand) + self.ui.addSteamLinkIntegration.clicked.connect( + addSteamLinkIntegrationButtonCommand + ) self.ui.InstancesList.setEnabled(False) @@ -387,36 +437,41 @@ class LauncherView(QMainWindow): def setup_web_engine(self): # 1. Get the current active page page = self.ui.marketplacesWebsiteEngine.page() - + # 2. Extract and strictly bind the profile self.browser_profile = page.profile() - + # 3. Connect the signal self.browser_profile.downloadRequested.connect(self.handleDownloadCommand) - + def handleDownloadCommand(self, download: QWebEngineDownloadRequest): """Processes the PySide6 download stream request.""" print("Download Started!") - - path_str, _ = QFileDialog.getSaveFileName(None, "Save File", download.downloadFileName()) - + + path_str, _ = QFileDialog.getSaveFileName( + None, "Save File", download.downloadFileName() + ) + if path_str: save_path = Path(path_str) # Safely extract directory and filename regardless of OS (Windows/Mac/Linux) download.setDownloadDirectory(str(save_path.parent)) download.setDownloadFileName(save_path.name) - download.accept() + download.accept() else: download.cancel() - - def loadInstanceCommand(self, data : dict[str, str], instanceManager : InstanceManager, ) -> None: + def loadInstanceCommand( + self, + data: dict[str, str], + instanceManager: InstanceManager, + ) -> None: instance = Instance() instance.load_inst_from_dict(data) features.load_instance_from_instance(instanceManager, instance) self.loadInstanceInForm(instanceManager) - def loadInstanceInForm(self, instanceManager : InstanceManager): + def loadInstanceInForm(self, instanceManager: InstanceManager): self.ui.instanceNameInputBox.setText(instanceManager.instance.name) self.image_label = instanceManager.instance.image self.news_feed = instanceManager.instance.news_feed @@ -428,6 +483,6 @@ class LauncherView(QMainWindow): pixmap = QPixmap(self.image_label) self.ui.instance_img.setPixmap(pixmap) self.ui.repo_name_branch.setText(self.instance_name) - self.ui.newsEngineView.setUrl(self.news_feed) + self.ui.newsEngineView.setUrl(self.news_feed) if not instanceManager.is_installable(): - self.ui.installButton.setEnabled(False) \ No newline at end of file + self.ui.installButton.setEnabled(False) diff --git a/src/lce_qt_launcher/views/setting_dialog.py b/src/lce_qt_launcher/views/setting_dialog.py index a120aa4..29f23ff 100644 --- a/src/lce_qt_launcher/views/setting_dialog.py +++ b/src/lce_qt_launcher/views/setting_dialog.py @@ -1,16 +1,20 @@ from PySide6.QtWidgets import QDialog, QWidget, QMessageBox -from PySide6.QtCore import Qt +from PySide6.QtCore import Qt from lce_qt_launcher.app_context import AppContext import lce_qt_launcher.models.theme as theme from lce_qt_launcher.ui_settingDialog import Ui_settingDialog + class SettingDialog(QDialog): """_summary_ The Setting Dialog""" - def __init__(self, parent : QWidget, ui_setting : Ui_settingDialog, appContext : AppContext) -> None: + + def __init__( + self, parent: QWidget, ui_setting: Ui_settingDialog, appContext: AppContext + ) -> None: super().__init__() - self.setting_dialog: QDialog = QDialog(parent) - self.ui_setting: Ui_settingDialog = ui_setting + self.setting_dialog: QDialog = QDialog(parent) + self.ui_setting: Ui_settingDialog = ui_setting self.ui_setting.setupUi(self.setting_dialog) # pyright: ignore[reportUnknownMemberType] self.setting_dialog.show() self.appContext = appContext @@ -18,18 +22,28 @@ class SettingDialog(QDialog): self.ui_setting.settingsOptions.accepted.connect(self.applyButtonCommand) - comingSoonMsgBox = lambda : QMessageBox().information(self, "Setting", "Not Implemented Yet!") + comingSoonMsgBox = lambda: QMessageBox().information( + self, "Setting", "Not Implemented Yet!" + ) self.ui_setting.settingsOptions.helpRequested.connect(comingSoonMsgBox) - self.ui_setting.accesibilitycheckBox.setChecked(bool(self.userPref.get_accesible_mode())) - self.ui_setting.developperModeDheckBox.setChecked(bool(self.userPref.get_developper_mode())) - self.ui_setting.holydayDheckBox.setChecked(bool(self.userPref.get_show_holiday())) - self.ui_setting.enableExperimentscheckBox.setChecked(bool(self.userPref.get_experimental_mode())) - + self.ui_setting.accesibilitycheckBox.setChecked( + bool(self.userPref.get_accesible_mode()) + ) + self.ui_setting.developperModeDheckBox.setChecked( + bool(self.userPref.get_developper_mode()) + ) + self.ui_setting.holydayDheckBox.setChecked( + bool(self.userPref.get_show_holiday()) + ) + self.ui_setting.enableExperimentscheckBox.setChecked( + bool(self.userPref.get_experimental_mode()) + ) + self.ui_setting.languagesComboBox.setEditText(self.userPref.get_language_pref()) self.ui_setting.themesComboBox.setEditText(self.userPref.get_theme_pref()) - + def applyButtonCommand(self): isDevelopperModeEnabled = self.ui_setting.developperModeDheckBox.isChecked() isAccesbilityModeEnabled = self.ui_setting.accesibilitycheckBox.isChecked() @@ -42,8 +56,8 @@ class SettingDialog(QDialog): self.userPref.set_accesible_mode(isAccesbilityModeEnabled) self.userPref.set_developper_mode(isDevelopperModeEnabled) self.userPref.set_show_holiday(isHolidayEnabled) - self.userPref.set_theme_pref(str(theme.from_entity_to_strTheme(theme.ThemeEntity(themeSelectedIndex)))) + self.userPref.set_theme_pref( + str(theme.from_entity_to_strTheme(theme.ThemeEntity(themeSelectedIndex))) + ) self.userPref.set_language_pref(languageSelectedIndex) self.userPref.set_experimental_mode(isExperimentsOn) - - \ No newline at end of file diff --git a/src/lce_qt_launcher/views/term_service.py b/src/lce_qt_launcher/views/term_service.py index 782f92d..d508827 100644 --- a/src/lce_qt_launcher/views/term_service.py +++ b/src/lce_qt_launcher/views/term_service.py @@ -1,15 +1,17 @@ from rich import print -def print_error(msg : str, header : str = "Error! :") -> None: + +def print_error(msg: str, header: str = "Error! :") -> None: """_summary_ Print an pretty error msg Args: msg (str): _description_ : the error msg to show - header (_type_, optional): Defaults to "Error! :" _description_ The header to replace the default Error" + header (_type_, optional): Defaults to "Error! :" _description_ The header to replace the default Error" """ print(f"[bold red]{header}[/bold red] {msg}") -def print_warning(msg : str, header : str = "Warning! :") -> None: + +def print_warning(msg: str, header: str = "Warning! :") -> None: """_summary_ Print an pretty warning msg Args: @@ -18,7 +20,8 @@ def print_warning(msg : str, header : str = "Warning! :") -> None: """ print(f"[yellow bold]{header}[/yellow bold]{msg}") -def print_information(msg : str) -> None: + +def print_information(msg: str) -> None: """_summary_ Print a pretty an colorful msg Args: @@ -26,17 +29,19 @@ def print_information(msg : str) -> None: """ print(f"[yellow]{msg}[/yellow]") -def print_pretty(msg : str) -> None: + +def print_pretty(msg: str) -> None: """_summary_ Print a pretty msg , no default color Args: msg (str): _description_ : the mssage to show """ print(msg) -def print_success(msg : str) -> None: + +def print_success(msg: str) -> None: """_summary_ Print an success green msg Args: msg (str): _description_ the success msg to show """ - print(f"[green] {msg}") \ No newline at end of file + print(f"[green] {msg}")