arnavam commited on
Commit
6ae3d39
·
1 Parent(s): 9216a20

fixig some things

Browse files
Files changed (1) hide show
  1. server.py +125 -30
server.py CHANGED
@@ -75,6 +75,9 @@ audio_processor = AudioProcessor(str(MODEL_DIR))
75
  # MongoDB state
76
  mongo_client: AsyncMongoClient | None = None
77
  users_collection = None
 
 
 
78
 
79
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
80
 
@@ -319,29 +322,76 @@ async def vcam_generator_loop():
319
  @app.get("/")
320
  async def health_check():
321
  """Health check endpoint."""
 
322
  return {
323
  "status": "ok",
324
  "service": "AFS Tracking Backend",
325
- "mongodb": "connected" if users_collection is not None else "disconnected"
326
  }
327
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  @app.on_event("startup")
329
  async def startup_event():
330
- global mongo_client, users_collection
331
  mongo_uri = os.getenv("MONGODB_URI", "mongodb://localhost:27017")
332
  mongo_db_name = os.getenv("MONGODB_DB", "afs")
333
 
334
  try:
335
  mongo_client = AsyncMongoClient(mongo_uri, serverSelectionTimeoutMS=5000)
336
- users_collection = mongo_client[mongo_db_name]["users"]
 
 
 
 
 
 
 
 
337
  await users_collection.create_index("email", unique=True)
338
- logger.info("Connected to MongoDB and initialized users index.")
339
  except Exception as e:
340
- logger.warning(f"MongoDB connection failed: {e}. Running without authentication.")
341
  mongo_client = None
342
  users_collection = None
 
 
 
343
 
344
  asyncio.create_task(vcam_generator_loop())
 
345
 
346
 
347
  @app.on_event("shutdown")
@@ -792,35 +842,34 @@ async def get_audio_angles():
792
  async def upload_audio_file(
793
  file: UploadFile = File(...)
794
  ):
795
- """Upload recorded audio file from frontend."""
796
  try:
797
- audio_dir = MODEL_DIR / "audio_recordings"
798
- audio_dir.mkdir(parents=True, exist_ok=True)
799
-
800
- timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
801
- ext = Path(file.filename).suffix
802
- if not ext:
803
- ext = ".wav"
804
 
805
- file_path = audio_dir / f"uploaded_audio_{timestamp}{ext}"
806
-
807
- with open(file_path, 'wb') as f:
808
- shutil.copyfileobj(file.file, f)
 
 
 
809
 
810
  return {
811
  "ok": True,
812
- "message": "Audio file uploaded successfully",
813
- "filename": str(file_path.name)
 
814
  }
815
  except Exception as e:
816
- logger.error(f"Error uploading audio: {e}")
817
  raise HTTPException(status_code=500, detail=str(e))
818
 
819
  @app.post("/api/audio/set-angle")
820
  async def set_desired_angle(
821
  angle: float = Form(...)
822
  ):
823
- """Send a desired angle to the audio processing system."""
824
  try:
825
  if not (0 <= angle <= 360):
