fabulously-optimized/CLI tools/CurseForge to Packwiz-Modrinth.py

195 lines
7.1 KiB
Python
Raw Normal View History

import os
import json
import subprocess
from typing import IO
from pathlib import Path
from zipfile import ZipFile
from shutil import unpack_archive
import toml # pip install toml
2022-01-07 18:08:00 +00:00
user_path = os.path.expanduser("~")
2022-06-03 16:00:34 +00:00
git_path = user_path + "\\Documents\\GitHub\\fabulously-optimized\\"
2024-04-24 17:47:24 +00:00
minecraft_version = "1.20.5"
2022-06-03 16:00:34 +00:00
packwiz_path = git_path + "Packwiz\\" + minecraft_version + "\\"
packwiz_exe_path = os.path.join("..", "packwiz.exe")
2022-01-07 18:08:00 +00:00
mods_path = packwiz_path + "mods"
packwiz_manifest = "pack.toml"
2022-01-07 18:08:00 +00:00
2022-06-03 16:00:34 +00:00
cf_zip_path = ""
pack_version = ""
2022-06-03 16:11:56 +00:00
refresh_only = False
2022-01-19 16:12:02 +00:00
is_legacy = False
2022-03-14 16:26:33 +00:00
hydrogen = False
2022-05-23 16:11:34 +00:00
modrinth_overrides = True
mmc_export_packwiz_export = True
2022-06-03 16:00:34 +00:00
mmc_export_modrinth_export = True
packwiz_modrinth_export = False
2022-01-07 18:08:00 +00:00
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}")
2022-01-07 18:08:00 +00:00
else:
print(f"Skipped {from_desc} copying to {to_desc}, didn't exist")
2022-01-07 18:08:00 +00:00
def remove_from_archive(file_path: str, archive_path: str) -> None:
files = []
with ZipFile(archive_path) as archive:
for zipinfo in archive.infolist():
if zipinfo.filename != file_path:
files.append((zipinfo.filename, archive.read(zipinfo.filename)))
with ZipFile(archive_path, "w") as archive:
for filename, content in files:
archive.writestr(filename, content)
def read_mod_meta(file_handle: IO[bytes]) -> dict:
with ZipFile(file_handle) as archive:
data = archive.read("fabric.mod.json")
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
with archive.open(name) as mod_file:
mod_meta = read_mod_meta(mod_file)
if mod_meta["name"] == mod_name:
remove_from_archive(name, archive_path)
return
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.chdir(packwiz_path)
if not refresh_only:
# 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:
# Update pack.toml first
with open(packwiz_manifest, "r") as f:
pack_toml = toml.load(f)
pack_toml["version"] = pack_version
with open(packwiz_manifest, "w") as f:
toml.dump(pack_toml, f)
# Packwiz import
subprocess.call(f'{packwiz_exe_path} curseforge import "{cf_zip_path}"', shell=True)
if hydrogen:
os.system(f"{packwiz_exe_path} remove hydrogen")
os.system(f"{packwiz_exe_path} mr install hydrogen")
if modrinth_overrides:
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
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"
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_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)
os.remove(packwiz_zip_path)
# Export Modrinth pack and manifest via mmc-export method
if mmc_export_modrinth_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"
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)
if not is_legacy:
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
if packwiz_modrinth_export:
os.system(f"{packwiz_exe_path} modrinth export")
for pack in os.listdir(packwiz_path):
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(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"
2023-12-07 16:53:41 +00:00
#remove_mod_from_archive("Sodium", mmc_zip_path)
#remove_mod_from_archive("Iris", mmc_zip_path)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("Operation aborted by user.")
exit(-1)