""" 第一步:将工程文件转化为json文件 """ import os import shutil import subprocess import time import requests import urllib.parse import json import sys import threading import glob import atexit import tempfile import uuid # 全局变量,用于跟踪Java进程 java_process = None def convert_project_to_json(input_folder, output_folder): """ 将指定文件夹中的工程文件转换为JSON格式,并保存到输出文件夹 参数: input_folder: 输入文件夹路径,包含要转换的工程文件 output_folder: 输出文件夹路径,转换后的JSON文件将保存在这里 返回: 转换成功的文件列表,格式为 [(源文件路径, 生成的JSON文件路径), ...] """ # 确保输入和输出文件夹存在 if not os.path.exists(input_folder): print(f"错误:输入文件夹 {input_folder} 不存在") return [] os.makedirs(output_folder, exist_ok=True) # 启动Java服务 if not start_java_server(): print("错误:无法启动Java服务") return [] # 查找输入文件夹中的所有文件(不限制格式) project_files = [] for file in os.listdir(input_folder): file_path = os.path.join(input_folder, file) # 只处理文件,不处理文件夹 if os.path.isfile(file_path): project_files.append(file_path) if not project_files: print(f"警告:在文件夹 {input_folder} 中没有找到任何文件") return [] print(f"找到 {len(project_files)} 个文件: {[os.path.basename(f) for f in project_files]}") # 转换每个文件 successful_conversions = [] for file_path in project_files: print(f"正在处理文件: {file_path}") result_message, json_file_path = process_file(file_path, output_folder) if json_file_path: print(f"转换成功: {os.path.basename(file_path)} -> {os.path.basename(json_file_path)}") successful_conversions.append((file_path, json_file_path)) else: print(f"转换失败: {os.path.basename(file_path)} - {result_message}") # 返回转换结果 return successful_conversions def start_java_server(): """启动Java服务器,返回是否成功启动""" global java_process if java_process is not None: # 如果进程已存在,检查是否在运行 if java_process.poll() is None: # None表示进程仍在运行 return True # 使用相对路径 script_dir = os.path.dirname(os.path.abspath(__file__)) working_dir = os.path.join(script_dir, "analysis-server") # 确保工作目录存在 if not os.path.exists(working_dir): print(f"错误:工作目录不存在: {working_dir}") return False # 移除不必要的config目录创建 # config_dir = os.path.join(script_dir, "config") # if not os.path.exists(config_dir): # os.makedirs(config_dir, exist_ok=True) # print(f"创建配置目录: {config_dir}") try: # 使用与原始Java命令相同的方式启动 java_process = subprocess.Popen( ["java", "-Dfile.encoding=UTF-8", "-jar", "booway-analysis-server-null.jar"], # 使用相对路径 cwd=working_dir, # 在正确的工作目录中运行 stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1, encoding="utf-8", errors="replace", ) # 实时打印日志但不发送到前端 def read_output(stream, is_error=False): for line in iter(stream.readline, ""): stripped_line = line.strip() if stripped_line: print(stripped_line) t1 = threading.Thread(target=read_output, args=(java_process.stdout,), daemon=True) t2 = threading.Thread(target=read_output, args=(java_process.stderr, True), daemon=True) t1.start() t2.start() # 等待服务启动 print("等待Java服务启动...") time.sleep(20) # 等待20秒 return True except Exception as e: print(f"启动Java服务失败: {str(e)}") return False def process_file(file_path, output_folder): """处理单个工程文件,返回结果消息和JSON文件路径""" try: # 创建临时工作目录 temp_dir = tempfile.mkdtemp(prefix="project_converter_") print(f"创建临时工作目录: {temp_dir}") # 复制工程文件到临时目录 file_name = os.path.basename(file_path) temp_file_path = os.path.join(temp_dir, file_name) shutil.copy2(file_path, temp_file_path) print(f"复制文件到临时目录: {file_path} -> {temp_file_path}") try: # 调用Java服务处理文件 absolute_temp_dir = os.path.abspath(temp_dir).replace("\\", "/") encoded_temp_dir = urllib.parse.quote(absolute_temp_dir) url = f"http://localhost:8090/api/doAnalysis?filePath={encoded_temp_dir}" print("正在请求:", url) print(f"临时目录路径: {absolute_temp_dir}") print(f"文件名: {file_name}") # 记录转换前文件夹状态 before_files = set(os.listdir(temp_dir)) print(f"转换前临时目录内容: {before_files}") # 发送请求到Java服务 response = requests.get(url, timeout=180) print(f"API响应状态码: {response.status_code}") print(f"API响应内容: {response.text[:200]}...") # 等待一段时间,确保JSON文件已生成 time.sleep(10) # 等待10秒 # 记录转换后文件夹状态 after_files = set(os.listdir(temp_dir)) print(f"转换后临时目录内容: {after_files}") # 找出新增文件 new_files = after_files - before_files print(f"新增文件: {new_files}") # 查找生成的JSON文件 json_files = [f for f in new_files if f.endswith(".json")] if not json_files: # 如果没有找到新增的JSON文件,查找所有JSON文件 json_files = [f for f in after_files if f.endswith(".json")] if json_files: # 按修改时间排序,获取最新的 json_file = max(json_files, key=lambda f: os.path.getmtime(os.path.join(temp_dir, f))) temp_json_path = os.path.join(temp_dir, json_file) # 确保JSON文件是UTF-8编码 with open(temp_json_path, "r", encoding="utf-8") as f: data = json.load(f) # 生成输出文件名 base_name = os.path.splitext(file_name)[0] output_json_name = f"{base_name}.json" output_json_path = os.path.join(output_folder, output_json_name) # 检查是否已存在同名文件,如果存在,添加时间戳 if os.path.exists(output_json_path): timestamp = int(time.time()) output_json_name = f"{base_name}_{timestamp}.json" output_json_path = os.path.join(output_folder, output_json_name) # 将JSON数据写入输出文件 with open(output_json_path, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=4) print(f"JSON文件已保存到: {output_json_path}") return "✅ 工程文件转换成功!", output_json_path else: print("未能在临时目录中找到JSON文件,开始搜索其他可能的位置...") # 搜索多个可能的位置 search_locations = [ temp_dir, # 临时目录 os.path.join( os.path.dirname(os.path.abspath(__file__)), "analysis-server" ), # 相对路径的analysis-server os.getcwd(), # 当前工作目录 os.path.expanduser("~"), # 用户主目录 os.path.join(os.path.expanduser("~"), "Desktop"), # 桌面目录 os.path.join(os.path.expanduser("~"), "Documents"), # 文档目录 ] # 添加Java服务的工作目录 java_working_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "analysis-server") if os.path.exists(java_working_dir): search_locations.append(java_working_dir) # 搜索所有位置 found_json_files = [] for search_dir in search_locations: if os.path.exists(search_dir): print(f"搜索目录: {search_dir}") try: json_files_in_dir = [f for f in os.listdir(search_dir) if f.endswith(".json")] if json_files_in_dir: # 按修改时间排序,获取最新的 latest_json = max( json_files_in_dir, key=lambda f: os.path.getmtime(os.path.join(search_dir, f)) ) json_path = os.path.join(search_dir, latest_json) found_json_files.append((json_path, os.path.getmtime(json_path))) print(f"在 {search_dir} 中找到JSON文件: {latest_json}") except Exception as e: print(f"搜索目录 {search_dir} 时出错: {e}") if found_json_files: # 选择最新的JSON文件 latest_json_path, _ = max(found_json_files, key=lambda x: x[1]) # 生成输出文件名 base_name = os.path.splitext(file_name)[0] output_json_name = f"{base_name}.json" output_json_path = os.path.join(output_folder, output_json_name) # 检查是否已存在同名文件,如果存在,添加时间戳 if os.path.exists(output_json_path): timestamp = int(time.time()) output_json_name = f"{base_name}_{timestamp}.json" output_json_path = os.path.join(output_folder, output_json_name) # 读取JSON文件并保存到输出目录 with open(latest_json_path, "r", encoding="utf-8") as f: data = json.load(f) with open(output_json_path, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=4) print(f"从 {latest_json_path} 复制JSON文件到: {output_json_path}") return "✅ 工程文件转换成功!", output_json_path else: print("在所有搜索位置中都未找到JSON文件") return "❌ 转换可能已完成,但未能找到JSON文件。", None finally: # 清理临时目录 try: shutil.rmtree(temp_dir) print(f"已清理临时目录: {temp_dir}") except Exception as e: print(f"清理临时目录时出错: {str(e)}") except Exception as e: print(f"处理文件时发生错误: {str(e)}") return f"❌ 发生错误:{str(e)}", None def cleanup(): """清理资源,关闭Java进程""" global java_process if java_process is not None and java_process.poll() is None: java_process.terminate() print("已关闭Java服务") # 确保程序退出时关闭Java进程 atexit.register(cleanup) # if __name__ == "__main__": # # 使用示例 # input_folder = "project2json/uploads" # output_folder = "project2json/outputs/json" # print(f"当前工作目录: {os.getcwd()}") # # 检查输入文件夹是否存在 # if not os.path.exists(input_folder): # print(f"错误: 输入文件夹 '{input_folder}' 不存在") # # 尝试使用相对于脚本的路径 # script_dir = os.path.dirname(os.path.abspath(__file__)) # alternative_input = os.path.join(script_dir, "uploads") # print(f"尝试使用替代路径: {alternative_input}") # if os.path.exists(alternative_input): # input_folder = alternative_input # print(f"使用替代输入路径: {input_folder}") # # 同样调整输出文件夹 # output_folder = os.path.join(script_dir, "outputs") # print(f"使用替代输出路径: {output_folder}") # else: # print(f"错误: 替代输入路径 '{alternative_input}' 也不存在") # sys.exit(1) # # 确保输出文件夹存在 # os.makedirs(output_folder, exist_ok=True) # try: # print(f"输入文件夹: {input_folder}") # print(f"输出文件夹: {output_folder}") # # 列出输入文件夹中的文件 # print("输入文件夹内容:") # for file in os.listdir(input_folder): # print(f" - {file}") # # 使用正确的函数处理整个文件夹 # result = convert_project_to_json(input_folder, output_folder) # # 显示处理结果 # if result: # print("\n处理结果:") # for src, dst in result: # print(f" {os.path.basename(src)} -> {os.path.basename(dst)}") # print(f"\n成功转换 {len(result)} 个文件") # else: # print("\n没有文件被成功转换") # except Exception as e: # print(f"处理过程中发生错误: {str(e)}") # import traceback # traceback.print_exc()