Add Sentinel-1 asset management and PyINT pipeline support

This commit is contained in:
2026-05-14 03:02:56 +08:00
parent 508ca5641a
commit 729c5c2a7f
61 changed files with 7800 additions and 885 deletions
+98 -1
View File
@@ -10,7 +10,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from .. import database
from ..config import settings, split_env_paths
from ..models import ManagedRootORM, PathInventoryORM, ScanCursorORM
from ..models import AssetInventoryStateORM, ManagedRootORM, PathInventoryORM, ScanCursorORM
_SLUG_RE = re.compile(r"[^a-z0-9]+")
@@ -87,6 +87,15 @@ def _cursor_type_for_scan_mode(scan_mode: str) -> str:
return mapping.get(str(scan_mode or "").strip().lower(), "directory_walk")
def _asset_inventory_type_for_root_role(root_role: str) -> Optional[str]:
role = str(root_role or "").strip().lower()
if role == "source_product_pool":
return "source_product"
if role == "orbit_asset_pool":
return "orbit_asset"
return None
def _iter_multi_root_specs(
*,
env_var: str,
@@ -169,6 +178,36 @@ def _build_root_specs_from_settings() -> List[RootSpec]:
scan_mode="archive_walk",
)
)
source_product_paths = split_env_paths(settings.SOURCE_PRODUCT_DIRS)
if not source_product_paths:
source_product_paths = (
split_env_paths(settings.INSAR_STORAGE_DIRS)
+ split_env_paths(settings.MONITOR_RADAR_DIRS)
)
specs.extend(
_iter_multi_root_specs(
env_var="SOURCE_PRODUCT_DIRS",
paths=source_product_paths,
root_role="source_product_pool",
display_prefix="Source Product Pool",
scan_mode="file_pool",
)
)
source_product_path_set = {_normalize_root_path(path) for path in source_product_paths}
sentinel1_storage_paths = [
path
for path in split_env_paths(settings.SENTINEL1_STORAGE_DIRS)
if _normalize_root_path(path) not in source_product_path_set
]
specs.extend(
_iter_multi_root_specs(
env_var="SENTINEL1_STORAGE_DIRS",
paths=sentinel1_storage_paths,
root_role="source_product_pool",
display_prefix="Sentinel-1 Storage Pool",
scan_mode="file_pool",
)
)
specs.extend(
_iter_multi_root_specs(
env_var="INSAR_STORAGE_DIRS",
@@ -214,6 +253,18 @@ def _build_root_specs_from_settings() -> List[RootSpec]:
scan_mode="scene_directory",
)
)
orbit_source_paths = split_env_paths(settings.ORBIT_SOURCE_DIRS)
if not orbit_source_paths:
orbit_source_paths = split_env_paths(settings.MONITOR_ORBIT_DIR)
specs.extend(
_iter_multi_root_specs(
env_var="ORBIT_SOURCE_DIRS",
paths=orbit_source_paths,
root_role="orbit_asset_pool",
display_prefix="Orbit Asset Pool",
scan_mode="file_pool",
)
)
specs.extend(
_iter_single_root_specs(
env_var="MONITOR_ORBIT_DIR",
@@ -374,6 +425,43 @@ class RootRegistryService:
changed = True
return "updated" if changed else None
async def _ensure_asset_inventory_state(self, db: AsyncSession, root: ManagedRootORM) -> Optional[str]:
inventory_type = _asset_inventory_type_for_root_role(root.root_role)
if not inventory_type:
return None
result = await db.execute(
select(AssetInventoryStateORM).where(
AssetInventoryStateORM.root_ref_id == root.id,
AssetInventoryStateORM.inventory_type == inventory_type,
)
)
state = result.scalar_one_or_none()
if state is None:
state = AssetInventoryStateORM(
root_ref_id=root.id,
inventory_type=inventory_type,
root_path=root.path,
scan_mode=root.scan_mode,
status="NEVER_SCANNED",
needs_rescan=True,
metadata_json={
"root_role": root.root_role,
"created_by": "root_registry_sync",
},
)
db.add(state)
return "created"
changed = False
if state.root_path != root.path:
state.root_path = root.path
changed = True
if state.scan_mode != root.scan_mode:
state.scan_mode = root.scan_mode
changed = True
return "updated" if changed else None
async def sync_from_settings(self, db: Optional[AsyncSession] = None) -> Dict[str, Any]:
generated_session = db is None
if generated_session:
@@ -394,6 +482,8 @@ class RootRegistryService:
disabled = 0
cursor_created = 0
cursor_updated = 0
inventory_state_created = 0
inventory_state_updated = 0
synced_codes: set[str] = set()
for spec in specs:
@@ -448,6 +538,12 @@ class RootRegistryService:
elif cursor_change == "updated":
cursor_updated += 1
inventory_state_change = await self._ensure_asset_inventory_state(db, row)
if inventory_state_change == "created":
inventory_state_created += 1
elif inventory_state_change == "updated":
inventory_state_updated += 1
for row in existing_rows:
if row.root_code in synced_codes:
continue
@@ -464,6 +560,7 @@ class RootRegistryService:
"updated": updated,
"disabled": disabled,
"cursor_created_or_updated": cursor_created + cursor_updated,
"asset_inventory_state_created_or_updated": inventory_state_created + inventory_state_updated,
"summary": summary,
}
except Exception: