Initial commit — DRB server stack
Includes c2-core (FastAPI/MQTT/Firestore), discord-bot (slash commands), frontend (Next.js admin UI), and mosquitto config.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
from typing import Optional
|
||||
from fastapi import APIRouter, UploadFile, File, Form, HTTPException, Security
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
from app.internal.storage import upload_audio
|
||||
from app.internal import firestore as fstore
|
||||
from app.internal.logger import logger
|
||||
|
||||
router = APIRouter(tags=["upload"])
|
||||
|
||||
_bearer = HTTPBearer(auto_error=False)
|
||||
|
||||
|
||||
@router.post("/upload")
|
||||
async def upload_call_audio(
|
||||
file: UploadFile = File(...),
|
||||
call_id: str = Form(...),
|
||||
node_id: str = Form(...),
|
||||
credentials: Optional[HTTPAuthorizationCredentials] = Security(_bearer),
|
||||
):
|
||||
"""
|
||||
Receive an audio recording from an edge node.
|
||||
Upload to GCS, update the call document in Firestore with the audio URL.
|
||||
"""
|
||||
# Verify the per-node API key
|
||||
if not credentials:
|
||||
raise HTTPException(401, "Missing authorization")
|
||||
key_doc = await fstore.doc_get("node_keys", node_id)
|
||||
if not key_doc or key_doc.get("api_key") != credentials.credentials:
|
||||
raise HTTPException(401, "Invalid node API key")
|
||||
|
||||
data = await file.read()
|
||||
if not data:
|
||||
raise HTTPException(400, "Empty file.")
|
||||
|
||||
filename = f"{call_id}_{file.filename}"
|
||||
audio_url = await upload_audio(data, filename)
|
||||
|
||||
if audio_url:
|
||||
try:
|
||||
await fstore.doc_update("calls", call_id, {"audio_url": audio_url})
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not update call {call_id} with audio_url: {e}")
|
||||
|
||||
return {"url": audio_url}
|
||||
Reference in New Issue
Block a user