feat: add counting bench, triage, and dataset modules
This commit includes major additions and updates to the frontend and backend architectures, introducing new dataset management, live counting features, batch processing, and triage logic. Includes new UI pages, components, and API routes.
This commit is contained in:
1 parent
8285400254
commit
5c7c122105
80 files changed
+20074
-1412
No files matched your search
@@ -220,6 +220,45 @@ def delete(annotation_id: int) -> bool:
|
||||
return cur.rowcount > 0
|
||||
|
||||
|
||||
def delete_many(annotation_ids: List[int]) -> int:
|
||||
"""Drop a marquee's worth of shapes in one statement.
|
||||
|
||||
One DELETE per shape would be one request per shape from the editor, and a
|
||||
marquee over a dense frame routinely covers a hundred (REQ-045a)."""
|
||||
if not annotation_ids:
|
||||
return 0
|
||||
marks = ",".join("?" * len(annotation_ids))
|
||||
with db.cursor() as cur:
|
||||
cur.execute(f"DELETE FROM annotations WHERE id IN ({marks})", annotation_ids)
|
||||
return cur.rowcount
|
||||
|
||||
|
||||
def reclass_many(annotation_ids: List[int], class_id: int) -> int:
|
||||
if not annotation_ids:
|
||||
return 0
|
||||
with db.cursor() as cur:
|
||||
cur.execute(
|
||||
"""SELECT DISTINCT b.project_id FROM annotations a
|
||||
JOIN frames f ON f.id = a.frame_id
|
||||
JOIN batches b ON b.id = f.batch_id
|
||||
WHERE a.id IN (%s)""" % ",".join("?" * len(annotation_ids)),
|
||||
annotation_ids,
|
||||
)
|
||||
projects = [row[0] for row in cur.fetchall()]
|
||||
for project_id in projects:
|
||||
_check_class(project_id, class_id)
|
||||
|
||||
marks = ",".join("?" * len(annotation_ids))
|
||||
with db.cursor() as cur:
|
||||
# Same rule as update(): a hand decision makes these the user's shapes,
|
||||
# so a re-run of auto-annotation leaves them alone (REQ-034).
|
||||
cur.execute(
|
||||
f"UPDATE annotations SET class_id = ?, source = 'manual' WHERE id IN ({marks})",
|
||||
[class_id, *annotation_ids],
|
||||
)
|
||||
return cur.rowcount
|
||||
|
||||
|
||||
def replace_auto(frame_id: int, items: List[dict]) -> int:
|
||||
"""Swap this frame's automatic shapes for a fresh set, leaving manual ones."""
|
||||
with db.cursor() as cur:
|
||||
|
||||
Reference in new issue
Block a user