fix video label
This commit is contained in:
@@ -8,6 +8,7 @@ weight_prediction.json、临时 pred.json 等),由 fish_api 在子进程结
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import math
|
||||
import shutil
|
||||
import sqlite3
|
||||
from datetime import datetime, timezone
|
||||
@@ -222,6 +223,86 @@ def get_latest_health(settings: Settings) -> HealthSnapshot:
|
||||
conn.close()
|
||||
|
||||
|
||||
def _coerce_finite_number(v: Any) -> Optional[float]:
|
||||
if v is None:
|
||||
return None
|
||||
if isinstance(v, bool):
|
||||
return None
|
||||
if isinstance(v, (int, float)):
|
||||
x = float(v)
|
||||
return x if math.isfinite(x) else None
|
||||
if isinstance(v, str):
|
||||
s = v.strip()
|
||||
if not s:
|
||||
return None
|
||||
try:
|
||||
x = float(s)
|
||||
return x if math.isfinite(x) else None
|
||||
except ValueError:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
def _coerce_track_id(v: Any) -> Optional[int]:
|
||||
# bool is a subclass of int in Python
|
||||
if isinstance(v, bool):
|
||||
return None
|
||||
if isinstance(v, int):
|
||||
return v if v >= 0 else None
|
||||
if isinstance(v, str):
|
||||
try:
|
||||
i = int(v.strip(), 10)
|
||||
return i if i >= 0 else None
|
||||
except ValueError:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
def measure_result_deliverable(result: Any, error: Optional[str]) -> bool:
|
||||
"""至少一条记录含有效 track id 与有限数值的 weight(g)、length(mm)。"""
|
||||
if error:
|
||||
return False
|
||||
if not isinstance(result, list) or not result:
|
||||
return False
|
||||
for it in result:
|
||||
if not isinstance(it, dict):
|
||||
continue
|
||||
tid = _coerce_track_id(it.get("id"))
|
||||
w = _coerce_finite_number(it.get("weight"))
|
||||
ln = _coerce_finite_number(it.get("length"))
|
||||
if tid is not None and w is not None and ln is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def measure_snapshot_deliverable(snap: MeasureSnapshot) -> bool:
|
||||
return measure_result_deliverable(snap.result, snap.error)
|
||||
|
||||
|
||||
def health_snapshot_deliverable(snap: HealthSnapshot) -> bool:
|
||||
if snap.error:
|
||||
return False
|
||||
b = (snap.behavior_result or "").strip()
|
||||
h = (snap.health_result or "").strip()
|
||||
r = (snap.raw_class_en or "").strip()
|
||||
return bool(b or h or r)
|
||||
|
||||
|
||||
def _health_row_deliverable(
|
||||
behavior_result: str,
|
||||
health_result: str,
|
||||
raw_class_en: str,
|
||||
error: Optional[str],
|
||||
) -> bool:
|
||||
snap = HealthSnapshot(
|
||||
behavior_result=behavior_result or "",
|
||||
health_result=health_result or "",
|
||||
raw_class_en=raw_class_en or "",
|
||||
error=error,
|
||||
)
|
||||
return health_snapshot_deliverable(snap)
|
||||
|
||||
|
||||
def _last_delivered_id(
|
||||
conn: sqlite3.Connection, kind: str, snapshots_table: str
|
||||
) -> int:
|
||||
@@ -243,48 +324,55 @@ def _last_delivered_id(
|
||||
def pop_next_measure(
|
||||
settings: Settings,
|
||||
) -> Tuple[MeasureSnapshot, bool, Optional[int]]:
|
||||
"""取队首未投递的 measure 快照并推进游标;无未投递时 has_new=False。"""
|
||||
"""取队首未投递且可交付的 measure 快照并推进游标;跳过不可交付行仅推进游标。"""
|
||||
init_db(settings)
|
||||
conn = _connect(settings.sqlite_path)
|
||||
try:
|
||||
conn.execute("BEGIN IMMEDIATE")
|
||||
last_id = _last_delivered_id(conn, "measure", "measure_snapshots")
|
||||
|
||||
next_row = conn.execute(
|
||||
"""
|
||||
SELECT id, created_at, result_json, video_left, video_right,
|
||||
error, raw_prediction_path
|
||||
FROM measure_snapshots
|
||||
WHERE id > ?
|
||||
ORDER BY id ASC
|
||||
LIMIT 1
|
||||
""",
|
||||
(last_id,),
|
||||
).fetchone()
|
||||
while True:
|
||||
next_row = conn.execute(
|
||||
"""
|
||||
SELECT id, created_at, result_json, video_left, video_right,
|
||||
error, raw_prediction_path
|
||||
FROM measure_snapshots
|
||||
WHERE id > ?
|
||||
ORDER BY id ASC
|
||||
LIMIT 1
|
||||
""",
|
||||
(last_id,),
|
||||
).fetchone()
|
||||
|
||||
if next_row is None:
|
||||
conn.commit()
|
||||
return MeasureSnapshot(result=[], video_left="", video_right=""), False, None
|
||||
|
||||
nid = int(next_row["id"])
|
||||
err: Optional[str] = next_row["error"]
|
||||
data: Any = json.loads(next_row["result_json"])
|
||||
if not isinstance(data, list):
|
||||
data = []
|
||||
|
||||
conn.execute(
|
||||
"UPDATE delivery_cursor SET last_delivered_id = ? WHERE kind = ?",
|
||||
(nid, "measure"),
|
||||
)
|
||||
|
||||
if not measure_result_deliverable(data, err):
|
||||
last_id = nid
|
||||
continue
|
||||
|
||||
if next_row is None:
|
||||
conn.commit()
|
||||
return MeasureSnapshot(result=[], video_left="", video_right=""), False, None
|
||||
|
||||
nid = int(next_row["id"])
|
||||
conn.execute(
|
||||
"UPDATE delivery_cursor SET last_delivered_id = ? WHERE kind = ?",
|
||||
(nid, "measure"),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
data: Any = json.loads(next_row["result_json"])
|
||||
if not isinstance(data, list):
|
||||
data = []
|
||||
snap = MeasureSnapshot(
|
||||
result=data,
|
||||
video_left=next_row["video_left"] or "",
|
||||
video_right=next_row["video_right"] or "",
|
||||
updated_at=_parse_dt(next_row["created_at"]),
|
||||
error=next_row["error"],
|
||||
raw_prediction_path=next_row["raw_prediction_path"],
|
||||
)
|
||||
return snap, True, nid
|
||||
snap = MeasureSnapshot(
|
||||
result=data,
|
||||
video_left=next_row["video_left"] or "",
|
||||
video_right=next_row["video_right"] or "",
|
||||
updated_at=_parse_dt(next_row["created_at"]),
|
||||
error=err,
|
||||
raw_prediction_path=next_row["raw_prediction_path"],
|
||||
)
|
||||
return snap, True, nid
|
||||
except Exception:
|
||||
conn.rollback()
|
||||
raise
|
||||
@@ -293,44 +381,54 @@ def pop_next_measure(
|
||||
|
||||
|
||||
def pop_next_health(settings: Settings) -> Tuple[HealthSnapshot, bool, Optional[int]]:
|
||||
"""取队首未投递的 health 快照并推进游标;无未投递时 has_new=False。"""
|
||||
"""取队首未投递且可交付的 health 快照并推进游标;跳过不可交付行仅推进游标。"""
|
||||
init_db(settings)
|
||||
conn = _connect(settings.sqlite_path)
|
||||
try:
|
||||
conn.execute("BEGIN IMMEDIATE")
|
||||
last_id = _last_delivered_id(conn, "health", "health_snapshots")
|
||||
|
||||
next_row = conn.execute(
|
||||
"""
|
||||
SELECT id, created_at, behavior_result, health_result,
|
||||
raw_class_en, error
|
||||
FROM health_snapshots
|
||||
WHERE id > ?
|
||||
ORDER BY id ASC
|
||||
LIMIT 1
|
||||
""",
|
||||
(last_id,),
|
||||
).fetchone()
|
||||
while True:
|
||||
next_row = conn.execute(
|
||||
"""
|
||||
SELECT id, created_at, behavior_result, health_result,
|
||||
raw_class_en, error
|
||||
FROM health_snapshots
|
||||
WHERE id > ?
|
||||
ORDER BY id ASC
|
||||
LIMIT 1
|
||||
""",
|
||||
(last_id,),
|
||||
).fetchone()
|
||||
|
||||
if next_row is None:
|
||||
conn.commit()
|
||||
return HealthSnapshot(behavior_result="", health_result=""), False, None
|
||||
|
||||
nid = int(next_row["id"])
|
||||
beh = next_row["behavior_result"] or ""
|
||||
hlth = next_row["health_result"] or ""
|
||||
raw_en = next_row["raw_class_en"] or ""
|
||||
err: Optional[str] = next_row["error"]
|
||||
|
||||
conn.execute(
|
||||
"UPDATE delivery_cursor SET last_delivered_id = ? WHERE kind = ?",
|
||||
(nid, "health"),
|
||||
)
|
||||
|
||||
if not _health_row_deliverable(beh, hlth, raw_en, err):
|
||||
last_id = nid
|
||||
continue
|
||||
|
||||
if next_row is None:
|
||||
conn.commit()
|
||||
return HealthSnapshot(behavior_result="", health_result=""), False, None
|
||||
|
||||
nid = int(next_row["id"])
|
||||
conn.execute(
|
||||
"UPDATE delivery_cursor SET last_delivered_id = ? WHERE kind = ?",
|
||||
(nid, "health"),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
snap = HealthSnapshot(
|
||||
behavior_result=next_row["behavior_result"] or "",
|
||||
health_result=next_row["health_result"] or "",
|
||||
updated_at=_parse_dt(next_row["created_at"]),
|
||||
error=next_row["error"],
|
||||
raw_class_en=next_row["raw_class_en"] or "",
|
||||
)
|
||||
return snap, True, nid
|
||||
snap = HealthSnapshot(
|
||||
behavior_result=beh,
|
||||
health_result=hlth,
|
||||
updated_at=_parse_dt(next_row["created_at"]),
|
||||
error=err,
|
||||
raw_class_en=raw_en,
|
||||
)
|
||||
return snap, True, nid
|
||||
except Exception:
|
||||
conn.rollback()
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user