上传代码

This commit is contained in:
chentianrui
2025-09-08 17:58:02 +08:00
parent be848c3e78
commit f5f26c5cf8
76 changed files with 839039 additions and 2695 deletions
Binary file not shown.
+226 -26
View File
@@ -7,12 +7,22 @@ import json
import shutil
import threading
import atexit
import tempfile
# ==================== BCL 工具配置 ====================
# 相对于本脚本所在目录的 BwZipBCLTool.exe 路径(位于 `project2json/解压计算配置工具/` 下)
BCL_TOOL_RELATIVE_PATH = os.path.join(
os.path.dirname(__file__),
"解压计算配置工具",
"BwZipBCLTool.exe",
)
# ======================================================
# ==================== 配置区 ====================
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
@@ -81,37 +91,218 @@ def check_server_ready(timeout=30):
def convert_json_to_readable(input_file, output_file=None):
"""
将JSON文件转换为可读格式并保存
参数:
input_file: 输入JSON文件路径
output_file: 输出文件路径,如果为None则自动生成
升级版:支持编码检测和容错
"""
if output_file is None:
base_name = os.path.splitext(input_file)[0]
output_file = f"{base_name}_pretty.json"
# 确保输出目录存在
os.makedirs(os.path.dirname(output_file) if os.path.dirname(output_file) else ".", exist_ok=True)
encodings = ["utf-8", "gbk", "gb18030", "latin1"] # 常见编码
data = None
for enc in encodings:
try:
with open(input_file, "r", encoding=enc) as f:
data = json.load(f)
print(f"✔ 使用编码 {enc} 成功读取 {input_file}")
break
except UnicodeDecodeError:
continue
except Exception as e:
print(f"❌ 读取失败 {input_file}: {e}")
return None
if data is None:
print(f"❌ 所有编码尝试失败: {input_file}")
return 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}")
print(f"✅ 美化成功: {output_file}")
return output_file
except Exception as e:
print(f"转换JSON失败 {input_file}: {e}")
print(f"写入失败: {e}")
return None
def convert_project_to_json(input_folder, output_folder):
def _parse_version_key(name: str):
"""将形如 '1.20' 的版本字符串转换为可比较的元组。(主, 次, 补丁...)
非法格式将返回一个极小值以便被忽略。
"""
try:
parts = [int(p) for p in name.strip().split(".") if p.isdigit()]
if not parts:
return (-1,)
return tuple(parts)
except Exception:
return (-1,)
def _copy_dir_contents(src_dir: str, dst_dir: str):
"""将 src_dir 下的所有文件/子目录复制到 dst_dir(不包含 src_dir 这一层目录)。"""
os.makedirs(dst_dir, exist_ok=True)
for entry in os.listdir(src_dir):
s = os.path.join(src_dir, entry)
d = os.path.join(dst_dir, entry)
if os.path.isdir(s):
# 复制子目录
if os.path.exists(d):
shutil.rmtree(d)
shutil.copytree(s, d)
else:
shutil.copy2(s, d)
def run_bcl_tool_and_copy_best(
project_path: str,
final_copy_dir: str,
desktop_base: str = None,
exe_path: str = None,
exts: tuple[str, ...] | None = None,
cleanup_temp: bool = True,
):
"""
运行 BwZipBCLTool.exe 解析 BCL,并将临时输出目录下“版本号最大”的子文件夹内容复制到 final_copy_dir。
参数:
project_path: .zwqd 工程文件路径或包含该文件的目录
final_copy_dir: 版本号最大的文件夹内的所有文件复制到的最终目录
desktop_base: 临时输出目录所在的桌面路径,默认为当前用户桌面
exe_path: BwZipBCLTool.exe 的完整路径,默认使用 BCL_TOOL_RELATIVE_PATH
返回:
(bool, str): (是否成功, 最佳版本目录路径或错误信息)
"""
try:
exe_path = exe_path or BCL_TOOL_RELATIVE_PATH
if not os.path.exists(exe_path):
return False, f"未找到 BCL 工具: {exe_path}"
# 构建候选工程文件列表
# 默认:尝试目录内所有文件;若传入 exts,则只筛选指定后缀
candidates: list[str] = []
if os.path.isfile(project_path):
candidates = [project_path]
elif os.path.isdir(project_path):
names = sorted(os.listdir(project_path))
if exts:
lower_exts = tuple(e.lower() for e in exts)
candidates.extend([os.path.join(project_path, n) for n in names if n.lower().endswith(lower_exts)])
else:
candidates.extend(
[os.path.join(project_path, n) for n in names if os.path.isfile(os.path.join(project_path, n))]
)
else:
return False, f"路径不存在: {project_path}"
if not candidates:
return False, f"'{project_path}' 未找到可供解析的工程文件"
last_error = None
for eng_file in candidates:
# 临时目录放到桌面
if desktop_base is None:
desktop_base = os.path.join(os.path.expanduser("~"), "Desktop")
os.makedirs(desktop_base, exist_ok=True)
temp_out_dir = tempfile.mkdtemp(prefix="bcl_", dir=desktop_base)
print(f"🚀 调用 BCL 工具: {exe_path}")
print(f" ├─ 工程文件: {eng_file}")
print(f" └─ 临时输出: {temp_out_dir}")
try:
# 运行外部工具
result = subprocess.run(
[exe_path, eng_file, temp_out_dir],
capture_output=True,
text=True,
encoding="utf-8",
errors="replace",
shell=False,
)
if result.returncode != 0:
stderr = (result.stderr or "").strip()
stdout = (result.stdout or "").strip()
last_error = f"BCL 工具执行失败 (code={result.returncode})\nSTDOUT: {stdout}\nSTDERR: {stderr}"
continue
# 在临时目录下查找版本号子目录
subdirs = [d for d in os.listdir(temp_out_dir) if os.path.isdir(os.path.join(temp_out_dir, d))]
if not subdirs:
last_error = f"BCL 工具未在输出目录生成任何子目录: {temp_out_dir}"
continue
best_dir_name = max(subdirs, key=_parse_version_key)
best_dir_path = os.path.join(temp_out_dir, best_dir_name)
print(f"🏆 发现最佳版本目录: {best_dir_name}")
# 若下层只有单一子目录则继续下探;若存在多个子目录,且其名称像版本号(如 1.2.13),则选取版本号最大者继续下探
def _descend_if_single_subdir(path: str) -> str:
try:
while True:
entries = [os.path.join(path, e) for e in os.listdir(path)]
files = [p for p in entries if os.path.isfile(p)]
dirs = [p for p in entries if os.path.isdir(p)]
if files:
return path
if len(dirs) == 1:
path = dirs[0]
continue
if len(dirs) > 1:
# 如果多子目录都像版本号,则选择最大的版本继续下探
dir_names = [os.path.basename(d) for d in dirs]
def looks_like_version(name: str) -> bool:
parts = name.split(".")
if not parts:
return False
return all(p.isdigit() for p in parts)
version_like = [d for d, n in zip(dirs, dir_names) if looks_like_version(n)]
if version_like:
best_dir = max(version_like, key=lambda p: _parse_version_key(os.path.basename(p)))
path = best_dir
continue
# 否则停止下探,返回当前层
return path
return path
except Exception:
return path
copy_root = _descend_if_single_subdir(best_dir_path)
# 复制内容到最终目录
os.makedirs(final_copy_dir, exist_ok=True)
_copy_dir_contents(copy_root, final_copy_dir)
print(f"✅ 已将最佳版本目录内的文件复制到: {final_copy_dir}")
return True, copy_root
finally:
if cleanup_temp:
try:
shutil.rmtree(temp_out_dir, ignore_errors=True)
# print(f"🧹 已清理临时目录: {temp_out_dir}")
except Exception:
pass
# 所有候选均失败
return False, (last_error or "未找到可用的工程文件以执行 BCL 工具")
except Exception as e:
return False, f"运行 BCL 工具出错: {e}"
def convert_project_to_json(input_folder, output_folder, best_version_dest_folder=None):
"""
将工程文件夹转换为JSON,并移动到输出文件夹(含美化)
参数:
input_folder: 工程文件所在目录(包含 .zwzj 文件)
output_folder: 转换后的 JSON 文件输出目录
best_version_dest_folder: 若提供,则会在流程开始前运行 BCL 工具,并将最佳版本目录内容复制到该路径
返回:
tuple(bool, int): (是否成功, 成功转移并美化的文件数量)
@@ -147,13 +338,21 @@ def convert_project_to_json(input_folder, output_folder):
print(f"❌ 创建输出目录失败: {e}")
return False, 0
# 3. 启动 Java 服务
# 3. 若用户指定了 BCL 最终复制目录,则先进行 BCL 解析与复制
if best_version_dest_folder:
ok, info = run_bcl_tool_and_copy_best(input_folder, best_version_dest_folder)
if ok:
print(f"🧩 BCL 解析已完成,最佳版本输出目录: {info}")
else:
print(f"⚠️ BCL 解析步骤失败: {info}")
# 4. 启动 Java 服务
if not start_java_server():
return False, 0
if not check_server_ready():
return False, 0
# 4. 调用 API 开始分析
# 5. 调用 API 开始分析
params = {"filePath": input_folder.replace("\\", "/")}
print(f"🌐 调用 API: {SERVER_URL}?{requests.compat.urlencode(params)}")
@@ -171,10 +370,10 @@ def convert_project_to_json(input_folder, output_folder):
print(f"❌ 调用 API 出错: {e}")
return False, 0
# 5. 等待并检测 JSON 文件生成完成(改进版)
# 6. 等待并检测 JSON 文件生成完成(改进版)
print("⏳ 正在等待 JSON 文件生成完成...")
json_files = []
max_wait_time = 600
max_wait_time = 6000
check_interval = 2
start_time = time.time()
@@ -209,7 +408,7 @@ def convert_project_to_json(input_folder, output_folder):
print(f"❌ 在 {max_wait_time} 秒内未生成任何 JSON 文件。")
return False, 0
# 6. 查找所有 .json 文件
# 7. 查找所有 .json 文件
json_files = [f for f in os.listdir(input_folder) if f.endswith(".json")]
if not json_files:
print(f"❌ 未在 {input_folder} 中生成 JSON 文件。")
@@ -217,7 +416,7 @@ def convert_project_to_json(input_folder, output_folder):
print(f"📄 发现 {len(json_files)} 个 JSON 文件: {json_files}")
# 7. 转换为可读格式并移动到输出目录
# 8. 转换为可读格式并移动到输出目录
transferred_count = 0
for file_name in json_files:
src_path = os.path.join(input_folder, file_name)
@@ -255,10 +454,11 @@ atexit.register(cleanup)
# ==================== 使用示例 ====================
if __name__ == "__main__":
# 示例调用
input_dir = r"project2json/uploads"
output_dir = r"project2json/outputs/json"
input_dir = r"data/output/uploads"
output_dir = r"data/output/json"
best_bcl_dest = r"data/output/bcl"
success = convert_project_to_json(input_dir, output_dir)
success, _count = convert_project_to_json(input_dir, output_dir, best_bcl_dest)
if success:
print("\n🎉 ✅ 全部流程执行成功!")
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
BwZipBCLTool.exe C:\Users\Administrator\Downloads\变电检修国网\全口径-陆上电缆-国网2023规范.zwzj C:\Users\Administrator\Desktop
pause