from fastapi import APIRouter, Depends, HTTPException, UploadFile, File from sqlalchemy.orm import Session from typing import List, Optional from app.db.session import get_db from app.models.beat import Beat from app.models.user import User from app.schemas.beat import BeatCreate, BeatUpdate, BeatResponse from app.services.auth import get_current_producer import shutil from pathlib import Path router = APIRouter() @router.get("/", response_model=List[BeatResponse]) async def get_beats( skip: int = 0, limit: int = 100, genre: Optional[str] = None, producer_id: Optional[int] = None, db: Session = Depends(get_db) ): query = db.query(Beat).filter(Beat.is_available) if genre: query = query.filter(Beat.genre == genre) if producer_id: query = query.filter(Beat.producer_id == producer_id) beats = query.offset(skip).limit(limit).all() return beats @router.get("/{beat_id}", response_model=BeatResponse) async def get_beat(beat_id: int, db: Session = Depends(get_db)): beat = db.query(Beat).filter(Beat.id == beat_id, Beat.is_available).first() if not beat: raise HTTPException(status_code=404, detail="Beat not found") return beat @router.post("/", response_model=BeatResponse) async def create_beat( beat: BeatCreate, current_user: User = Depends(get_current_producer), db: Session = Depends(get_db) ): db_beat = Beat( **beat.dict(), producer_id=current_user.id, file_path="", # Will be set when file is uploaded ) db.add(db_beat) db.commit() db.refresh(db_beat) return db_beat @router.put("/{beat_id}", response_model=BeatResponse) async def update_beat( beat_id: int, beat_update: BeatUpdate, current_user: User = Depends(get_current_producer), db: Session = Depends(get_db) ): beat = db.query(Beat).filter(Beat.id == beat_id, Beat.producer_id == current_user.id).first() if not beat: raise HTTPException(status_code=404, detail="Beat not found") update_data = beat_update.dict(exclude_unset=True) for field, value in update_data.items(): setattr(beat, field, value) db.commit() db.refresh(beat) return beat @router.delete("/{beat_id}") async def delete_beat( beat_id: int, current_user: User = Depends(get_current_producer), db: Session = Depends(get_db) ): beat = db.query(Beat).filter(Beat.id == beat_id, Beat.producer_id == current_user.id).first() if not beat: raise HTTPException(status_code=404, detail="Beat not found") beat.is_available = False db.commit() return {"message": "Beat deleted successfully"} @router.post("/{beat_id}/upload-file") async def upload_beat_file( beat_id: int, file: UploadFile = File(...), current_user: User = Depends(get_current_producer), db: Session = Depends(get_db) ): beat = db.query(Beat).filter(Beat.id == beat_id, Beat.producer_id == current_user.id).first() if not beat: raise HTTPException(status_code=404, detail="Beat not found") if not file.filename.endswith(('.mp3', '.wav', '.flac')): raise HTTPException(status_code=400, detail="Invalid file format") storage_dir = Path("/app/storage/beats") storage_dir.mkdir(parents=True, exist_ok=True) file_path = storage_dir / f"{beat_id}_{file.filename}" with open(file_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) beat.file_path = str(file_path) db.commit() return {"message": "File uploaded successfully", "file_path": str(file_path)} @router.post("/{beat_id}/upload-preview") async def upload_beat_preview( beat_id: int, file: UploadFile = File(...), current_user: User = Depends(get_current_producer), db: Session = Depends(get_db) ): beat = db.query(Beat).filter(Beat.id == beat_id, Beat.producer_id == current_user.id).first() if not beat: raise HTTPException(status_code=404, detail="Beat not found") if not file.filename.endswith(('.mp3', '.wav')): raise HTTPException(status_code=400, detail="Invalid file format") storage_dir = Path("/app/storage/beats/previews") storage_dir.mkdir(parents=True, exist_ok=True) file_path = storage_dir / f"{beat_id}_preview_{file.filename}" with open(file_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) beat.preview_path = str(file_path) db.commit() return {"message": "Preview uploaded successfully", "preview_path": str(file_path)}