import gradio as gr import subprocess import os import shutil import zipfile def build_minecraft_mod(zip_file): """ Автоматически собирает мод для Minecraft из zip-файла, используя Gradle. Args: zip_file: Объект Gradio File, представляющий загруженный zip-файл. Returns: (str, str): Кортеж, содержащий путь к собранному jar-файлу мода (или None, если сборка не удалась) и сообщения stdout и stderr процесса сборки. Если zip-файл невалидный, возвращается (None, "Invalid zip file or missing build.gradle"). """ try: # 1. Распаковка zip-файла во временную директорию temp_dir = "temp_mod_dir" if os.path.exists(temp_dir): shutil.rmtree(temp_dir) # Удаляем, если директория уже существует os.makedirs(temp_dir) with zipfile.ZipFile(zip_file.name, 'r') as zip_ref: zip_ref.extractall(temp_dir) # 2. Поиск build.gradle gradle_file_path = os.path.join(temp_dir, "build.gradle") gradlew_file_path = os.path.join(temp_dir, "gradlew") # Check for gradlew gradlew_bat_file_path = os.path.join(temp_dir, "gradlew.bat") #check for gradlew.bat (windows) if not os.path.exists(gradle_file_path): # Check for a subdirectory containing build.gradle found_gradle = False for root, _, files in os.walk(temp_dir): if "build.gradle" in files: gradle_file_path = os.path.join(root, "build.gradle") temp_dir = root # update temp_dir to be the directory with build.gradle! Very important. gradlew_file_path = os.path.join(temp_dir, "gradlew") gradlew_bat_file_path = os.path.join(temp_dir, "gradlew.bat") found_gradle = True break if not found_gradle: shutil.rmtree("temp_mod_dir") # Clean up return None, "Invalid zip file or missing build.gradle" # 3. Сборка мода с помощью Gradle if os.path.exists(gradlew_file_path): command = [gradlew_file_path, "build"] # Use gradlew elif os.path.exists(gradlew_bat_file_path): command = [gradlew_bat_file_path, "build"] # Use gradlew.bat (windows) else: command = ["gradle", "build"] # Use the system's gradle command process = subprocess.Popen(command, cwd=temp_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() stdout_str = stdout.decode("utf-8") stderr_str = stderr.decode("utf-8") # 4. Поиск собранного JAR файла build_libs_dir = os.path.join(temp_dir, "build", "libs") jar_file_path = None if os.path.exists(build_libs_dir): for filename in os.listdir(build_libs_dir): if filename.endswith(".jar") and not filename.endswith("-sources.jar") and not filename.endswith("-dev.jar"): #look for compiled jar not sources or dev jar_file_path = os.path.join(build_libs_dir, filename) break # 5. Clean up: remove temp dir shutil.rmtree("temp_mod_dir") return jar_file_path, stdout_str + "\n" + stderr_str except Exception as e: if os.path.exists("temp_mod_dir"): # Make sure to cleanup if any error occurred. shutil.rmtree("temp_mod_dir") return None, f"An error occurred: {e}" # Gradio Interface iface = gr.Interface( fn=build_minecraft_mod, inputs=gr.File(label="Upload Mod ZIP File"), outputs=[ gr.File(label="Built Mod JAR File"), gr.Textbox(label="Build Output", lines=10) ], title="Minecraft Mod Auto-Builder", description="Upload a zip file containing your Minecraft mod source code (with a build.gradle file), and this tool will automatically build it using Gradle.", ) iface.launch()