from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File from sqlalchemy.orm import Session from typing import List import os import uuid from PIL import Image from config.database import get_db from config.settings import settings from models.user import User from schemas.user import UserResponse, UserUpdate from utils.security import get_current_active_user from utils.settings_service import SettingsService from pathlib import Path router = APIRouter() @router.get("/me", response_model=UserResponse) async def get_current_user_info(current_user: User = Depends(get_current_active_user)): """Get current user information.""" return current_user @router.get("/", response_model=List[UserResponse]) async def get_all_users( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """Get all users.""" users = db.query(User).filter(User.is_active == True).all() return users @router.get("/{user_id}", response_model=UserResponse) async def get_user( user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """Get a specific user by ID.""" user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) return user @router.put("/me", response_model=UserResponse) async def update_current_user( user_update: UserUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """Update current user information.""" if user_update.full_name: current_user.full_name = user_update.full_name if user_update.bio is not None: current_user.bio = user_update.bio if user_update.avatar_url is not None: current_user.avatar_url = user_update.avatar_url db.commit() db.refresh(current_user) return current_user @router.post("/me/avatar", response_model=UserResponse) async def upload_avatar( file: UploadFile = File(...), db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): """Upload user avatar.""" # Validate file type if not SettingsService.is_file_type_allowed(db, file.content_type or "unknown"): allowed_types = SettingsService.get_setting(db, "allowed_image_types", ["image/jpeg", "image/png", "image/gif", "image/webp"]) raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid file type. Allowed types: {', '.join(allowed_types)}" ) # Create user directory user_dir = Path(settings.UPLOAD_PATH) / "avatars" / str(current_user.id) user_dir.mkdir(parents=True, exist_ok=True) # Generate unique filename file_extension = file.filename.split(".")[-1] filename = f"{uuid.uuid4()}.{file_extension}" file_path = user_dir / filename # Save and resize image contents = await file.read() with open(file_path, "wb") as f: f.write(contents) # Resize image to 800x800 with high quality try: img = Image.open(file_path) img.thumbnail((800, 800)) img.save(file_path, quality=95, optimize=True) except Exception as e: os.remove(file_path) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Error processing image" ) # Update user avatar URL current_user.avatar_url = f"/avatars/{current_user.id}/{filename}" db.commit() db.refresh(current_user) return current_user