826
  raise HTTPException(
@@ -828,24 +877,70 @@ async def set_desired_angle(
828
  detail="Angle must be between 0 and 360 degrees"
829
  )
830
 
831
- audio_dir = MODEL_DIR / "audio_recordings"
832
- audio_dir.mkdir(parents=True, exist_ok=True)
833
-
834
- desired_angle_file = audio_dir / "desired_angle.txt"
835
- with open(desired_angle_file, 'w') as f:
836
- f.write(f"{angle}\n")
837
 
838
- logger.info(f"Set desired angle {angle}°")
839
 
840
  return {
841
  "ok": True,
842
- "message": f"Desired angle set to {angle}°",
843
  "angle": angle
844
  }
845
  except HTTPException:
846
  raise
847
  except Exception as e:
848
- logger.error(f"Error setting angle: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
849
  raise HTTPException(status_code=500, detail=str(e))
850
 
851
  if __name__ == "__main__":
 
75
  # MongoDB state
76
  mongo_client: AsyncMongoClient | None = None
77
  users_collection = None
78
+ audio_recordings_collection = None
79
+ audio_settings_collection = None
80
+ audio_angles_collection = None
81
 
82
  pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
83
 
 
322
  @app.get("/")
323
  async def health_check():
324
  """Health check endpoint."""
325
+ status_db = "connected" if users_collection is not None else "disconnected"
326
  return {
327
  "status": "ok",
328
  "service": "AFS Tracking Backend",
329
+ "mongodb": status_db
330
  }
331
 
332
+ async def mongodb_reconnect_loop():
333
+ """Background task to attempt MongoDB reconnection if disconnected."""
334
+ global mongo_client, users_collection, audio_recordings_collection, audio_settings_collection
335
+ while True:
336
+ if users_collection is None:
337
+ mongo_uri = os.getenv("MONGODB_URI", "mongodb://localhost:27017")
338
+ mongo_db_name = os.getenv("MONGODB_DB", "afs")
339
+ try:
340
+ logger.info("Attempting to reconnect to MongoDB...")
341
+ client = AsyncMongoClient(mongo_uri, serverSelectionTimeoutMS=5000)
342
+ # Ping to force connection verification
343
+ await client.admin.command('ping')
344
+
345
+ # Re-initialize
346
+ mongo_client = client
347
+ db = mongo_client[mongo_db_name]
348
+ users_collection = db["users"]
349
+ audio_recordings_collection = db["audio_recordings"]
350
+ audio_settings_collection = db["audio_settings"]
351
+ audio_angles_collection = db["audio_angles"]
352
+
353
+ await users_collection.create_index("email", unique=True)
354
+ logger.info("Successfully reconnected to MongoDB.")
355
+ except Exception as e:
356
+ logger.error(f"MongoDB reconnection failed: {e}")
357
+ mongo_client = None
358
+ users_collection = None
359
+ audio_recordings_collection = None
360
+ audio_settings_collection = None
361
+ audio_angles_collection = None
362
+
363
+ # Wait before next check (e.g., 10 seconds)
364
+ await asyncio.sleep(10)
365
+
366
  @app.on_event("startup")
367
  async def startup_event():
368
+ global mongo_client, users_collection, audio_recordings_collection, audio_settings_collection, audio_angles_collection
369
  mongo_uri = os.getenv("MONGODB_URI", "mongodb://localhost:27017")
370
  mongo_db_name = os.getenv("MONGODB_DB", "afs")
371
 
372
  try:
373
  mongo_client = AsyncMongoClient(mongo_uri, serverSelectionTimeoutMS=5000)
374
+ # Ping to force connection verification
375
+ await mongo_client.admin.command('ping')
376
+
377
+ db = mongo_client[mongo_db_name]
378
+ users_collection = db["users"]
379
+ audio_recordings_collection = db["audio_recordings"]
380
+ audio_settings_collection = db["audio_settings"]
381
+ audio_angles_collection = db["audio_angles"]
382
+
383
  await users_collection.create_index("email", unique=True)
384
+ logger.info("Connected to MongoDB and initialized collections.")
385
  except Exception as e:
386
+ logger.warning(f"MongoDB connection failed on startup: {e}. Starting reconnection loop.")
387
  mongo_client = None
388
  users_collection = None
389
+ audio_recordings_collection = None
390
+ audio_settings_collection = None
391
+ audio_angles_collection = None
392
 
393
  asyncio.create_task(vcam_generator_loop())
394
+ asyncio.create_task(mongodb_reconnect_loop())
395
 
396
 
397
  @app.on_event("shutdown")
 
842
  async def upload_audio_file(
843
  file: UploadFile = File(...)
844
  ):
845
+ """Upload recorded audio file from frontend and save to MongoDB."""
846
  try:
847
+ # Read file content for DB persistence
848
+ file_content = await file.read()
 
 
 
 
 
849
 
850
+ if audio_recordings_collection is not None:
851
+ await audio_recordings_collection.insert_one({
852
+ "filename": file.filename,
853
+ "content": file_content, # Saved as binary in MongoDB
854
+ "content_type": file.content_type,
855
+ "timestamp": datetime.utcnow()
856
+ })
857
 
858
  return {
859
  "ok": True,
860
+ "message": "Audio file saved to database successfully",
861
+ "filename": file.filename,
862
+ "size": len(file_content)
863
  }
864
  except Exception as e:
865
+ logger.error(f"Error saving audio to DB: {e}")
866
  raise HTTPException(status_code=500, detail=str(e))
867
 
868
  @app.post("/api/audio/set-angle")
869
  async def set_desired_angle(
870
  angle: float = Form(...)
871
  ):
872
+ """Send a desired angle to the audio processing system and persist to MongoDB."""
873
  try:
874
  if not (0 <= angle <= 360):
875
  raise HTTPException(
 
877
  detail="Angle must be between 0 and 360 degrees"
878
  )
879
 
880
+ if audio_angles_collection is not None:
881
+ await audio_angles_collection.update_one(
882
+ {"key": "latest_angle"},
883
+ {"$set": {"value": angle, "updated_at": datetime.utcnow()}},
884
+ upsert=True
885
+ )
886
 
887
+ logger.info(f"Set and persisted desired angle {angle}° to DB")
888
 
889
  return {
890
  "ok": True,
891
+ "message": f"Desired angle set to {angle}° and saved to DB",
892
  "angle": angle
893
  }
894
  except HTTPException:
895
  raise
896
  except Exception as e:
897
+ logger.error(f"Error setting angle in DB: {e}")
898
+ raise HTTPException(status_code=500, detail=str(e))
899
+
900
+ @app.get("/api/audio/settings")
901
+ async def get_audio_settings():
902
+ """Retrieve all audio settings from MongoDB."""
903
+ try:
904
+ if audio_settings_collection is None:
905
+ return {"ok": False, "message": "Database not connected"}
906
+
907
+ cursor = audio_settings_collection.find({}, {"_id": 0})
908
+ settings_list = await cursor.to_list(length=100)
909
+
910
+ # Convert list to dictionary
911
+ settings_dict = {s["key"]: s["value"] for s in settings_list if "key" in s}
912
+
913
+ return {
914
+ "ok": True,
915
+ "settings": settings_dict
916
+ }
917
+ except Exception as e:
918
+ logger.error(f"Error retrieving audio settings: {e}")
919
+ raise HTTPException(status_code=500, detail=str(e))
920
+
921
+ @app.post("/api/audio/settings")
922
+ async def update_audio_settings(
923
+ settings: dict = Body(...)
924
+ ):
925
+ """Update general audio settings in MongoDB."""
926
+ try:
927
+ if audio_settings_collection is None:
928
+ raise HTTPException(status_code=503, detail="Database not connected")
929
+
930
+ for key, value in settings.items():
931
+ await audio_settings_collection.update_one(
932
+ {"key": key},
933
+ {"$set": {"value": value, "updated_at": datetime.utcnow()}},
934
+ upsert=True
935
+ )
936
+
937
+ return {
938
+ "ok": True,
939
+ "message": "Audio settings updated successfully",
940
+ "updated_keys": list(settings.keys())
941
+ }
942
+ except Exception as e:
943
+ logger.error(f"Error updating audio settings: {e}")
944
  raise HTTPException(status_code=500, detail=str(e))
945
 
946
  if __name__ == "__main__":