Skip to content

Commit

Permalink
Various fixes (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
boubou19 authored Dec 7, 2024
1 parent c0b51ed commit 76b3193
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 50 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ __pycache__/
updated_mods.json
releases/**/*.zip
releases/curse/
releases/technic/
.inplace_mod_exclusions
.inplace_pinned_mods
17 changes: 13 additions & 4 deletions src/gtnh/assembler/generic_assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,46 +121,55 @@ def get_mods(self, side: Side) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
mods: List[Tuple[GTNHModInfo, GTNHVersion]] = github_mods + external_mods
return mods

def external_mods(self, valid_sides: Set[Side]) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
def external_mods(
self, valid_sides: Set[Side], release: Optional[GTNHRelease] = None
) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
"""
Method to grab the external mod info objects as well as their targetted version.
:param valid_sides: a set of valid sides to retrieve the mods from.
:param release: if specified, the release version to get data from instead of the one used for the assembling.
"""
get_mod: Callable[
[str, ModVersionInfo, Set[Side], ModSource],
Optional[tuple[Union[GTNHModInfo], GTNHVersion]],
] = self.modpack_manager.assets.get_mod_and_version

release = self.release if release is None else release

external_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = list(
filter(
None,
[
get_mod(name, version, valid_sides, ModSource.other)
for name, version in self.release.external_mods.items()
for name, version in release.external_mods.items()
],
)
)

return external_mods

def github_mods(self, valid_sides: Set[Side]) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
def github_mods(
self, valid_sides: Set[Side], release: Optional[GTNHRelease] = None
) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
"""
Method to grab the github mod info objects as well as their targetted version.
:param valid_sides: a set of valid sides to retrieve the mods from.
:param release: if specified, the release version to get data from instead of the one used for the assembling.
"""
get_mod: Callable[
[str, ModVersionInfo, Set[Side], ModSource],
Optional[tuple[GTNHModInfo, GTNHVersion]],
] = self.modpack_manager.assets.get_mod_and_version
release = self.release if release is None else release

github_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = list(
filter(
None,
[
get_mod(name, version, valid_sides, ModSource.github)
for name, version in self.release.github_mods.items()
for name, version in release.github_mods.items()
],
)
)
Expand Down
109 changes: 88 additions & 21 deletions src/gtnh/assembler/technic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import re
import shutil
from enum import Enum
from pathlib import Path
from typing import Callable, List, Optional, Set, Tuple
from zipfile import ZIP_DEFLATED, ZipFile
Expand All @@ -20,6 +21,12 @@
log = get_logger("technic process")


class DifferentialUpdateMode(str, Enum):
NEW_MODS = "NEW_MODS"
UPDATED_MODS = "UPDATED_MODS"
REMOVED_MODS = "REMOVED_MODS"


def technify(string: str) -> str:
"""
format the given string to be only lower case letters or numbers or dashes.
Expand Down Expand Up @@ -76,56 +83,110 @@ async def partial_assemble(self, side: Side, verbose: bool = False) -> None:
if side not in {Side.CLIENT, Side.CLIENT_JAVA9}:
raise Exception(f"Can only assemble release for CLIENT or SERVER, not {side}")

archive_name: Path = self.get_partial_archive_path()
updated_mods_archive_name: Path = self.get_updated_mods_archive_path()
new_mods_archive_name: Path = self.get_new_mods_archive_path()
removed_modlist_name: Path = self.get_removed_modlist_path()

# deleting any existing archive
if os.path.exists(archive_name):
os.remove(archive_name)
log.warn(f"Previous archive {Fore.YELLOW}'{archive_name}'{Fore.RESET} deleted")
if os.path.exists(updated_mods_archive_name):
os.remove(updated_mods_archive_name)
log.warn(f"Previous archive {Fore.YELLOW}'{updated_mods_archive_name}'{Fore.RESET} deleted")

if os.path.exists(new_mods_archive_name):
os.remove(new_mods_archive_name)
log.warn(f"Previous archive {Fore.YELLOW}'{new_mods_archive_name}'{Fore.RESET} deleted")

log.info(f"Constructing {Fore.YELLOW}{side}{Fore.RESET} archive at {Fore.YELLOW}'{archive_name}'{Fore.RESET}")
if os.path.exists(removed_modlist_name):
os.remove(removed_modlist_name)
log.warn(f"Previous modlist {Fore.YELLOW}'{removed_modlist_name}'{Fore.RESET} deleted")

with ZipFile(archive_name, "w", compression=ZIP_DEFLATED) as archive:
log.info(
f"Constructing {Fore.YELLOW}{side}{Fore.RESET} archive at {Fore.YELLOW}'{updated_mods_archive_name}'{Fore.RESET}"
)

with ZipFile(updated_mods_archive_name, "w", compression=ZIP_DEFLATED) as archive:
log.info("Adding mods to the archive")
self.add_mods(side, self.partial_mods(side), archive, verbose=verbose)
self.add_mods(
side, self.differential_update(side, DifferentialUpdateMode.UPDATED_MODS), archive, verbose=verbose
)
log.info("Adding config to the archive")
self.add_config(side, self.get_config(), archive, verbose=verbose)
log.info("Generating the readme for the modpack repo")
self.generate_readme()
log.info("Archive created successfully!")

def partial_mods(self, side: Side) -> list[Tuple[GTNHModInfo, GTNHVersion]]:
log.info(
f"Constructing {Fore.YELLOW}{side}{Fore.RESET} archive at {Fore.YELLOW}'{new_mods_archive_name}'{Fore.RESET}"
)

with ZipFile(new_mods_archive_name, "w", compression=ZIP_DEFLATED) as archive:
log.info("Adding mods to the archive")
self.add_mods(
side, self.differential_update(side, DifferentialUpdateMode.NEW_MODS), archive, verbose=verbose
)
log.info("Archive created successfully!")

with open(removed_modlist_name, "w") as file:
log.info("generating removed modlist")
removed_modlist: List[tuple[GTNHModInfo, GTNHVersion]] = self.differential_update(
side, DifferentialUpdateMode.REMOVED_MODS
)
file.write("\n".join([f"{mod.name}: {version.version_tag}" for (mod, version) in removed_modlist]))
log.info("modlist created successfully!")

def differential_update(
self, side: Side, update_mode: DifferentialUpdateMode
) -> list[Tuple[GTNHModInfo, GTNHVersion]]:
update_source: Callable[[GTNHRelease, GTNHRelease], set[str]]

if update_mode == DifferentialUpdateMode.NEW_MODS:
update_source = self.modpack_manager.get_new_mods
elif update_mode == DifferentialUpdateMode.UPDATED_MODS:
update_source = self.modpack_manager.get_changed_mods
else:
update_source = self.modpack_manager.get_removed_mods

last_release: GTNHRelease = self.modpack_manager.get_release(self.release.last_version) # type: ignore
process_release: GTNHRelease = (
last_release if update_mode == DifferentialUpdateMode.REMOVED_MODS else self.release
)

valid_sides: Set[Side] = side.valid_mod_sides()
j9_sides: Set[Side] = {Side.CLIENT_JAVA9, Side.BOTH_JAVA9}

github_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.github_mods(valid_sides)
github_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.github_mods(valid_sides, release=process_release)
github_mods_names = [x[0].name for x in github_mods]
github_mods_j9: List[Tuple[GTNHModInfo, GTNHVersion]] = self.github_mods(j9_sides, release=process_release)
github_mods_names_j9 = [x[0].name for x in github_mods_j9]

external_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.external_mods(valid_sides)
external_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.external_mods(valid_sides, release=process_release)
external_mods_names = [x[0].name for x in external_mods]

last_version: GTNHRelease = self.modpack_manager.get_release(self.release.last_version) # type: ignore
external_mods_j9: List[Tuple[GTNHModInfo, GTNHVersion]] = self.external_mods(j9_sides, release=process_release)
external_mods_names_j9 = [x[0].name for x in external_mods_j9]

mods: List[Tuple[GTNHModInfo, GTNHVersion]] = []

for mod_name in self.modpack_manager.get_changed_mods(self.release, last_version):
for mod_name in update_source(self.release, last_release):
if mod_name in github_mods_names:
mod_index = github_mods_names.index(mod_name)
mods.append(github_mods[mod_index])
elif mod_name in external_mods_names:
mod_index = external_mods_names.index(mod_name)
mods.append(external_mods[mod_index])
else:
log.warn(
f"Mod {mod_name} was detected as an updated mod" ", but is not a github mod nor an external one"
)
if side == Side.CLIENT and (mod_name in github_mods_names_j9 or mod_name in external_mods_names_j9):
log.warn(f"Mod {mod_name} is a java 9+ mod but currently packing only java 8 mods. Skipping it.")
else:
log.warn(
f"Mod {mod_name} was detected as an updated mod" ", but is not a github mod nor an external one"
)

return mods

def add_mods(
self, side: Side, mods: list[tuple[GTNHModInfo, GTNHVersion]], archive: ZipFile, verbose: bool = False
) -> None:

temp_zip_path: Path = Path("./temp.zip")
temp_zip_path: Path = RELEASE_TECHNIC_DIR / "temp.zip"

for mod, version in mods:
source_file: Path = get_asset_version_cache_location(mod, version)
Expand All @@ -146,7 +207,7 @@ def add_mods(
)

# deleting temp zip
if temp_zip_path is not None:
if temp_zip_path.exists():
temp_zip_path.unlink()

def add_config(
Expand Down Expand Up @@ -204,8 +265,14 @@ def add_config(
def get_archive_path(self, side: Side) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(technic).zip"

def get_partial_archive_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(technic_partial).zip"
def get_updated_mods_archive_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(updated mods).zip"

def get_new_mods_archive_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(new mods).zip"

def get_removed_modlist_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(removed mods).txt"

async def assemble(self, side: Side, verbose: bool = False) -> None:
if side != Side.CLIENT:
Expand Down
66 changes: 65 additions & 1 deletion src/gtnh/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ def __init__(self, themed: bool = False) -> None:
client_modrinth=lambda: asyncio.ensure_future(self.assemble_release(Side.CLIENT, Archive.MODRINTH)),
client_technic=lambda: asyncio.ensure_future(self.assemble_release(Side.CLIENT, Archive.TECHNIC)),
update_all=lambda: asyncio.ensure_future(self.assemble_all()),
update_beta=lambda: asyncio.ensure_future(self.assemble_beta()),
generate_changelog=lambda: asyncio.ensure_future(self.generate_changelog()),
load=lambda release_name: asyncio.ensure_future(self.load_gtnh_version(release_name)),
delete=lambda release_name: asyncio.ensure_future(self.delete_gtnh_version(release_name)),
add=lambda release_name, previous_version: asyncio.ensure_future(
Expand Down Expand Up @@ -276,6 +278,33 @@ def toggle(self, widget: Any) -> None:
for child in widget.winfo_children():
self.toggle(child)

async def generate_changelog(self) -> None:
"""
Method used to trigger the assembling of the client archive corresponding to the provided source.
:return: None
"""
global_callback: Callable[
[float, str], None
] = self.modpack_list_frame.action_frame.progress_bar_global.add_progress

try:
self.set_progress(100 / 2)
self.trigger_toggle()
release_assembler: ReleaseAssembler = await self.pre_assembling()
release_assembler.generate_changelog()
global_callback(self.get_progress(), f"Generate changelog from {self.last_version} to {self.version}")
self.trigger_toggle()
except BaseException as e:
showerror(
"An error occured during the generation of the changelog",
f"An error occured during the generation of the changelog from {self.last_version} to {self.version}."
"\n Please check the logs for more information.",
)
if not self.toggled:
self.trigger_toggle()
raise e

async def assemble_release(self, side: Side, archive_type: Archive) -> None:
"""
Method used to trigger the assembling of the client archive corresponding to the provided source.
Expand Down Expand Up @@ -366,7 +395,7 @@ def add_error_message(self, error_message: str) -> None:

async def assemble_all(self) -> None:
"""
Assemble update_all the archives.
Assemble all the archives for a full update.
:return: None
"""
Expand Down Expand Up @@ -405,6 +434,41 @@ async def assemble_all(self) -> None:
self.trigger_toggle()
raise e

async def assemble_beta(self) -> None:
"""
Assemble all the archives for a beta/RC update.
:return: None
"""
try:
self.trigger_toggle()

self.set_progress(100 / (1 + 3 + 2)) # download + archives for client + archive for server
release_assembler: ReleaseAssembler = await self.pre_assembling()

release_assembler.set_progress(self.get_progress())

# zip archives
await self.assemble_release(Side.CLIENT, Archive.ZIP)
await self.assemble_release(Side.SERVER, Archive.ZIP)
await self.assemble_release(Side.SERVER_JAVA9, Archive.ZIP)

# MMC archives
await self.assemble_release(Side.CLIENT, Archive.MMC)
await self.assemble_release(Side.CLIENT_JAVA9, Archive.MMC)

self.trigger_toggle()

except BaseException as e:
showerror(
"An error occured during the update of the assembling of the archives",
"An error occurended during the update of the assembling of the archives."
"\n Please check the logs for more information",
)
if not self.toggled:
self.trigger_toggle()
raise e

def set_progress(self, delta_progress: float) -> None:
"""
Setter for self.delta_progress.
Expand Down
Loading

0 comments on commit 76b3193

Please sign in to comment.