Files

203 lines
6.1 KiB
Python

"""Import workflow functions extracted from envi_service.py."""
from __future__ import annotations
import os
from glob import glob
from typing import Any, Dict, List
from .envi_service import (
DEFAULT_TIMEOUT,
_collect_task_folders,
_find_meta_files,
_has_sml,
_to_local_path,
execute_envi_task,
)
def _import_single_dir(
display_name: str,
data_dir: str,
log_lines: List[str],
) -> tuple:
"""Import all .meta.xml in one directory. Returns (processed, failed, skipped)."""
import time
if _has_sml(data_dir):
log_lines.append(f"[skip] {display_name}: .sml already exists")
return 0, 0, 1
meta_files = _find_meta_files(data_dir)
if not meta_files:
log_lines.append(f"[skip] {display_name}: no *.meta.xml")
return 0, 0, 0
processed = 0
failed = 0
for meta_file in meta_files:
start = time.time()
try:
execute_envi_task(
"SARsImportLuTan1",
{
"INPUT_FILE_LIST": [meta_file],
"ROOT_URI_FOR_OUTPUT": data_dir,
},
)
elapsed = round(time.time() - start, 1)
processed += 1
log_lines.append(
f"[ok] import {display_name}: "
f"{os.path.basename(meta_file)} ({elapsed}s)"
)
except Exception as exc:
elapsed = round(time.time() - start, 1)
failed += 1
log_lines.append(
f"[err] import {display_name}: "
f"{os.path.basename(meta_file)} failed ({elapsed}s): {exc}"
)
return processed, failed, 0
def run_import_workflow(
root_dir: str,
num_to_process: int = 0,
timeout: int = DEFAULT_TIMEOUT,
) -> Dict[str, Any]:
"""Scan root_dir for raw SAR data and batch-import via SARsImportLuTan1."""
root_dir = _to_local_path(root_dir)
if not root_dir or not os.path.isdir(root_dir):
raise ValueError(f"Import root directory does not exist: {root_dir}")
task_folders = _collect_task_folders(root_dir)
scan_mode = "task_folder"
if not task_folders:
task_folders = sorted(
p for p in glob(os.path.join(root_dir, "*")) if os.path.isdir(p)
)
scan_mode = "flat_folder"
log_lines: List[str] = [
f"[envi] import task=SARsImportLuTan1",
f"[envi] root_dir={root_dir}",
f"[envi] scan_mode={scan_mode}",
f"[envi] found folders={len(task_folders)}",
]
if not task_folders:
return {
"summary": {
"scan_mode": scan_mode,
"task_folders": 0,
"processed": 0,
"failed": 0,
"skipped": 0,
},
"log_lines": log_lines,
}
total_processed = 0
total_failed = 0
total_skipped = 0
for folder in task_folders:
if num_to_process > 0 and total_processed >= num_to_process:
log_lines.append(f"[envi] reached limit={num_to_process}")
break
name = os.path.basename(folder)
if scan_mode == "flat_folder":
candidates = [(name, folder)]
else:
candidates = []
for side in ("master", "slave"):
d = os.path.join(folder, side)
if os.path.isdir(d):
candidates.append((f"{name}/{side}", d))
else:
log_lines.append(f"[warn] {name}/{side} missing, skip")
for display, data_dir in candidates:
if num_to_process > 0 and total_processed >= num_to_process:
break
p, f, s = _import_single_dir(display, data_dir, log_lines)
total_processed += p
total_failed += f
total_skipped += s
if total_failed > 0 and total_processed == 0:
detail = "\n".join(log_lines[-20:])
raise RuntimeError(
f"All import tasks failed. failed={total_failed}.\n{detail}"
)
return {
"summary": {
"scan_mode": scan_mode,
"task_folders": len(task_folders),
"processed": total_processed,
"failed": total_failed,
"skipped": total_skipped,
},
"log_lines": log_lines,
}
def inspect_import(root_dir: str) -> Dict[str, Any]:
"""Pre-check Import readiness for a root directory."""
root_dir = _to_local_path(root_dir)
result: Dict[str, Any] = {
"workflow": "import",
"root_dir": root_dir,
"exists": bool(root_dir and os.path.isdir(root_dir)),
"ready": False,
"summary": {},
"warnings": [],
}
if not result["exists"]:
result["warnings"].append("root_dir does not exist.")
return result
task_folders = _collect_task_folders(root_dir)
scan_mode = "task_folder"
scan_targets = task_folders
if not task_folders:
scan_mode = "flat_folder"
scan_targets = sorted(
p for p in glob(os.path.join(root_dir, "*")) if os.path.isdir(p)
)
meta_count = 0
sml_count = 0
candidate_count = 0
for folder in scan_targets:
if scan_mode == "flat_folder":
candidates = [folder]
else:
candidates = [
os.path.join(folder, "master"),
os.path.join(folder, "slave"),
]
for candidate in candidates:
if not os.path.isdir(candidate):
continue
metas = glob(os.path.join(candidate, "*.meta.xml"))
smls = glob(os.path.join(candidate, "*.sml"))
meta_count += len(metas)
sml_count += len(smls)
if metas and not smls:
candidate_count += len(metas)
result["summary"] = {
"scan_mode": scan_mode,
"folder_count": len(scan_targets),
"meta_file_count": meta_count,
"existing_sml_count": sml_count,
"import_candidate_count": candidate_count,
}
result["ready"] = candidate_count > 0
if candidate_count == 0:
result["warnings"].append(
"No import candidates (*.meta.xml without *.sml)."
)
return result