From 770a865d4b5e84c68e13182d0161951471d24323 Mon Sep 17 00:00:00 2001 From: Kirill Volozhanin Date: Sat, 11 Nov 2023 23:20:07 +0500 Subject: [PATCH] CLI tools refactoring (#754) Hi. Beautified and optimized some stuff without changing any logic and functionality. --------- Co-authored-by: Project D.D Co-authored-by: Madis Otenurm --- CLI tools/CurseForge to MultiMC-Git.py | 33 +++-- CLI tools/CurseForge to Packwiz-Modrinth.py | 146 ++++++++++++-------- CLI tools/MultiMC to Git.py | 26 ++-- CLI tools/Update version.py | 8 +- 4 files changed, 127 insertions(+), 86 deletions(-) diff --git a/CLI tools/CurseForge to MultiMC-Git.py b/CLI tools/CurseForge to MultiMC-Git.py index 805573b9..90ce629a 100644 --- a/CLI tools/CurseForge to MultiMC-Git.py +++ b/CLI tools/CurseForge to MultiMC-Git.py @@ -2,15 +2,16 @@ import shutil from pathlib import Path -cf_path = Path(Path.home(), "curseforge/minecraft/Instances/Fabulously Optimized/") -mmc_path = Path(Path.home(), "Documents/MultiMC/instances/Fabulously Optimized/minecraft/") -git_path = Path(Path.home(), "Documents/GitHub/fabulously-optimized/") minecraft_version = "1.20.2" -packwiz_path = Path(git_path, "Packwiz", minecraft_version) +git_path = Path.home() / "Documents/GitHub/fabulously-optimized/" +packwiz_path = git_path / "Packwiz" / minecraft_version +cf_path = Path.home() / "curseforge/minecraft/Instances/Fabulously Optimized/" +mmc_path = Path.home() / "Documents/MultiMC/instances/Fabulously Optimized/minecraft/" def remove_dir(path: Path, description: str) -> None: if path.is_dir(): + print(f"Deleting {description}") shutil.rmtree(path) print(f"Deleted {description}") else: @@ -19,6 +20,7 @@ def remove_dir(path: Path, description: str) -> None: def remove_file(path: Path, description: str) -> None: if path.is_file(): + print(f"Deleting {description}") path.unlink() print(f"Deleted {description}") else: @@ -27,6 +29,7 @@ def remove_file(path: Path, description: str) -> None: def copy_dir(from_path: Path, to_path: Path, from_desc: str, to_desc: str) -> None: if from_path.is_dir(): + print(f"Copying {from_desc} to {to_desc}") shutil.copytree(from_path, to_path, dirs_exist_ok=True) print(f"Copied {from_desc} to {to_desc}") else: @@ -35,6 +38,7 @@ def copy_dir(from_path: Path, to_path: Path, from_desc: str, to_desc: str) -> No def copy_file(from_path: Path, to_path: Path, from_desc: str, to_desc: str) -> None: if from_path.is_file(): + print(f"Copying {from_desc} to {to_desc}") shutil.copy2(from_path, to_path) print(f"Copied {from_desc} to {to_desc}") else: @@ -42,16 +46,15 @@ def copy_file(from_path: Path, to_path: Path, from_desc: str, to_desc: str) -> N # CurseForge to MultiMC -remove_dir(Path(mmc_path, "mods"), "MultiMC mods") -remove_dir(Path(mmc_path, "config"), "MultiMC configs") -remove_dir(Path(mmc_path, "resourcepacks"), "MultiMC resourcepacks") -remove_file(Path(mmc_path, "options.txt"), "MultiMC options.txt") -copy_dir(Path(cf_path, "mods"), Path(mmc_path, "mods"), "CurseForge mods", "MultiMC") -copy_dir(Path(cf_path, "config"), Path(mmc_path, "config"), "CurseForge configs", "MultiMC") -copy_dir(Path(cf_path, "resourcepacks"), Path(mmc_path, "resourcepacks"), "CurseForge resource packs", "MultiMC") +remove_dir(mmc_path / "mods", "MultiMC mods") +remove_dir(mmc_path / "config", "MultiMC configs") +remove_dir(mmc_path / "resourcepacks", "MultiMC resourcepacks") +remove_file(mmc_path / "options.txt", "MultiMC options.txt") +copy_dir(cf_path / "mods", mmc_path / "mods", "CurseForge mods", "MultiMC") +copy_dir(cf_path / "config", mmc_path / "config", "CurseForge configs", "MultiMC") +copy_dir(cf_path / "resourcepacks", mmc_path / "resourcepacks", "CurseForge resource packs", "MultiMC") # CurseForge to Git -# Manifest and json copying moved to "CurseForge to Packwiz.py" to make sure they are always newest -remove_dir(Path(packwiz_path, "config"), "Packwiz configs in Git") -copy_dir(Path(cf_path, "config"), Path(packwiz_path, "config"), "CurseForge configs", "Git (Packwiz)") -copy_dir(Path(cf_path, "resourcepacks"), Path(packwiz_path, "resourcepacks"), "CurseForge resource packs", "Git (Packwiz)") +remove_dir(packwiz_path / "config", "Packwiz configs in Git") +copy_dir(cf_path / "config", packwiz_path / "config", "CurseForge configs", "Git (Packwiz)") +copy_dir(cf_path / "resourcepacks", packwiz_path / "resourcepacks", "CurseForge resource packs", "Git (Packwiz)") diff --git a/CLI tools/CurseForge to Packwiz-Modrinth.py b/CLI tools/CurseForge to Packwiz-Modrinth.py index b4aead52..112e1dd2 100644 --- a/CLI tools/CurseForge to Packwiz-Modrinth.py +++ b/CLI tools/CurseForge to Packwiz-Modrinth.py @@ -1,17 +1,19 @@ -from json import loads as parse_json -from zipfile import ZipFile -from io import BytesIO - import os -from shutil import unpack_archive +import json +import subprocess +from typing import IO from pathlib import Path -import toml # pip install toml +from zipfile import ZipFile +from shutil import unpack_archive + +import toml # pip install toml + user_path = os.path.expanduser("~") git_path = user_path + "\\Documents\\GitHub\\fabulously-optimized\\" minecraft_version = "1.20.2" packwiz_path = git_path + "Packwiz\\" + minecraft_version + "\\" -packwiz_exe_path = "..\packwiz.exe" +packwiz_exe_path = os.path.join("..", "packwiz.exe") mods_path = packwiz_path + "mods" packwiz_manifest = "pack.toml" @@ -26,16 +28,18 @@ mmc_export_packwiz_export = True mmc_export_modrinth_export = True packwiz_modrinth_export = False -def extract_file(from_zip, from_file, to_path, from_desc, to_desc): - with ZipFile(from_zip, 'r') as zip: - if from_file in zip.namelist(): - zip.extract(from_file, to_path) - print("Copied " + from_desc + " to " + to_desc) + +def extract_file(from_zip: str, from_file: str, to_path: str, from_desc: str, to_desc: str) -> None: + with ZipFile(from_zip, "r") as archive: + if from_file in archive.namelist(): + print(f"Copying {from_desc} to {to_desc}") + archive.extract(from_file, to_path) + print(f"Copied {from_desc} to {to_desc}") else: - print("Skipped " + from_desc + " copying to " + to_desc + ", didn't exist") + print(f"Skipped {from_desc} copying to {to_desc}, didn't exist") + def remove_from_archive(file_path: str, archive_path: str) -> None: - files = [] with ZipFile(archive_path) as archive: @@ -44,24 +48,24 @@ def remove_from_archive(file_path: str, archive_path: str) -> None: files.append((zipinfo.filename, archive.read(zipinfo.filename))) with ZipFile(archive_path, "w") as archive: - for filename, content in files: archive.writestr(filename, content) + for filename, content in files: + archive.writestr(filename, content) -def read_mod_meta(file_handle: BytesIO) -> dict: +def read_mod_meta(file_handle: IO[bytes]) -> dict: with ZipFile(file_handle) as archive: data = archive.read("fabric.mod.json") - return parse_json(data, strict=False) - + return json.loads(data, strict=False) + + def remove_mod_from_archive(mod_name: str, archive_path: str) -> None: - with ZipFile(archive_path) as archive: - for zipinfo in archive.infolist(): - name = zipinfo.filename - if not name.endswith(".jar"): continue - + if not name.endswith(".jar"): + continue + with archive.open(name) as mod_file: mod_meta = read_mod_meta(mod_file) @@ -69,19 +73,20 @@ def remove_mod_from_archive(mod_name: str, archive_path: str) -> None: remove_from_archive(name, archive_path) return -def main() -> int: +def main(): mod_files = os.listdir(mods_path) if not refresh_only: for item in mod_files: - os.remove( os.path.join(mods_path, item)) + os.remove(os.path.join(mods_path, item)) os.chdir(packwiz_path) if not refresh_only: - cf_zip_path = input("Please drag the CurseForge zip file here: ")[3:][:-1] # Because dragging the file adds "& " and double quotes + # Slicing, because dragging the file adds "& " and double quotes + cf_zip_path = input("Please drag the CurseForge zip file here: ")[3:][:-1] pack_version = "-".join(str(Path(cf_zip_path).with_suffix("")).split("-")[1:]) - if not mmc_export_packwiz_export and not refresh_only: + if not mmc_export_packwiz_export and not refresh_only: # Update pack.toml first with open(packwiz_manifest, "r") as f: pack_toml = toml.load(f) @@ -90,32 +95,41 @@ def main() -> int: toml.dump(pack_toml, f) # Packwiz import - os.system(packwiz_exe_path + " curseforge import \"" + cf_zip_path + "\"") + subprocess.call(f'{packwiz_exe_path} curseforge import "{cf_zip_path}"', shell=True) if hydrogen: - os.system(packwiz_exe_path + " remove hydrogen") - os.system(packwiz_exe_path + " mr install hydrogen") + os.system(f"{packwiz_exe_path} remove hydrogen") + os.system(f"{packwiz_exe_path} mr install hydrogen") if modrinth_overrides: - os.system(packwiz_exe_path + " remove entityculling") - os.system(packwiz_exe_path + " mr install entityculling") - - elif refresh_only: - os.system(packwiz_exe_path + " refresh") + os.system(f"{packwiz_exe_path} remove entityculling") + os.system(f"{packwiz_exe_path} mr install entityculling") + + elif refresh_only: + subprocess.call(f"{packwiz_exe_path} refresh", shell=True) # Copy fresh manifest/modlist to git if not is_legacy and not refresh_only: extract_file(cf_zip_path, "manifest.json", git_path + "CurseForge", "CurseForge manifest.json", "Git") extract_file(cf_zip_path, "modlist.html", git_path + "CurseForge", "CurseForge modlist.html", "Git") - # Export packwiz pack via mmc-export method + # Export Packwiz pack via mmc-export method if mmc_export_packwiz_export and not refresh_only: mmc_zip_root = str(Path(cf_zip_path).parents[0]) mmc_zip_path = mmc_zip_root + "\\Fabulously Optimized " + pack_version + ".zip" packwiz_config = git_path + "Packwiz\\mmc-export.toml" - cmd = f'mmc-export -i "{mmc_zip_path}" -f packwiz --modrinth-search loose -o "{mmc_zip_root}" -c "{packwiz_config}" -v {pack_version} --provider-priority Modrinth CurseForge Other --scheme mmc_export_packwiz_output' - os.system(cmd) + args = ( + "mmc-export", + "-i", mmc_zip_path, + "-f", "packwiz", + "--modrinth-search", "loose", + "-o", mmc_zip_root, + "-c", packwiz_config, + "-v", pack_version, + "--provider-priority", "Modrinth", "CurseForge", "Other", + "--scheme", "mmc_export_packwiz_output", + ); subprocess.call(args, shell=True) - packwiz_zip_path = Path(mmc_zip_root) / "mmc_export_packwiz_output.zip" + packwiz_zip_path = Path(mmc_zip_root) / "mmc_export_packwiz_output.zip" packwiz_out_path = Path(git_path) / "Packwiz" / minecraft_version packwiz_out_path.mkdir(parents=True, exist_ok=True) unpack_archive(packwiz_zip_path, packwiz_out_path) @@ -127,34 +141,54 @@ def main() -> int: mmc_zip_root = str(Path(cf_zip_path).parents[0]) mmc_zip_path = mmc_zip_root + "\\Fabulously Optimized " + pack_version + ".zip" modrinth_config = git_path + "Modrinth\\mmc-export.toml" + + args = ( + "mmc-export", + "-i", mmc_zip_path, + "-f", "Modrinth", + "--modrinth-search", "loose", + "-o", mmc_zip_root, + "-c", modrinth_config, + "-v", pack_version, + "--scheme", "{name}-{version}", + ); subprocess.call(args, shell=True) - cmd = f'mmc-export -i "{mmc_zip_path}" -f Modrinth --modrinth-search loose -o "{mmc_zip_root}" -c "{modrinth_config}" -v {pack_version} --scheme {"{name}-{version}"}' - os.system(cmd) + if not is_legacy: + extract_file( + mmc_zip_root + "\\Fabulously Optimized-" + pack_version + ".mrpack", + "modrinth.index.json", + git_path + "\\" + "Modrinth", + "Modrinth manifest", + "Git", + ) - if is_legacy == False: - extract_file(mmc_zip_root + "\\Fabulously Optimized-" + pack_version + ".mrpack", "modrinth.index.json", git_path + "\\" + "Modrinth", "Modrinth manifest", "Git") - - # Export Modrinth pack and manifest via packwiz method + # Export Modrinth pack and manifest via Packwiz method if packwiz_modrinth_export: - os.system(packwiz_exe_path + " modrinth export") + os.system(f"{packwiz_exe_path} modrinth export") for pack in os.listdir(packwiz_path): - if pack.endswith('.mrpack'): - if is_legacy == False: - extract_file(packwiz_path + "\\" + pack, "modrinth.index.json", git_path + "\\" + "Modrinth", "Modrinth manifest", "Git") + if pack.endswith(".mrpack"): + if not is_legacy: + extract_file( + packwiz_path + "\\" + pack, + "modrinth.index.json", + git_path + "\\" + "Modrinth", + "Modrinth manifest", + "Git", + ) os.replace(packwiz_path + "\\" + pack, os.path.expanduser("~/Desktop") + "\\" + pack) - print("Moved " + pack + " to desktop") - os.system(packwiz_exe_path + " refresh") - + print(f"Moved {pack} to desktop") + subprocess.call(f"{packwiz_exe_path} refresh", shell=True) + if not refresh_only: mmc_zip_root = str(Path(cf_zip_path).parents[0]) mmc_zip_path = mmc_zip_root + "\\Fabulously Optimized " + pack_version + ".zip" - #remove_mod_from_archive("Sodium", mmc_zip_path) - #remove_mod_from_archive("Iris", mmc_zip_path) + # remove_mod_from_archive("Sodium", mmc_zip_path) + # remove_mod_from_archive("Iris", mmc_zip_path) - return 0 if __name__ == "__main__": - try: main() + try: + main() except KeyboardInterrupt: print("Operation aborted by user.") exit(-1) diff --git a/CLI tools/MultiMC to Git.py b/CLI tools/MultiMC to Git.py index b912b91b..fc6351c2 100644 --- a/CLI tools/MultiMC to Git.py +++ b/CLI tools/MultiMC to Git.py @@ -3,13 +3,15 @@ import shutil import zipfile from pathlib import Path -mmc_path = Path(Path.home(), "Documents/MultiMC/instances/Fabulously Optimized/") -git_path = Path(Path.home(), "Documents/GitHub/fabulously-optimized/") -output_path = Path(Path.home(), "Desktop/") + +mmc_path = Path.home() / "Documents/MultiMC/instances/Fabulously Optimized/" +git_path = Path.home() / "Documents/GitHub/fabulously-optimized/" +output_path = Path.home() / "Desktop/" def copy_file(from_path: Path, to_path: Path, from_desc: str, to_desc: str) -> None: if from_path.is_file(): + print(f"Copying {from_desc} to {to_desc}") shutil.copy2(from_path, to_path) print(f"Copied {from_desc} to {to_desc}") else: @@ -34,30 +36,32 @@ def copy_to_archive(from_path: Path, to_path: str, archive_path: Path) -> None: version = "0.0.0" pattern = re.compile(r"\d+\.\d+\.\d+-?\w*\.?\d*") -with open(Path(mmc_path, "instance.cfg"), "r") as file: +with open(mmc_path / "instance.cfg", "r") as file: if match := pattern.search(file.read()): version = match.group() -with open(Path(git_path, "MultiMC/Fabulously Optimized x.y.z/instance.cfg"), "r+") as file: +with open(git_path / "MultiMC/Fabulously Optimized x.y.z/instance.cfg", "r+") as file: data = pattern.sub(version, file.read()) file.seek(0) file.truncate() file.write(data) copy_to_archive( - Path(git_path, "MultiMC/Fabulously Optimized x.y.z/instance.cfg"), + git_path / "MultiMC/Fabulously Optimized x.y.z/instance.cfg", f"Fabulously Optimized {version}/instance.cfg", - Path(output_path, f"Fabulously Optimized {version}.zip"), + output_path / f"Fabulously Optimized {version}.zip", ) + copy_file( - Path(mmc_path, "mmc-pack.json"), - Path(git_path, "MultiMC/Fabulously Optimized x.y.z/mmc-pack.json"), + mmc_path / "mmc-pack.json", + git_path / "MultiMC/Fabulously Optimized x.y.z/mmc-pack.json", "MultiMC mmc-pack.json", "Git", ) + copy_file( - Path(mmc_path, "pack.png"), - Path(git_path, "MultiMC/Fabulously Optimized x.y.z/pack.png"), + mmc_path / "pack.png", + git_path / "MultiMC/Fabulously Optimized x.y.z/pack.png", "MultiMC pack.png", "Git", ) diff --git a/CLI tools/Update version.py b/CLI tools/Update version.py index 7fb2b8ce..f73278ec 100644 --- a/CLI tools/Update version.py +++ b/CLI tools/Update version.py @@ -2,12 +2,12 @@ import json from pathlib import Path -cf_path = Path(Path.home(), "curseforge/minecraft/Instances/Fabulously Optimized/") -title_screen_path = Path(cf_path, "config/isxander-main-menu-credits.json") -warning_path = Path(cf_path, "config/fabric_loader_dependencies.json") +mmc_path = Path.home() / "curseforge/minecraft/Instances/Fabulously Optimized/" +title_screen_path = mmc_path / "config/isxander-main-menu-credits.json" +warning_path = mmc_path / "config/fabric_loader_dependencies.json" -def load_json(path: Path): +def load_json(path: Path) -> dict: with open(path, "r") as f: return json.load(f)