Add initial files for Audio Dashboard Management System
- Created .env.example for environment variable configuration. - Added docker-compose.yml for service orchestration. - Implemented frequency response extraction in extract_frequency_response.py and convert_to_frequency_db.py. - Generated output files: frequency_response_detailed.json, frequency_response_points.json, frequency_response.csv, and frequency_response_curve.png. - Included sample measurement data for FiiO FA19 in CSV format.
This commit is contained in:
+74
-11
@@ -1,12 +1,18 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Body
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Body, UploadFile, File, Form
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
from database import get_db
|
||||
from models.model import Model
|
||||
from schemas import ModelCreate, ModelUpdate, ModelResponse
|
||||
from response import ApiResponse, PageData
|
||||
import requests
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
# Configure logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/models", tags=["models"])
|
||||
|
||||
@@ -15,6 +21,10 @@ MEILISEARCH_URL = os.getenv("MEILISEARCH_URL", "http://localhost:7700")
|
||||
MEILISEARCH_API_KEY = os.getenv("MEILISEARCH_API_KEY", "")
|
||||
MEILISEARCH_INDEX = os.getenv("MEILISEARCH_INDEX", "models")
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_FOLDER = Path(__file__).parent.parent.parent / "autoeq" / "measurements"
|
||||
ALLOWED_EXTENSIONS = {'.csv', '.txt', '.json'}
|
||||
|
||||
|
||||
@router.get("/", response_model=ApiResponse)
|
||||
def get_models(
|
||||
@@ -26,6 +36,7 @@ def get_models(
|
||||
):
|
||||
"""获取所有型号列表(支持按品牌名称和型号名称模糊查询)"""
|
||||
try:
|
||||
logger.info(f"Getting models: skip={skip}, limit={limit}, brand_name={brand_name}, name={name}")
|
||||
query = db.query(Model)
|
||||
if brand_name:
|
||||
query = query.filter(Model.brand_name.like(f"%{brand_name}%"))
|
||||
@@ -35,7 +46,10 @@ def get_models(
|
||||
total = query.count()
|
||||
models = query.offset(skip).limit(limit).all()
|
||||
|
||||
logger.info(f"Found {len(models)} models, total={total}")
|
||||
|
||||
if not models:
|
||||
logger.warning("No models found")
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
|
||||
# 转换为字典列表
|
||||
@@ -43,6 +57,7 @@ def get_models(
|
||||
|
||||
return ApiResponse(code=1, msg="success", data={"items": models_data, "total": total, "skip": skip, "limit": limit})
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting models: {str(e)}", exc_info=True)
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@@ -50,39 +65,78 @@ def get_models(
|
||||
def get_model(model_id: int, db: Session = Depends(get_db)):
|
||||
"""获取单个型号"""
|
||||
try:
|
||||
logger.info(f"Getting model: id={model_id}")
|
||||
model = db.query(Model).filter(Model.id == model_id).first()
|
||||
if not model:
|
||||
logger.warning(f"Model not found: id={model_id}")
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
logger.info(f"Model found: {model.to_dict()}")
|
||||
return ApiResponse(code=1, msg="success", data=model.to_dict())
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting model {model_id}: {str(e)}", exc_info=True)
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.post("/", response_model=ApiResponse)
|
||||
def create_model(model: ModelCreate, db: Session = Depends(get_db)):
|
||||
"""创建新型号"""
|
||||
def create_model(
|
||||
brand_name: str = Form(...),
|
||||
name: str = Form(...),
|
||||
form: str = Form(None),
|
||||
rig: str = Form(None),
|
||||
source: str = Form(None),
|
||||
eq_key: str = Form(None),
|
||||
measurement_file: UploadFile = File(None),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""创建新型号(支持文件上传)"""
|
||||
try:
|
||||
logger.info(f"Creating model: brand_name={brand_name}, name={name}, form={form}, source={source}")
|
||||
# 检查是否已存在
|
||||
existing = db.query(Model).filter(
|
||||
Model.brand_name == model.brand_name,
|
||||
Model.name == model.name
|
||||
Model.brand_name == brand_name,
|
||||
Model.name == name
|
||||
).first()
|
||||
if existing:
|
||||
logger.warning(f"Model already exists: brand_name={brand_name}, name={name}")
|
||||
return ApiResponse(code=0, msg="该品牌下型号名称已存在", data=None)
|
||||
|
||||
# 处理文件上传
|
||||
measurement_filename = None
|
||||
if measurement_file and measurement_file.filename:
|
||||
logger.info(f"Uploading measurement file: {measurement_file.filename}")
|
||||
# 验证文件扩展名
|
||||
file_ext = os.path.splitext(measurement_file.filename)[1].lower()
|
||||
if file_ext not in ALLOWED_EXTENSIONS:
|
||||
logger.error(f"Unsupported file format: {file_ext}")
|
||||
return ApiResponse(code=0, msg=f"不支持的文件格式:{file_ext}", data=None)
|
||||
|
||||
# 创建保存路径:autoeq/measurements/{source}/data/{form}/{filename}
|
||||
save_dir = UPLOAD_FOLDER / source / "data" / form
|
||||
save_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 保存文件(保留原文件名)
|
||||
file_path = save_dir / measurement_file.filename
|
||||
with open(file_path, "wb") as buffer:
|
||||
shutil.copyfileobj(measurement_file.file, buffer)
|
||||
|
||||
measurement_filename = measurement_file.filename
|
||||
logger.info(f"File saved: {file_path}")
|
||||
|
||||
db_model = Model(
|
||||
brand_name=model.brand_name,
|
||||
name=model.name,
|
||||
form=model.form,
|
||||
rig=model.rig,
|
||||
source=model.source,
|
||||
eq_key=model.eq_key
|
||||
brand_name=brand_name,
|
||||
name=name,
|
||||
form=form,
|
||||
rig=rig,
|
||||
source=source,
|
||||
eq_key=eq_key
|
||||
)
|
||||
db.add(db_model)
|
||||
db.commit()
|
||||
db.refresh(db_model)
|
||||
logger.info(f"Model created successfully: id={db_model.id}")
|
||||
return ApiResponse(code=1, msg="success", data=db_model.to_dict())
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating model: {str(e)}", exc_info=True)
|
||||
db.rollback()
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
@@ -91,8 +145,10 @@ def create_model(model: ModelCreate, db: Session = Depends(get_db)):
|
||||
def update_model(model_id: int, model: ModelUpdate, db: Session = Depends(get_db)):
|
||||
"""更新型号"""
|
||||
try:
|
||||
logger.info(f"Updating model: id={model_id}, data={model.dict()}")
|
||||
db_model = db.query(Model).filter(Model.id == model_id).first()
|
||||
if not db_model:
|
||||
logger.warning(f"Model not found: id={model_id}")
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
|
||||
# 如果更新品牌或型号名称,检查是否冲突
|
||||
@@ -106,6 +162,7 @@ def update_model(model_id: int, model: ModelUpdate, db: Session = Depends(get_db
|
||||
Model.name == new_name
|
||||
).first()
|
||||
if existing:
|
||||
logger.warning(f"Model already exists: brand_name={new_brand_name}, name={new_name}")
|
||||
return ApiResponse(code=0, msg="该品牌下型号名称已存在", data=None)
|
||||
|
||||
# 更新字段
|
||||
@@ -124,8 +181,10 @@ def update_model(model_id: int, model: ModelUpdate, db: Session = Depends(get_db
|
||||
|
||||
db.commit()
|
||||
db.refresh(db_model)
|
||||
logger.info(f"Model updated successfully: id={db_model.id}")
|
||||
return ApiResponse(code=1, msg="success", data=db_model.to_dict())
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating model {model_id}: {str(e)}", exc_info=True)
|
||||
db.rollback()
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
@@ -134,14 +193,18 @@ def update_model(model_id: int, model: ModelUpdate, db: Session = Depends(get_db
|
||||
def delete_model(model_id: int, db: Session = Depends(get_db)):
|
||||
"""删除型号"""
|
||||
try:
|
||||
logger.info(f"Deleting model: id={model_id}")
|
||||
db_model = db.query(Model).filter(Model.id == model_id).first()
|
||||
if not db_model:
|
||||
logger.warning(f"Model not found: id={model_id}")
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
|
||||
db.delete(db_model)
|
||||
db.commit()
|
||||
logger.info(f"Model deleted successfully: id={model_id}")
|
||||
return ApiResponse(code=1, msg="success", data=None)
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting model {model_id}: {str(e)}", exc_info=True)
|
||||
db.rollback()
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user