diff --git a/poetry.lock b/poetry.lock index eaba6dc..d73c61c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -143,6 +143,20 @@ files = [ docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +[[package]] +name = "fire" +version = "0.5.0" +description = "A library for automatically generating command line interfaces." +optional = false +python-versions = "*" +files = [ + {file = "fire-0.5.0.tar.gz", hash = "sha256:a6b0d49e98c8963910021f92bba66f65ab440da2982b78eb1bbf95a0a34aacc6"}, +] + +[package.dependencies] +six = "*" +termcolor = "*" + [[package]] name = "identify" version = "2.5.24" @@ -358,6 +372,31 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "termcolor" +version = "2.3.0" +description = "ANSI color formatting for output in terminal" +optional = false +python-versions = ">=3.7" +files = [ + {file = "termcolor-2.3.0-py3-none-any.whl", hash = "sha256:3afb05607b89aed0ffe25202399ee0867ad4d3cb4180d98aaf8eefa6a5f7d475"}, + {file = "termcolor-2.3.0.tar.gz", hash = "sha256:b5b08f68937f138fe92f6c089b99f1e2da0ae56c52b78bf7075fd95420fd9a5a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + [[package]] name = "urllib3" version = "2.0.3" @@ -398,4 +437,4 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "7d2bf3678e910680af7a343064533ccd713d5583786eef1d7d8fa2d930da6128" +content-hash = "a96832cd8f35bc83d3041fd4ec46972877becf824e5a307207a48459260b5289" diff --git a/pyproject.toml b/pyproject.toml index 92b63d6..fc09431 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,10 @@ requests = "^2.31.0" pytest = "^7.3.1" pre-commit = "^3.3.3" + +[tool.poetry.group.cli.dependencies] +fire = "^0.5.0" + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/vollerei/__init__.py b/vollerei/__init__.py index e69de29..3dc1f76 100644 --- a/vollerei/__init__.py +++ b/vollerei/__init__.py @@ -0,0 +1 @@ +__version__ = "0.1.0" diff --git a/vollerei/__main__.py b/vollerei/__main__.py new file mode 100644 index 0000000..55470f3 --- /dev/null +++ b/vollerei/__main__.py @@ -0,0 +1,5 @@ +from vollerei.cli import CLI +from fire import Fire + + +Fire(CLI, name="vollerei") diff --git a/vollerei/cli/__init__.py b/vollerei/cli/__init__.py index 50c9110..b29ef2b 100644 --- a/vollerei/cli/__init__.py +++ b/vollerei/cli/__init__.py @@ -1,6 +1,22 @@ -from typing import Any +from pathlib import Path +from vollerei import __version__ +from vollerei.cli.hsr import HSR +from vollerei.hsr import PatchType class CLI: - def __init__(self): - pass + def __init__(self, game_path: str = None, patch_type=None) -> None: + """ + Vollerei CLI + """ + print(f"Vollerei v{__version__}") + if not game_path: + game_path = Path.cwd() + game_path = Path(game_path) + if patch_type is None: + patch_type = PatchType.Jadeite + elif isinstance(patch_type, str): + patch_type = PatchType[patch_type] + elif isinstance(patch_type, int): + patch_type = PatchType(patch_type) + self.hsr = HSR(game_path=game_path, patch_type=patch_type) diff --git a/vollerei/cli/hsr.py b/vollerei/cli/hsr.py new file mode 100644 index 0000000..3488b27 --- /dev/null +++ b/vollerei/cli/hsr.py @@ -0,0 +1,51 @@ +from traceback import print_exc +from vollerei.hsr import Game, Patcher +from vollerei.exceptions.patcher import PatcherError, PatchUpdateError +from vollerei.hsr.patcher import PatchType + + +class HSR: + def __init__( + self, game_path=None, patch_type: PatchType = PatchType.Jadeite + ) -> None: + self._game = Game(game_path) + print("Game directory:", self._game.path) + print("Game version:", self._game.get_version_str()) + self._patcher = Patcher() + self._patcher.patch_type = patch_type + + # Double _ means private to prevent Fire from invoking it + def patch_type(self): + print("Patch type:", self._patcher.patch_type.name) + + def __update_patch(self): + self.patch_type() + print("Updating patch...", end=" ") + try: + self._patcher.update_patch() + except PatchUpdateError as e: + print("FAILED") + print(f"Patch update failed with following error: {e} ({e.__context__})") + print_exc() + return False + print("OK") + return True + + def update_patch(self): + self.__update_patch() + + def patch(self): + if not self.__update_patch(): + return + try: + print("Patching game...", end=" ") + jadelte_dir = self._patcher.patch_game(game=self._game) + except PatcherError as e: + print("FAILED") + print(f"Patching failed with following error: {e}") + return + print("OK") + print("Jadelte executable is located at:", jadelte_dir.joinpath("jadelte.exe")) + print( + "Patching succeeded, but note that you need to run the game using Jadelte to use the patch." + )