99 lines
3.1 KiB
Python
99 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from .manifest_inventory_service import manifest_inventory_service
|
|
from .result_catalog_service import result_catalog_service
|
|
from .task_service import task_service
|
|
|
|
|
|
def _dedupe_existing_dirs(paths: Optional[List[str]]) -> tuple[List[str], List[str]]:
|
|
normalized: List[str] = []
|
|
ignored: List[str] = []
|
|
for raw_path in paths or []:
|
|
path = os.path.normpath(os.path.abspath(str(raw_path or "").strip()))
|
|
if not path:
|
|
continue
|
|
if not os.path.isdir(path):
|
|
ignored.append(path)
|
|
continue
|
|
if path in normalized:
|
|
continue
|
|
normalized.append(path)
|
|
return normalized, ignored
|
|
|
|
|
|
class DinsarScanService:
|
|
async def _update_task(self, task_id: Optional[str], *, message: str, progress: int) -> None:
|
|
if not task_id:
|
|
return
|
|
await task_service.update_task(
|
|
task_id,
|
|
message=message,
|
|
progress=max(0, min(100, int(progress))),
|
|
)
|
|
|
|
async def run_scan(
|
|
self,
|
|
db: AsyncSession,
|
|
*,
|
|
source_directories: Optional[List[str]] = None,
|
|
publish_root: Optional[str] = None,
|
|
task_id: Optional[str] = None,
|
|
) -> Dict[str, Any]:
|
|
source_dirs, ignored_dirs = _dedupe_existing_dirs(source_directories)
|
|
|
|
publish_result = None
|
|
if source_dirs:
|
|
await self._update_task(
|
|
task_id,
|
|
message="正在将 D-InSAR 原始结果发布为 package...",
|
|
progress=20,
|
|
)
|
|
publish_result = await result_catalog_service.publish_from_sources(
|
|
db,
|
|
source_dirs,
|
|
publish_root=publish_root,
|
|
)
|
|
|
|
await self._update_task(
|
|
task_id,
|
|
message="正在同步 manifest inventory...",
|
|
progress=55,
|
|
)
|
|
inventory_result = await manifest_inventory_service.sync_manifest_roots(db)
|
|
|
|
await self._update_task(
|
|
task_id,
|
|
message="正在重建 D-InSAR catalog 与兼容视图...",
|
|
progress=75,
|
|
)
|
|
rebuild_result = await result_catalog_service.rebuild_catalog(
|
|
db,
|
|
publish_root=publish_root,
|
|
full_rebuild=True,
|
|
)
|
|
|
|
compat_result = rebuild_result.get("compat_sync")
|
|
compat_error = rebuild_result.get("compat_error")
|
|
return {
|
|
"source_directories": source_dirs,
|
|
"ignored_source_directories": ignored_dirs,
|
|
"publish": publish_result,
|
|
"manifest_inventory": inventory_result,
|
|
"rebuild": rebuild_result,
|
|
"compat_sync": compat_result,
|
|
"compat_error": compat_error,
|
|
"message": (
|
|
"D-InSAR unified scan completed"
|
|
if not compat_error
|
|
else f"D-InSAR unified scan completed with compat error: {compat_error}"
|
|
),
|
|
}
|
|
|
|
|
|
dinsar_scan_service = DinsarScanService()
|