mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-01 18:28:27 +02:00
added a 2nd progress bar
This commit is contained in:
parent
917f491ad1
commit
c0915ae13e
10 changed files with 118 additions and 100 deletions
|
@ -13,6 +13,7 @@ from source.gui import better_gui_error, mystuff, mod_settings
|
|||
from source.mkw.Game import Game
|
||||
from source.mkw.ModConfig import ModConfig
|
||||
from source.option import Option
|
||||
from source.progress import Progress
|
||||
from source.translation import translate as _
|
||||
from source import plugins
|
||||
from source import *
|
||||
|
@ -95,18 +96,23 @@ class Window(tkinter.Tk):
|
|||
for child in self.winfo_children():
|
||||
getattr(child, "set_state", lambda *_: "pass")(state)
|
||||
|
||||
def progress_function(self, func_gen: Generator) -> None:
|
||||
def progress_function(self, func_gen: Generator[Progress, None, None]) -> None:
|
||||
"""
|
||||
Run a generator function that yield status for the progress bar
|
||||
:return:
|
||||
"""
|
||||
# get the generator data yield by the generator function
|
||||
for step_data in func_gen:
|
||||
if "description" in step_data: self.progress_bar.set_description(step_data["description"])
|
||||
if "maximum" in step_data: self.progress_bar.set_maximum(step_data["maximum"])
|
||||
if "step" in step_data: self.progress_bar.step(step_data["step"])
|
||||
if "value" in step_data: self.progress_bar.set_value(step_data["value"])
|
||||
if "determinate" in step_data: self.progress_bar.set_determinate(step_data["determinate"])
|
||||
for progress in func_gen:
|
||||
if progress.title is not None: self.progress_bar.set_title(progress.title)
|
||||
if progress.part is not None: self.progress_bar.part(progress.part)
|
||||
if progress.set_part is not None: self.progress_bar.set_part(progress.set_part)
|
||||
if progress.max_part is not None: self.progress_bar.set_max_part(progress.max_part)
|
||||
|
||||
if progress.description is not None: self.progress_bar.set_description(progress.description)
|
||||
if progress.step is not None: self.progress_bar.step(progress.step)
|
||||
if progress.set_step is not None: self.progress_bar.set_step(progress.set_step)
|
||||
if progress.max_step is not None: self.progress_bar.set_max_step(progress.max_step)
|
||||
if progress.determinate is not None: self.progress_bar.set_determinate(progress.determinate)
|
||||
|
||||
def get_mod_config(self) -> ModConfig:
|
||||
"""
|
||||
|
@ -450,11 +456,17 @@ class ProgressBar(ttk.LabelFrame):
|
|||
# make the element fill the whole frame
|
||||
self.columnconfigure(1, weight=1)
|
||||
|
||||
self.progress_bar = ttk.Progressbar(self, orient="horizontal")
|
||||
self.progress_bar.grid(row=1, column=1, sticky="nsew")
|
||||
self.progress_bar_part = ttk.Progressbar(self, orient="horizontal")
|
||||
self.progress_bar_part.grid(row=1, column=1, sticky="nsew")
|
||||
|
||||
self.title = ttk.Label(self, text="", anchor="center", font=("TkDefaultFont", 10), wraplength=350)
|
||||
self.title.grid(row=2, column=1, sticky="nsew")
|
||||
|
||||
self.progress_bar_step = ttk.Progressbar(self, orient="horizontal")
|
||||
self.progress_bar_step.grid(row=3, column=1, sticky="nsew")
|
||||
|
||||
self.description = ttk.Label(self, text="", anchor="center", font=("TkDefaultFont", 10), wraplength=350)
|
||||
self.description.grid(row=2, column=1, sticky="nsew")
|
||||
self.description.grid(row=4, column=1, sticky="nsew")
|
||||
|
||||
def set_state(self, state: InstallerState) -> None:
|
||||
"""
|
||||
|
@ -466,37 +478,15 @@ class ProgressBar(ttk.LabelFrame):
|
|||
case InstallerState.IDLE: self.grid_remove()
|
||||
case InstallerState.INSTALLING: self.grid()
|
||||
|
||||
def set_description(self, desc: str) -> None:
|
||||
"""
|
||||
Set the progress bar description
|
||||
:param desc: description
|
||||
:return:
|
||||
"""
|
||||
self.description.config(text=desc)
|
||||
def set_title(self, title: str): self.title.config(text=title)
|
||||
def set_max_part(self, maximum: int): self.progress_bar_part.configure(maximum=maximum)
|
||||
def set_part(self, value: int): self.progress_bar_part.configure(value=value)
|
||||
def part(self, value: int = 1): self.progress_bar_part.step(value)
|
||||
|
||||
def set_maximum(self, maximum: int) -> None:
|
||||
"""
|
||||
Set the progress bar maximum value
|
||||
:param maximum: the maximum value
|
||||
:return:
|
||||
"""
|
||||
self.progress_bar.configure(maximum=maximum)
|
||||
|
||||
def set_value(self, value: int) -> None:
|
||||
"""
|
||||
Set the progress bar value
|
||||
:param value: the value
|
||||
:return:
|
||||
"""
|
||||
self.progress_bar.configure(value=value)
|
||||
|
||||
def step(self, value: int = 1) -> None:
|
||||
"""
|
||||
Set the progress bar by the value
|
||||
:param value: the step
|
||||
:return:
|
||||
"""
|
||||
self.progress_bar.step(value)
|
||||
def set_description(self, desc: str) -> None: self.description.config(text=desc)
|
||||
def set_max_step(self, maximum: int) -> None: self.progress_bar_step.configure(maximum=maximum)
|
||||
def set_step(self, value: int) -> None: self.progress_bar_step.configure(value=value)
|
||||
def step(self, value: int = 1) -> None: self.progress_bar_step.step(value)
|
||||
|
||||
def set_determinate(self, value: bool) -> None:
|
||||
"""
|
||||
|
|
|
@ -5,6 +5,7 @@ from typing import Generator, IO, TYPE_CHECKING
|
|||
|
||||
from source.mkw.ModConfig import ModConfig
|
||||
from source.mkw.Patch.Patch import Patch
|
||||
from source.progress import Progress
|
||||
from source.wt import szs, lec, wit
|
||||
from source.wt.wstrt import StrPath
|
||||
|
||||
|
@ -27,35 +28,35 @@ class ExtractedGame:
|
|||
self.original_game = original_game
|
||||
self._special_file: dict[str, IO] = {}
|
||||
|
||||
def extract_autoadd(self, destination_path: "Path | str") -> Generator[dict, None, None]:
|
||||
def extract_autoadd(self, destination_path: "Path | str") -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Extract all the autoadd files from the game to destination_path
|
||||
:param destination_path: directory where the autoadd files will be extracted
|
||||
"""
|
||||
yield {"description": "Extracting autoadd files...", "determinate": False}
|
||||
yield Progress(description="Extracting autoadd files...", determinate=False)
|
||||
szs.autoadd(self.path / "files/Race/Course/", destination_path)
|
||||
|
||||
def extract_original_tracks(self, destination_path: "Path | str") -> Generator[dict, None, None]:
|
||||
def extract_original_tracks(self, destination_path: "Path | str") -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Move all the original tracks to the destination path
|
||||
:param destination_path: destination of the track
|
||||
"""
|
||||
destination_path = Path(destination_path)
|
||||
destination_path.mkdir(parents=True, exist_ok=True)
|
||||
yield {"description": "Extracting original tracks...", "determinate": False}
|
||||
yield Progress(description="Extracting original tracks...", determinate=False)
|
||||
for track_file in (self.path / "files/Race/Course/").glob("*.szs"):
|
||||
yield {"description": f"Extracting original tracks ({track_file.name})...", "determinate": False}
|
||||
yield Progress(description=f"Extracting original tracks ({track_file.name})...", determinate=False)
|
||||
if not (destination_path / track_file.name).exists(): track_file.rename(destination_path / track_file.name)
|
||||
else: track_file.unlink()
|
||||
|
||||
def install_mystuff(self, mystuff_path: "Path | str") -> Generator[dict, None, None]:
|
||||
def install_mystuff(self, mystuff_path: "Path | str") -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Install mystuff directory. If any files of the game have the same name as a file at the root of the MyStuff
|
||||
Patch, then it is copied.
|
||||
:mystuff_path: path to the MyStuff directory
|
||||
:return:
|
||||
"""
|
||||
yield {"description": f"Installing MyStuff '{mystuff_path}'...", "determinate": False}
|
||||
yield Progress(description=f"Installing MyStuff '{mystuff_path}'...", determinate=False)
|
||||
mystuff_path = Path(mystuff_path)
|
||||
|
||||
mystuff_rootfiles: dict[str, Path] = {}
|
||||
|
@ -67,49 +68,49 @@ class ExtractedGame:
|
|||
if (mystuff_file := mystuff_rootfiles.get(game_file.name)) is None: continue
|
||||
shutil.copy(mystuff_file, game_file)
|
||||
|
||||
def install_multiple_mystuff(self, mystuff_paths: list["Path | str"]) -> Generator[dict, None, None]:
|
||||
def install_multiple_mystuff(self, mystuff_paths: list["Path | str"]) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Install multiple mystuff patch
|
||||
:param mystuff_paths: paths to all the mystuff patch
|
||||
"""
|
||||
yield {"description": "Installing all the mystuff patchs"}
|
||||
yield Progress(description="Installing all the mystuff patchs")
|
||||
|
||||
for mystuff_path in mystuff_paths:
|
||||
yield from self.install_mystuff(mystuff_path)
|
||||
|
||||
def prepare_special_file(self, mod_config: ModConfig) -> Generator[dict, None, None]:
|
||||
def prepare_special_file(self, mod_config: ModConfig) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Prepare special files for the patch
|
||||
:return: the special files dict
|
||||
"""
|
||||
yield {"description": "Preparing ct_icon special file...", "determinate": False}
|
||||
yield Progress(description="Preparing ct_icon special file...", determinate=False)
|
||||
ct_icons = BytesIO()
|
||||
mod_config.get_full_cticon().save(ct_icons, format="PNG")
|
||||
ct_icons.seek(0)
|
||||
self._special_file["ct_icons"] = ct_icons
|
||||
|
||||
def prepare_dol(self) -> Generator[dict, None, None]:
|
||||
def prepare_dol(self) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Prepare main.dol and StaticR.rel files (clean them and add lecode)
|
||||
"""
|
||||
yield {"description": "Preparing main.dol...", "determinate": False}
|
||||
yield Progress(description="Preparing main.dol...", determinate=False)
|
||||
StrPath(self.path / "sys/main.dol").patch(clean_dol=True, add_lecode=True)
|
||||
|
||||
def recreate_all_szs(self) -> Generator[dict, None, None]:
|
||||
def recreate_all_szs(self) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Repack all the .d directory into .szs files.
|
||||
"""
|
||||
yield {"description": f"Repacking all szs", "determinate": False}
|
||||
yield Progress(description=f"Repacking all szs", determinate=False)
|
||||
|
||||
for extracted_szs in filter(lambda path: path.is_dir(), self.path.rglob("*.d")):
|
||||
# for every directory that end with a .d in the extracted game, recreate the szs
|
||||
yield {"description": f"Repacking {extracted_szs} to szs", "determinate": False}
|
||||
yield Progress(description=f"Repacking {extracted_szs} to szs", determinate=False)
|
||||
|
||||
szs.create(extracted_szs, extracted_szs.with_suffix(".szs"), overwrite=True)
|
||||
shutil.rmtree(str(extracted_szs.resolve()))
|
||||
|
||||
def patch_lecode(self, mod_config: ModConfig, cache_directory: Path | str,
|
||||
cttracks_directory: Path | str, ogtracks_directory: Path | str) -> Generator[dict, None, None]:
|
||||
cttracks_directory: Path | str, ogtracks_directory: Path | str) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
install lecode on the mod
|
||||
:param cttracks_directory: directory to the customs tracks
|
||||
|
@ -117,7 +118,7 @@ class ExtractedGame:
|
|||
:param cache_directory: Path to the cache
|
||||
:param mod_config: mod configuration
|
||||
"""
|
||||
yield {"description": "Patching LECODE.bin"}
|
||||
yield Progress(description="Patching LECODE.bin")
|
||||
cache_directory = Path(cache_directory)
|
||||
cttracks_directory = Path(cttracks_directory)
|
||||
ogtracks_directory = Path(ogtracks_directory)
|
||||
|
@ -139,42 +140,44 @@ class ExtractedGame:
|
|||
copy_tracks_directories=[ogtracks_directory, cttracks_directory]
|
||||
)
|
||||
|
||||
def _install_all_patch(self, mod_config: ModConfig, patch_directory_name: str) -> Generator[dict, None, None]:
|
||||
def _install_all_patch(self, mod_config: ModConfig, patch_directory_name: str) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
for all directory that are in the root of the mod, and don't start with an underscore,
|
||||
for all the subdirectory named by the patch_directory_name, apply the patch
|
||||
:param mod_config: the mod to install
|
||||
"""
|
||||
yield {} # yield an empty dict so that if nothing is yielded by the Patch, still is considered a generator
|
||||
# yield an empty dict so that if nothing is yielded by the Patch, still is considered a generator
|
||||
yield Progress()
|
||||
|
||||
for part_directory in mod_config.get_mod_directory().glob("[!_]*"):
|
||||
for patch_directory in part_directory.glob(patch_directory_name):
|
||||
yield from Patch(patch_directory, mod_config, self._special_file).install(self)
|
||||
|
||||
def install_all_prepatch(self, mod_config: ModConfig) -> Generator[dict, None, None]:
|
||||
def install_all_prepatch(self, mod_config: ModConfig) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Install all patchs of the mod_config into the game.
|
||||
Used before the lecode patch is applied
|
||||
:param mod_config: the mod to install
|
||||
"""
|
||||
yield {"description": "Installing all Pre-Patch...", "determinate": False}
|
||||
yield Progress(description="Installing all Pre-Patch...", determinate=False)
|
||||
yield from self._install_all_patch(mod_config, "_PREPATCH/")
|
||||
|
||||
def install_all_patch(self, mod_config: ModConfig) -> Generator[dict, None, None]:
|
||||
def install_all_patch(self, mod_config: ModConfig) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Install all patchs of the mod_config into the game.
|
||||
Used after the lecode patch is applied
|
||||
:param mod_config: the mod to install
|
||||
"""
|
||||
yield {"description": "Installing all Patch...", "determinate": False}
|
||||
yield Progress(description="Installing all Patch...", determinate=False)
|
||||
yield from self._install_all_patch(mod_config, "_PATCH/")
|
||||
|
||||
def convert_to(self, output_type: wit.Extension) -> Generator[dict, None, wit.WITPath | None]:
|
||||
def convert_to(self, output_type: wit.Extension) -> Generator[Progress, None, wit.WITPath | None]:
|
||||
"""
|
||||
Convert the extracted game to another format
|
||||
:param output_type: path to the destination of the game
|
||||
:output_type: format of the destination game
|
||||
"""
|
||||
yield {"description": f"Converting game to {output_type}", "determinate": False}
|
||||
yield Progress(description=f"Converting game to {output_type}", determinate=False)
|
||||
if output_type == wit.Extension.FST: return
|
||||
|
||||
destination_file = self.path.with_suffix(self.path.suffix + output_type.value)
|
||||
|
@ -190,7 +193,7 @@ class ExtractedGame:
|
|||
destination_file=destination_file,
|
||||
)
|
||||
|
||||
yield {"description": "Deleting the extracted game...", "determinate": False}
|
||||
yield Progress(description="Deleting the extracted game...", determinate=False)
|
||||
shutil.rmtree(self.path)
|
||||
|
||||
return converted_game
|
||||
|
|
|
@ -4,6 +4,7 @@ from typing import Generator
|
|||
from source.mkw.ExtractedGame import ExtractedGame
|
||||
from source.mkw.ModConfig import ModConfig
|
||||
from source.option import Option
|
||||
from source.progress import Progress
|
||||
from source.wt.wit import WITPath, Region, Extension
|
||||
|
||||
|
||||
|
@ -37,7 +38,7 @@ class Game:
|
|||
"""
|
||||
return not any(self.wit_path[f"./files/rel/lecode-{region.value}.bin"].exists() for region in Region)
|
||||
|
||||
def extract(self, dest: "Path | str") -> Generator[dict, None, Path]:
|
||||
def extract(self, dest: "Path | str") -> Generator[Progress, None, Path]:
|
||||
"""
|
||||
Extract the game to the destination directory. If the game is a FST, just copy to the destination
|
||||
:param dest: destination directory
|
||||
|
@ -45,30 +46,25 @@ class Game:
|
|||
gen = self.wit_path.progress_extract_all(dest)
|
||||
|
||||
if self.wit_path.extension == Extension.FST:
|
||||
for gen_data in gen:
|
||||
yield {
|
||||
"description": "Copying Game...",
|
||||
"determinate": False
|
||||
}
|
||||
for _ in gen: yield Progress(description="Copying Game...", determinate=False)
|
||||
try: next(gen)
|
||||
except StopIteration as e:
|
||||
return e.value
|
||||
except StopIteration as e: return e.value
|
||||
|
||||
else:
|
||||
for gen_data in gen:
|
||||
yield {
|
||||
"description": f'Extracting - {gen_data["percentage"]}% - (estimated time remaining: '
|
||||
f'{gen_data["estimation"] if gen_data["estimation"] is not None else "-:--"})',
|
||||
"maximum": 100,
|
||||
"value": gen_data["percentage"],
|
||||
"determinate": True
|
||||
}
|
||||
yield Progress(
|
||||
description=f'Extracting - {gen_data["percentage"]}% - (estimated time remaining: '
|
||||
f'{gen_data["estimation"] if gen_data["estimation"] is not None else "-:--"})',
|
||||
max_step=100,
|
||||
set_step=gen_data["percentage"],
|
||||
determinate=True
|
||||
)
|
||||
try: next(gen)
|
||||
except StopIteration as e:
|
||||
return e.value
|
||||
|
||||
def edit(self, mod_config: ModConfig) -> Generator[dict, None, None]:
|
||||
yield {"description": "Changing game metadata...", "determinate": False}
|
||||
def edit(self, mod_config: ModConfig) -> Generator[Progress, None, None]:
|
||||
yield Progress(description="Changing game metadata...", determinate=False)
|
||||
self.wit_path.edit(
|
||||
name=mod_config.name,
|
||||
game_id=self.wit_path.id[:4] + mod_config.variant
|
||||
|
@ -96,7 +92,7 @@ class Game:
|
|||
return extracted_game
|
||||
|
||||
def install_mod(self, dest: Path, mod_config: ModConfig, options: "Option", output_type: Extension
|
||||
) -> Generator[dict, None, None]:
|
||||
) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Patch the game with the mod
|
||||
:dest: destination directory
|
||||
|
|
|
@ -13,6 +13,7 @@ from source.mkw.Track import CustomTrack, DefaultTrack, Arena
|
|||
import json
|
||||
|
||||
from source.mkw.OriginalTrack import OriginalTrack
|
||||
from source.progress import Progress
|
||||
from source.safe_eval import safe_eval, multiple_safe_eval
|
||||
from source.wt.szs import SZSPath
|
||||
|
||||
|
@ -404,7 +405,8 @@ class ModConfig:
|
|||
return full_cticon
|
||||
|
||||
def normalize_all_tracks(self, autoadd_path: "Path | str", destination_path: "Path | str",
|
||||
original_tracks_path: "Path | str", thread_amount: int = 8) -> Generator[dict, None, None]:
|
||||
original_tracks_path: "Path | str",
|
||||
thread_amount: int = 8) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Convert all tracks of the mod to szs into the destination_path
|
||||
:param original_tracks_path: path to the originals tracks (if a track is disabled for multiplayer)
|
||||
|
@ -412,21 +414,23 @@ class ModConfig:
|
|||
:param autoadd_path: autoadd directory
|
||||
:param destination_path: destination where the files are converted
|
||||
"""
|
||||
yield {"description": "Normalizing track..."}
|
||||
yield Progress(description="Normalizing track...")
|
||||
destination_path = Path(destination_path)
|
||||
original_tracks_path = Path(original_tracks_path)
|
||||
destination_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
normalize_threads: list[dict] = []
|
||||
|
||||
def remove_finished_threads() -> Generator[dict, None, None]:
|
||||
def remove_finished_threads() -> Generator[Progress, None, None]:
|
||||
"""
|
||||
Remove all the thread that stopped in a thread list
|
||||
:return: the list without the stopped thread
|
||||
"""
|
||||
nonlocal normalize_threads
|
||||
|
||||
yield {"description": f"Normalizing tracks :\n" + "\n".join(thread['name'] for thread in normalize_threads)}
|
||||
yield Progress(
|
||||
description=f"Normalizing tracks :\n" + "\n".join(thread['name'] for thread in normalize_threads)
|
||||
)
|
||||
normalize_threads = list(filter(lambda thread: thread["thread"].is_alive(), normalize_threads))
|
||||
|
||||
track_directory = self.path.parent / "_TRACKS"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from pathlib import Path
|
||||
from typing import Generator, IO, TYPE_CHECKING
|
||||
|
||||
from source.progress import Progress
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.mkw.ModConfig import ModConfig
|
||||
from source.mkw.ExtractedGame import ExtractedGame
|
||||
|
@ -19,13 +21,13 @@ class Patch:
|
|||
def __repr__(self) -> str:
|
||||
return f"<{self.__class__.__name__} {self.path}>"
|
||||
|
||||
def install(self, extracted_game: "ExtractedGame") -> Generator[dict, None, None]:
|
||||
def install(self, extracted_game: "ExtractedGame") -> Generator[Progress, None, None]:
|
||||
"""
|
||||
patch a game with this Patch
|
||||
:param extracted_game: the extracted game
|
||||
"""
|
||||
from source.mkw.Patch.PatchDirectory import PatchDirectory
|
||||
yield {"description": f"Installing the patch", "determinate": False}
|
||||
yield Progress(description=f"Installing the patch", determinate=False)
|
||||
|
||||
# take all the files in the root directory, and patch them into the game.
|
||||
# Patch is not directly applied to the root to avoid custom configuration
|
||||
|
|
|
@ -3,6 +3,7 @@ from typing import Generator, TYPE_CHECKING
|
|||
|
||||
from source.mkw.Patch import PathOutsidePatch, InvalidPatchMode
|
||||
from source.mkw.Patch.PatchObject import PatchObject
|
||||
from source.progress import Progress
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.mkw.ExtractedGame import ExtractedGame
|
||||
|
@ -22,11 +23,11 @@ class PatchDirectory(PatchObject):
|
|||
if subpath.suffix == ".json": continue
|
||||
yield self.subfile_from_path(subpath)
|
||||
|
||||
def install(self, extracted_game: "ExtractedGame", game_subpath: Path) -> Generator[dict, None, None]:
|
||||
def install(self, extracted_game: "ExtractedGame", game_subpath: Path) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
patch a subdirectory of the game with the PatchDirectory
|
||||
"""
|
||||
yield {"description": f"Patching {game_subpath}"}
|
||||
yield Progress(description=f"Patching {game_subpath}")
|
||||
|
||||
# check if the directory should be patched
|
||||
if not self.is_enabled(extracted_game): return
|
||||
|
|
|
@ -5,6 +5,7 @@ from typing import Generator, IO, TYPE_CHECKING
|
|||
from source.mkw.Patch import PathOutsidePatch, InvalidPatchMode, InvalidSourceMode
|
||||
from source.mkw.Patch.PatchOperation import AbstractPatchOperation
|
||||
from source.mkw.Patch.PatchObject import PatchObject
|
||||
from source.progress import Progress
|
||||
from source.wt.szs import SZSPath
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -76,11 +77,11 @@ class PatchFile(PatchObject):
|
|||
if not szs_path.exists() and szs_path.with_suffix(".szs").exists():
|
||||
SZSPath(szs_path.with_suffix(".szs")).extract_all(szs_path)
|
||||
|
||||
def install(self, extracted_game: "ExtractedGame", game_subpath: Path) -> Generator[dict, None, None]:
|
||||
def install(self, extracted_game: "ExtractedGame", game_subpath: Path) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
patch a subfile of the game with the PatchFile
|
||||
"""
|
||||
yield {"description": f"Patching {game_subpath}"}
|
||||
yield Progress(description=f"Patching {game_subpath}")
|
||||
|
||||
# check if the file should be patched
|
||||
if not self.is_enabled(extracted_game): return
|
||||
|
@ -118,7 +119,7 @@ class PatchFile(PatchObject):
|
|||
if not game_subfile.relative_to(extracted_game.path):
|
||||
raise PathOutsidePatch(game_subfile, extracted_game.path)
|
||||
|
||||
yield {"description": f"Patching {game_subfile}"}
|
||||
yield Progress(description=f"Patching {game_subfile}")
|
||||
|
||||
# if the source is the game, then recalculate the content for every game subfile
|
||||
if self.configuration["source"] == "game":
|
||||
|
|
|
@ -3,6 +3,8 @@ from abc import abstractmethod, ABC
|
|||
from pathlib import Path
|
||||
from typing import Generator, TYPE_CHECKING
|
||||
|
||||
from source.progress import Progress
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.mkw.Patch import Patch
|
||||
from source.mkw.ExtractedGame import ExtractedGame
|
||||
|
@ -64,7 +66,7 @@ class PatchObject(ABC):
|
|||
return obj(self.patch, str(path.relative_to(self.patch.path)))
|
||||
|
||||
@abstractmethod
|
||||
def install(self, extracted_game: "ExtractedGame", game_subpath: Path) -> Generator[dict, None, None]:
|
||||
def install(self, extracted_game: "ExtractedGame", game_subpath: Path) -> Generator[Progress, None, None]:
|
||||
"""
|
||||
install the PatchObject into the game
|
||||
yield the step of the process
|
||||
|
|
21
source/progress.py
Normal file
21
source/progress.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Progress:
|
||||
"""
|
||||
Represent the level of progression of the installer. Used for progress bar.
|
||||
"""
|
||||
|
||||
# this represents the first progress bar, showing every big part in the process
|
||||
title: str = None
|
||||
part: int = None
|
||||
set_part: int = None
|
||||
max_part: int = None
|
||||
|
||||
# this represents the second progress bar, showing every step of the current part of the process
|
||||
description: str = None
|
||||
step: int = None
|
||||
set_step: int = None
|
||||
max_step: int = None
|
||||
determinate: bool = None
|
|
@ -148,9 +148,7 @@ class WITPath:
|
|||
:return: the extracted file path
|
||||
"""
|
||||
if self.extension == Extension.FST:
|
||||
yield {
|
||||
"determinate": False
|
||||
}
|
||||
yield {}
|
||||
shutil.copytree(self._get_fst_root(), dest)
|
||||
|
||||
else:
|
||||
|
|
Loading…
Reference in a new issue