bout right

This commit is contained in:
lda committed 2026-02-24 23:33:27 +07:00
1 parent 34bee8bf31
commit 2fc7d1cbfa
12 files changed
+1305 -335

No files matched your search

+2
View File
@@ -1,6 +1,7 @@
"""Sinks for pipeline output handling."""
from pipeline.sinks.alerts import FileAlertStore
from pipeline.sinks.database import DatabaseSink
from pipeline.sinks.display import WindowDisplaySink
from pipeline.sinks.events import SmartEventSink
from pipeline.sinks.metrics import MetricsSink
@@ -8,6 +9,7 @@ from pipeline.sinks.screenshots import ScreenshotSink
from pipeline.sinks.video import VideoFileStore
__all__ = [
"DatabaseSink",
"FileAlertStore",
"MetricsSink",
"ScreenshotSink",
+74
View File
@@ -0,0 +1,74 @@
"""Database sink - saves detection alerts to the database."""
import logging
import time
from pathlib import Path
import cv2
from db.repository import Repository
from pipeline.ops.drawing import draw_alert_banner, draw_detections
from pipeline.types import Frame
logger = logging.getLogger(__name__)
class DatabaseSink:
"""
Pipeline sink that saves smoking alerts to a database.
On ticket (alert), saves an annotated screenshot and inserts a detection record.
"""
def __init__(
self,
db: Repository,
user_id: int = 1,
image_dir: str = "static/alerts",
camera_source: str = "Pipeline",
):
self.db = db
self.user_id = user_id
self.camera_source = camera_source
self.image_dir = Path(image_dir)
self.image_dir.mkdir(parents=True, exist_ok=True)
self.count = 0
logger.info("DatabaseSink initialized (user_id=%d, dir=%s)", user_id, image_dir)
def handle(self, frame: Frame):
if not frame.ticket:
return
self.count += 1
ticket = frame.ticket
# Save annotated image
filename = f"alert_{int(time.time())}_{self.count}.jpg"
filepath = self.image_dir / filename
img = frame.data.copy()
draw_detections(img, frame.detections)
draw_alert_banner(img, f"SMOKING {ticket.confidence:.0%}")
cv2.imwrite(str(filepath), img)
# Insert into database
web_path = f"/static/alerts/{filename}"
try:
self.db.save_detection(
user_id=self.user_id,
image_path=web_path,
confidence=ticket.confidence,
camera_source=self.camera_source,
)
logger.info(
"Alert #%d saved to DB: %s (%.2f)",
self.count,
filename,
ticket.confidence,
)
except Exception as e:
logger.error("Failed to save alert to DB: %s", e)
def close(self):
pass # DB connection is managed by the repository