Handle UNC binary directories in AI structure flow
This commit is contained in:
@@ -62,37 +62,6 @@ async def html5_ai_structure_run(
|
||||
if should_save and save_credentials and username and password:
|
||||
save_credentials(project_id, {"username": username, "password": password, "domain": domain})
|
||||
|
||||
binary_source = _detect_binary_input(input_path)
|
||||
if binary_source is not None:
|
||||
if start_binary_job is None or save_run_state is None:
|
||||
return render_html5_ai_structure_error("Сервис подготовки CF/CFE через Windows Agent не подключен.")
|
||||
try:
|
||||
job = await start_binary_job(project_id=project_id, effective_project_id=effective_project_id, input_path=Path(input_path))
|
||||
except HTTPException as error:
|
||||
return render_html5_ai_structure_error(str(error.detail))
|
||||
save_run_state(
|
||||
job.job_id,
|
||||
{
|
||||
"project_id": project_id,
|
||||
"effective_project_id": effective_project_id,
|
||||
"input_path": input_path,
|
||||
"output_path": output_path,
|
||||
"username": username,
|
||||
"password": password,
|
||||
"domain": domain,
|
||||
"display_input_path": input_path,
|
||||
"display_output_path": output_path,
|
||||
},
|
||||
)
|
||||
return render_html5_ai_structure_job(
|
||||
project_id=project_id,
|
||||
job_id=job.job_id,
|
||||
status=_enum_text(job.status),
|
||||
source=_enum_text(job.source),
|
||||
message="Разбор CF/CFE запущен через Windows Agent",
|
||||
logs=getattr(job, "logs", []),
|
||||
)
|
||||
|
||||
work_dir = work_root / f"{effective_project_id}-{uuid4().hex}"
|
||||
try:
|
||||
work_dir.mkdir(parents=True, exist_ok=True)
|
||||
@@ -106,6 +75,41 @@ async def html5_ai_structure_run(
|
||||
password=password,
|
||||
domain=domain or None,
|
||||
)
|
||||
binary_match = _detect_binary_tree(local_input) or _normalize_binary_match(_detect_binary_input(input_path))
|
||||
if binary_match is not None:
|
||||
if start_binary_job is None or save_run_state is None:
|
||||
return render_html5_ai_structure_error("Сервис подготовки CF/CFE через Windows Agent не подключен.")
|
||||
try:
|
||||
job = await start_binary_job(
|
||||
project_id=project_id,
|
||||
effective_project_id=effective_project_id,
|
||||
input_path=input_path,
|
||||
detected_binary_relative_path=binary_match.get("relative_path"),
|
||||
)
|
||||
except HTTPException as error:
|
||||
return render_html5_ai_structure_error(str(error.detail))
|
||||
save_run_state(
|
||||
job.job_id,
|
||||
{
|
||||
"project_id": project_id,
|
||||
"effective_project_id": effective_project_id,
|
||||
"input_path": input_path,
|
||||
"output_path": output_path,
|
||||
"username": username,
|
||||
"password": password,
|
||||
"domain": domain,
|
||||
"display_input_path": input_path,
|
||||
"display_output_path": output_path,
|
||||
},
|
||||
)
|
||||
return render_html5_ai_structure_job(
|
||||
project_id=project_id,
|
||||
job_id=job.job_id,
|
||||
status=_enum_text(job.status),
|
||||
source=_enum_text(job.source),
|
||||
message="Разбор CF/CFE запущен через Windows Agent",
|
||||
logs=getattr(job, "logs", []),
|
||||
)
|
||||
result = prepare(
|
||||
project_id=effective_project_id,
|
||||
input_path=local_input,
|
||||
@@ -244,5 +248,30 @@ def _detect_binary_input(raw_input_path: str) -> str | None:
|
||||
return binary_files[0].suffix.casefold()
|
||||
|
||||
|
||||
def _detect_binary_tree(input_path: Path) -> dict[str, str] | None:
|
||||
if not input_path.exists():
|
||||
return None
|
||||
suffixes = {".cf", ".cfe"}
|
||||
if input_path.is_file() and input_path.suffix.casefold() in suffixes:
|
||||
return {"suffix": input_path.suffix.casefold(), "relative_path": input_path.name}
|
||||
if not input_path.is_dir():
|
||||
return None
|
||||
files = sorted(path for path in input_path.rglob("*") if path.is_file())
|
||||
parseable_files = any(path.suffix.casefold() in {".xml", ".mdo", ".bsl"} for path in files)
|
||||
binary_files = [path for path in files if path.suffix.casefold() in suffixes]
|
||||
if parseable_files or not binary_files:
|
||||
return None
|
||||
first = binary_files[0]
|
||||
return {"suffix": first.suffix.casefold(), "relative_path": first.relative_to(input_path).as_posix()}
|
||||
|
||||
|
||||
def _normalize_binary_match(value: str | dict[str, str] | None) -> dict[str, str] | None:
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, dict):
|
||||
return value
|
||||
return {"suffix": value, "relative_path": ""}
|
||||
|
||||
|
||||
def _enum_text(value: object) -> str:
|
||||
return str(getattr(value, "value", value or ""))
|
||||
|
||||
@@ -4,6 +4,7 @@ import asyncio
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import ntpath
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
@@ -581,9 +582,15 @@ def _agent_id_for_source(settings: "ProjectSettingsRequest", source: "ImportSour
|
||||
return str(agent.get("agent_id") or "").strip()
|
||||
|
||||
|
||||
async def _start_ai_structure_agent_job(*, project_id: str, effective_project_id: str, input_path: Path) -> AgentImportJob:
|
||||
async def _start_ai_structure_agent_job(
|
||||
*,
|
||||
project_id: str,
|
||||
effective_project_id: str,
|
||||
input_path: str,
|
||||
detected_binary_relative_path: str | None = None,
|
||||
) -> AgentImportJob:
|
||||
settings = _project_settings_or_404(project_id)
|
||||
binary_files = _ai_structure_binary_files(input_path)
|
||||
binary_files = _ai_structure_binary_files(input_path, detected_binary_relative_path=detected_binary_relative_path)
|
||||
if not binary_files:
|
||||
raise HTTPException(status_code=400, detail="Во входном пути не найдены файлы .cf или .cfe.")
|
||||
|
||||
@@ -641,7 +648,14 @@ async def _start_ai_structure_agent_job(*, project_id: str, effective_project_id
|
||||
)
|
||||
|
||||
|
||||
def _ai_structure_binary_files(input_path: Path) -> list[Path]:
|
||||
def _ai_structure_binary_files(raw_input_path: str, detected_binary_relative_path: str | None = None) -> list[Path]:
|
||||
lowered = raw_input_path.strip().casefold()
|
||||
if lowered.endswith(".cf") or lowered.endswith(".cfe"):
|
||||
return [Path(raw_input_path)]
|
||||
if detected_binary_relative_path:
|
||||
windows_path = ntpath.join(raw_input_path, detected_binary_relative_path.replace("/", "\\"))
|
||||
return [Path(windows_path)]
|
||||
input_path = Path(raw_input_path)
|
||||
if input_path.is_file() and input_path.suffix.casefold() in {".cf", ".cfe"}:
|
||||
return [input_path]
|
||||
if not input_path.exists() or not input_path.is_dir():
|
||||
|
||||
Reference in New Issue
Block a user