Skip to content

Commit 0fdcd94

Browse files
extension: backend: storage: Improve support to mcap files
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
1 parent a4d6c37 commit 0fdcd94

File tree

1 file changed

+49
-6
lines changed

1 file changed

+49
-6
lines changed

extension/backend/src/doris/services/storage.py

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,28 @@ def _detect_media_type(filename: str) -> MediaType:
4040

4141

4242
def _file_to_media(path: Path, root: Path) -> MediaFile:
43-
"""Convert a filesystem path to a MediaFile model."""
43+
"""Convert a filesystem path to a MediaFile model.
44+
45+
Files inside a subdirectory use the subdirectory name as the mission_id.
46+
Root-level files whose stem matches a subdirectory (e.g.
47+
``recorder_20260411.mcap`` alongside ``recorder_20260411/``) are also
48+
associated with that mission.
49+
"""
4450
stat = path.stat()
4551
rel = path.relative_to(root)
52+
if len(rel.parts) > 1:
53+
mission_id = rel.parts[0]
54+
elif (root / path.stem).is_dir():
55+
mission_id = path.stem
56+
else:
57+
mission_id = None
4658
return MediaFile(
4759
id=str(rel),
4860
filename=path.name,
4961
media_type=_detect_media_type(path.name),
5062
size_bytes=stat.st_size,
5163
created_at=datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc),
52-
mission_id=rel.parts[0] if len(rel.parts) > 1 else None,
64+
mission_id=mission_id,
5365
download_url=f"/api/v1/media/download/{rel}",
5466
)
5567

@@ -75,10 +87,13 @@ async def get_media_files(
7587
self,
7688
mission_id: str | None = None,
7789
media_type: MediaType | None = None,
78-
limit: int = 50,
90+
limit: int = 0,
7991
offset: int = 0,
8092
) -> list[MediaFile]:
81-
"""List media files from the recorder directory."""
93+
"""List media files from the recorder directory.
94+
95+
A *limit* of ``0`` (the default) returns all files.
96+
"""
8297
try:
8398
search_root = self.media_root / mission_id if mission_id else self.media_root
8499
if not search_root.exists():
@@ -101,14 +116,21 @@ async def get_media_files(
101116

102117
files.sort(key=lambda f: f.created_at, reverse=True)
103118

104-
return files[offset : offset + limit]
119+
if limit > 0:
120+
return files[offset : offset + limit]
121+
return files[offset:] if offset else files
105122

106123
except Exception as e:
107124
logger.warning(f"Failed to scan media files: {e}")
108125
raise
109126

110127
async def get_missions_with_media(self) -> list[MediaMission]:
111-
"""Discover missions by scanning top-level subdirectories of the recorder."""
128+
"""Discover missions by scanning top-level subdirectories of the recorder.
129+
130+
Root-level files whose stem matches a subdirectory (e.g.
131+
``recorder_20260411.mcap`` next to ``recorder_20260411/``) are
132+
counted as part of that mission.
133+
"""
112134
try:
113135
if not self.media_root.exists():
114136
return []
@@ -142,6 +164,27 @@ async def get_missions_with_media(self) -> list[MediaMission]:
142164
except (FileNotFoundError, PermissionError):
143165
continue
144166

167+
# Include root-level files whose stem matches this directory
168+
for sibling in self.media_root.iterdir():
169+
try:
170+
if not sibling.is_file() or sibling.stem != entry.name:
171+
continue
172+
ext = sibling.suffix.lstrip(".").lower()
173+
if ext not in ALL_EXTENSIONS:
174+
continue
175+
stat = sibling.stat()
176+
total_size += stat.st_size
177+
latest_mtime = max(latest_mtime, stat.st_mtime)
178+
mt = _detect_media_type(sibling.name)
179+
if mt == MediaType.IMAGE:
180+
images += 1
181+
elif mt == MediaType.VIDEO:
182+
videos += 1
183+
else:
184+
data_files += 1
185+
except (FileNotFoundError, PermissionError):
186+
continue
187+
145188
if images + videos + data_files == 0:
146189
continue
147190

0 commit comments

Comments
 (0)