Files
fhd_scan_web_app/backend/bag_metadata.py
T
gardentech f34817d5b6 Initial commit: scan_web integrated recording UI
FastAPI backend + vanilla JS frontend for LiDAR/camera startup, camera
settings, and rosbag recording, unifying the previous scan_gui/scan_gui_dual/
scan_gui_triple desktop tools into one web app.
2026-08-07 14:26:00 +09:00

56 lines
1.7 KiB
Python

"""Read back what ros2 bag already knows about a recording — duration,
message counts, per-topic counts — instead of just listing directory names.
Also a plain on-disk size sum (metadata.yaml doesn't carry a byte size in
the ros2 bag version installed here)."""
from __future__ import annotations
import os
from pathlib import Path
from typing import Optional
import yaml
def dir_size_bytes(path: Path) -> int:
total = 0
try:
for entry in path.iterdir():
if entry.is_file():
total += entry.stat().st_size
except OSError:
pass
return total
def read_bag_metadata(bag_dir: Path) -> Optional[dict]:
"""Returns None if metadata.yaml is missing (e.g. bag was killed mid-write
before rosbag2 flushed it) or unparseable — a real, if incomplete, state
the operator should be able to see rather than a crash."""
meta_path = bag_dir / "metadata.yaml"
if not meta_path.exists():
return None
try:
with open(meta_path, encoding="utf-8") as f:
raw = yaml.safe_load(f)
info = raw["rosbag2_bagfile_information"]
except Exception:
return None
duration_s = info.get("duration", {}).get("nanoseconds", 0) / 1e9
message_count = info.get("message_count", 0)
topics = []
for entry in info.get("topics_with_message_count", []):
tm = entry.get("topic_metadata", {})
topics.append({
"name": tm.get("name", "?"),
"type": tm.get("type", "?"),
"message_count": entry.get("message_count", 0),
})
return {
"duration_s": round(duration_s, 1),
"message_count": message_count,
"topics": topics,
"size_bytes": dir_size_bytes(bag_dir),
}