import os import subprocess import time from gradio_client import file import requests import json import shutil import threading import atexit # ==================== 配置区 ==================== JAVA_WORKING_DIR = "D:/eclipseworkspace/bwyAnalysis2.3.2/analysis-server" JAR_NAME = "booway-analysis-server-null.jar" SERVER_URL = "http://localhost:8090/api/doAnalysis" # ============================================== # 全局变量:Java 进程 java_process = None def start_java_server(): """启动 Java 服务""" global java_process if java_process is not None and java_process.poll() is None: print("✅ Java 服务已在运行。") return True try: jar_path = os.path.join(JAVA_WORKING_DIR, JAR_NAME) if not os.path.exists(jar_path): print(f"❌ JAR 文件不存在: {jar_path}") return False if not os.path.exists(JAVA_WORKING_DIR): print(f"❌ Java 工作目录不存在: {JAVA_WORKING_DIR}") return False print(f"📁 启动 Java 服务: {jar_path}") cmd = ["java", "-Dfile.encoding=UTF-8", "-jar", JAR_NAME] java_process = subprocess.Popen( cmd, cwd=JAVA_WORKING_DIR, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8", errors="replace", ) def log_output(pipe, prefix): for line in iter(pipe.readline, ""): if line.strip(): print(f"{prefix}{line.strip()}") threading.Thread(target=log_output, args=(java_process.stdout, "【OUT】 "), daemon=True).start() threading.Thread(target=log_output, args=(java_process.stderr, "【ERR】 "), daemon=True).start() print("⏳ 等待服务启动(等待 20 秒)...") time.sleep(20) return True except Exception as e: print(f"❌ 启动 Java 服务失败: {e}") return False def check_server_ready(timeout=30): """检查服务是否可用""" print("🔍 检测服务是否就绪...") start_time = time.time() while time.time() - start_time < timeout: try: requests.get("http://localhost:8090/", timeout=3) print("✅ 服务已就绪!") return True except: time.sleep(1) print("❌ 服务启动超时。") return False def convert_json_to_readable(input_file, output_file=None): """ 将JSON文件转换为可读格式并保存 参数: input_file: 输入JSON文件路径 output_file: 输出文件路径,如果为None则自动生成 """ try: with open(input_file, "r", encoding="utf-8") as f: data = json.load(f) if output_file is None: base_name = os.path.splitext(input_file)[0] output_file = f"{base_name}.json" with open(output_file, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=4) print(f"✅ JSON美化成功: {output_file}") return output_file except Exception as e: print(f"❌ 转换JSON失败 {input_file}: {e}") return None def convert_project_to_json(input_folder, output_folder): """ 将工程文件夹转换为JSON,并移动到输出文件夹(含美化) 参数: input_folder: 工程文件所在目录(包含 .zwzj 文件) output_folder: 转换后的 JSON 文件输出目录 返回: tuple(bool, int): (是否成功, 成功转移并美化的文件数量) """ transferred_count = 0 # 记录成功转移的文件数 success = False # 整体是否成功 # --- 路径预处理 --- try: input_folder = os.path.abspath(input_folder) output_folder = os.path.abspath(output_folder) except Exception as e: print(f"❌ 路径解析失败: {e}") return False, 0 print(f"📁 输入工程目录: {input_folder}") print(f"📁 输出 JSON 目录: {output_folder}") # ----------------- # 1. 检查输入目录 if not os.path.exists(input_folder): print(f"❌ 输入目录不存在: {input_folder}") return False, 0 if not os.path.isdir(input_folder): print(f"❌ 输入路径不是目录: {input_folder}") return False, 0 # 2. 确保输出目录存在 try: os.makedirs(output_folder, exist_ok=True) output_folder = os.path.abspath(output_folder) except Exception as e: print(f"❌ 创建输出目录失败: {e}") return False, 0 # 3. 启动 Java 服务 if not start_java_server(): return False, 0 if not check_server_ready(): return False, 0 # 4. 调用 API 开始分析 params = {"filePath": input_folder.replace("\\", "/")} print(f"🌐 调用 API: {SERVER_URL}?{requests.compat.urlencode(params)}") try: response = requests.get(SERVER_URL, params=params, timeout=180) print(f"📡 响应状态码: {response.status_code}") if response.status_code != 200: print(f"❌ API 调用失败: {response.text}") return False, 0 result = response.json() if not result.get("success", False): print(f"❌ 服务返回失败: {result.get('msg', '未知错误')}") return False, 0 except Exception as e: print(f"❌ 调用 API 出错: {e}") return False, 0 # 5. 等待并检测 JSON 文件生成完成(改进版) print("⏳ 正在等待 JSON 文件生成完成...") json_files = [] max_wait_time = 600 check_interval = 2 start_time = time.time() while time.time() - start_time < max_wait_time: # 获取目录中的所有文件 all_files = os.listdir(input_folder) # 获取JSON文件列表 current_jsons = [f for f in all_files if f.endswith(".json")] # 获取非JSON文件列表 non_json_files = [f for f in all_files if not f.endswith(".json")] # 计算文件数量 json_count = len(current_jsons) non_json_count = len(non_json_files) print( f" ├─ 第 {int(time.time()-start_time)} 秒: 发现 {json_count} 个 JSON 文件, {non_json_count} 个非 JSON 文件" ) # 如果JSON文件和非JSON文件数量相等且都大于0,认为处理完成 if json_count > 0 and json_count == non_json_count: json_files = current_jsons print(f"✅ 文件生成完成,JSON文件和非JSON文件数量相等(各{json_count}个)。") break time.sleep(check_interval) else: json_files = [f for f in os.listdir(input_folder) if f.endswith(".json")] if json_files: print(f"⚠️ 警告:等待超时,但已发现 {len(json_files)} 个 JSON 文件,继续处理。") else: print(f"❌ 在 {max_wait_time} 秒内未生成任何 JSON 文件。") return False, 0 # 6. 查找所有 .json 文件 json_files = [f for f in os.listdir(input_folder) if f.endswith(".json")] if not json_files: print(f"❌ 未在 {input_folder} 中生成 JSON 文件。") return False, 0 print(f"📄 发现 {len(json_files)} 个 JSON 文件: {json_files}") # 7. 转换为可读格式并移动到输出目录 transferred_count = 0 for file_name in json_files: src_path = os.path.join(input_folder, file_name) readable_path = os.path.join(output_folder, f"{os.path.splitext(file_name)[0]}.json") if convert_json_to_readable(src_path, readable_path): transferred_count += 1 else: print(f"⚠️ 跳过文件: {file_name}") print(f"✅ 共转移并美化 {transferred_count}/{len(json_files)} 个 JSON 文件到: {output_folder}") # ✅ 返回成功状态和实际转移数量 success = True return success, transferred_count def cleanup(): """清理 Java 进程""" global java_process if java_process and java_process.poll() is None: print("\n🛑 正在关闭 Java 服务...") java_process.terminate() try: java_process.wait(timeout=5) except subprocess.TimeoutExpired: java_process.kill() print("✅ Java 服务已关闭。") # 注册退出钩子 atexit.register(cleanup) # ==================== 使用示例 ==================== if __name__ == "__main__": # 示例调用 input_dir = r"project2json/uploads" output_dir = r"project2json/outputs/json" success = convert_project_to_json(input_dir, output_dir) if success: print("\n🎉 ✅ 全部流程执行成功!") else: print("\n❌ 流程执行失败,请检查日志。") input("\n按回车键退出...")