66 lines
2.3 KiB
Python
66 lines
2.3 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
|
|
from sqlalchemy.orm import Session
|
|
from typing import List
|
|
from ..db.database import get_db
|
|
from ..schemas.song import ScanResult
|
|
from ..services.audio import scan_directory, extract_metadata, transcode_to_ogg
|
|
from ..models.song import Song
|
|
import uuid
|
|
import os
|
|
import aiofiles
|
|
|
|
router = APIRouter(prefix="/api/import", tags=["import"])
|
|
|
|
|
|
@router.post("/bulk", response_model=ScanResult)
|
|
async def bulk_import(
|
|
files: List[UploadFile] = File(...),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
upload_dir = os.getenv("UPLOAD_DIR", "./uploads")
|
|
os.makedirs(upload_dir, exist_ok=True)
|
|
|
|
scanned = 0
|
|
added = 0
|
|
errors = []
|
|
supported = {'.mp3', '.aac', '.flac', '.wav', '.ogg', '.m4a'}
|
|
|
|
for file in files:
|
|
ext = os.path.splitext(file.filename)[1].lower()
|
|
if ext not in supported:
|
|
errors.append(f"Unsupported format: {file.filename}")
|
|
continue
|
|
|
|
scanned += 1
|
|
try:
|
|
file_id = str(uuid.uuid4())
|
|
saved_name = f"{file_id}_{uuid.uuid4().hex[:8]}{ext}"
|
|
file_path = os.path.join(upload_dir, saved_name)
|
|
|
|
async with aiofiles.open(file_path, "wb") as f:
|
|
content = await file.read()
|
|
await f.write(content)
|
|
|
|
metadata = extract_metadata(file_path)
|
|
transcoded = transcode_to_ogg(file_path, upload_dir)
|
|
|
|
song = Song(
|
|
id=file_id,
|
|
title=metadata.get("title") or file.filename.replace(ext, ""),
|
|
artist=metadata.get("artist") or "Unknown",
|
|
album=metadata.get("album"),
|
|
duration_sec=metadata.get("duration", 0),
|
|
genre=metadata.get("genre"),
|
|
file_path=file_path,
|
|
transcoded_path=transcoded,
|
|
album_art_path=metadata.get("album_art_path"),
|
|
file_format=ext.replace(".", ""),
|
|
file_size_bytes=len(content),
|
|
)
|
|
db.add(song)
|
|
added += 1
|
|
except Exception as e:
|
|
errors.append(f"Error importing {file.filename}: {str(e)}")
|
|
|
|
db.commit()
|
|
return ScanResult(scanned=scanned, added=added, skipped=0, errors=errors) |