fix(lab): keep full route result indexable
This commit is contained in:
@@ -7,6 +7,7 @@ import hashlib
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import struct
|
||||
import tarfile
|
||||
import tempfile
|
||||
import zipfile
|
||||
@@ -705,6 +706,18 @@ def seal_mixed_route_full_video_review(
|
||||
temporary / "video" / "ddrnet-semantic-masks.zip",
|
||||
FULL_ROUTE_FRAME_COUNT,
|
||||
)
|
||||
timeline_destination = temporary / "video" / "frame-source-times-ns.bin"
|
||||
timeline_destination.write_bytes(
|
||||
struct.pack(f"<{FULL_ROUTE_FRAME_COUNT}Q", *frame_times_ns)
|
||||
)
|
||||
timeline_descriptor = {
|
||||
"role": "full-route-frame-timeline",
|
||||
"path": "video/frame-source-times-ns.bin",
|
||||
"byte_length": timeline_destination.stat().st_size,
|
||||
"sha256": sha256_path(timeline_destination),
|
||||
"media_type": "application/octet-stream",
|
||||
}
|
||||
artifacts.append(timeline_descriptor)
|
||||
proof_descriptors: dict[str, dict[str, object]] = {}
|
||||
for key, path in (
|
||||
("base", base_root / "result.json"),
|
||||
@@ -739,7 +752,13 @@ def seal_mixed_route_full_video_review(
|
||||
"height": 600,
|
||||
"timeline_start_seconds": job.timeline_start_seconds,
|
||||
"timeline_end_seconds": job.timeline_end_seconds,
|
||||
"frame_source_times_ns": frame_times_ns,
|
||||
"timeline": {
|
||||
"path": timeline_descriptor["path"],
|
||||
"sha256": timeline_descriptor["sha256"],
|
||||
"byte_length": timeline_descriptor["byte_length"],
|
||||
"encoding": "uint64-le-nanoseconds",
|
||||
"frame_count": FULL_ROUTE_FRAME_COUNT,
|
||||
},
|
||||
"ground_truth": False,
|
||||
"decode_repair": {
|
||||
"repaired_frame_count": 1,
|
||||
|
||||
@@ -214,6 +214,54 @@ def _build_vegetation_lab_router(
|
||||
raise HTTPException(status_code=404, detail="Full-route semantic mask not found")
|
||||
return _zip_mask_response(candidate.joinpath(*relative.parts), sequence)
|
||||
|
||||
@router.get("/{result_id}/route-timeline")
|
||||
def get_full_route_timeline(result_id: str) -> FileResponse:
|
||||
candidate = _resolve_candidate(root_provider, definition, result_id)
|
||||
manifest = _read_verified(candidate, definition)
|
||||
route = manifest.get("route_full_review")
|
||||
timeline = route.get("timeline") if isinstance(route, dict) else None
|
||||
relative_text = timeline.get("path") if isinstance(timeline, dict) else None
|
||||
frame_count = timeline.get("frame_count") if isinstance(timeline, dict) else None
|
||||
byte_length = timeline.get("byte_length") if isinstance(timeline, dict) else None
|
||||
sha256 = timeline.get("sha256") if isinstance(timeline, dict) else None
|
||||
if (
|
||||
not isinstance(relative_text, str)
|
||||
or frame_count != route.get("frame_count")
|
||||
or byte_length != frame_count * 8
|
||||
or not isinstance(sha256, str)
|
||||
or len(sha256) != 64
|
||||
):
|
||||
raise HTTPException(status_code=404, detail="Full-route timeline not found")
|
||||
relative = PurePosixPath(relative_text)
|
||||
artifacts = manifest.get("artifacts")
|
||||
if (
|
||||
relative.is_absolute()
|
||||
or str(relative) != relative_text
|
||||
or any(part in {"", ".", ".."} for part in relative.parts)
|
||||
or not isinstance(artifacts, list)
|
||||
or not any(
|
||||
isinstance(item, dict)
|
||||
and item.get("path") == relative_text
|
||||
and item.get("byte_length") == byte_length
|
||||
and item.get("sha256") == sha256
|
||||
and item.get("media_type") == "application/octet-stream"
|
||||
for item in artifacts
|
||||
)
|
||||
):
|
||||
raise HTTPException(status_code=404, detail="Full-route timeline not found")
|
||||
path = candidate.joinpath(*relative.parts)
|
||||
if not path.is_file() or path.is_symlink() or path.stat().st_size != byte_length:
|
||||
raise HTTPException(status_code=404, detail="Full-route timeline not found")
|
||||
return FileResponse(
|
||||
path,
|
||||
media_type="application/octet-stream",
|
||||
headers={
|
||||
"Cache-Control": "private, max-age=31536000, immutable",
|
||||
"ETag": f'"{sha256}"',
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
},
|
||||
)
|
||||
|
||||
return router
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user