Files
LeDiscord/backend/api/routers/users.py

112 lines
3.6 KiB
Python

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