Files
Security_AI_integrated/api/sync.py

117 lines
3.7 KiB
Python
Raw Normal View History

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from typing import List, Optional
from db.models import get_db
from services.sync_service import get_sync_service
router = APIRouter(prefix="/api/sync", tags=["同步"])
@router.get("/status")
def get_sync_status(db: Session = Depends(get_db)):
"""获取同步服务状态"""
from sqlalchemy import text
service = get_sync_service()
status = service.get_status()
pending_cameras = db.execute(
text("SELECT COUNT(*) FROM cameras WHERE pending_sync = 1")
).scalar() or 0
pending_rois = db.execute(
text("SELECT COUNT(*) FROM rois WHERE pending_sync = 1")
).scalar() or 0
pending_alarms = db.execute(
text("SELECT COUNT(*) FROM alarms WHERE upload_status = 'pending' OR upload_status = 'retry'")
).scalar() or 0
return {
"running": status["running"],
"cloud_enabled": status["cloud_enabled"],
"network_status": status["network_status"],
"device_id": status["device_id"],
"pending_sync": pending_cameras + pending_rois,
"pending_alarms": pending_alarms,
"details": {
"pending_cameras": pending_cameras,
"pending_rois": pending_rois,
"pending_alarms": pending_alarms
}
}
@router.get("/pending")
def get_pending_syncs(db: Session = Depends(get_db)):
"""获取待同步项列表"""
from sqlalchemy import text
from db.models import Camera, ROI, Alarm
pending_cameras = db.query(Camera).filter(Camera.pending_sync == True).all()
pending_rois = db.query(ROI).filter(ROI.pending_sync == True).all()
from db.session import SessionLocal
temp_db = SessionLocal()
try:
pending_alarms = temp_db.query(Alarm).filter(
Alarm.upload_status.in_(['pending', 'retry'])
).limit(100).all()
finally:
temp_db.close()
return {
"cameras": [{"id": c.id, "name": c.name} for c in pending_cameras],
"rois": [{"id": r.id, "name": r.name, "camera_id": r.camera_id} for r in pending_rois],
"alarms": [{"id": a.id, "camera_id": a.camera_id, "type": a.event_type} for a in pending_alarms]
}
@router.post("/trigger")
def trigger_sync():
"""手动触发同步"""
service = get_sync_service()
from db.session import SessionLocal
from db.crud import get_all_cameras, get_all_rois
from db.models import Camera, ROI
db = SessionLocal()
try:
cameras = get_all_cameras(db)
for camera in cameras:
service.queue_camera_sync(camera.id, 'update', {
'name': camera.name,
'rtsp_url': camera.rtsp_url,
'enabled': camera.enabled
})
db.query(Camera).filter(Camera.id == camera.id).update({'pending_sync': False})
db.commit()
rois = get_all_rois(db)
for roi in rois:
service.queue_roi_sync(roi.id, 'update', {
'name': roi.name,
'roi_type': roi.roi_type,
'points': roi.points,
'enabled': roi.enabled
})
db.query(ROI).filter(ROI.id == roi.id).update({'pending_sync': False})
db.commit()
return {"message": "同步任务已加入队列", "count": len(cameras) + len(rois)}
finally:
db.close()
@router.post("/clear-failed")
def clear_failed_syncs(db: Session = Depends(get_db)):
"""清除失败的同步标记"""
from sqlalchemy import text
db.execute(text("UPDATE cameras SET pending_sync = 0, sync_failed_at = NULL, sync_retry_count = 0"))
db.execute(text("UPDATE rois SET pending_sync = 0, sync_failed_at = NULL, sync_retry_count = 0"))
db.commit()
return {"message": "已清除所有失败的同步标记"}