51 lines
1.9 KiB
Python

import uuid
import io
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile
import sqlalchemy as sa
from sqids.sqids import Sqids
from PIL import Image
from materia_server.config import Config
from materia_server.models import User, UserInfo
from materia_server.routers import middleware
router = APIRouter(tags = ["user"])
@router.get("/user", response_model = UserInfo)
async def info(claims = Depends(middleware.jwt_cookie), ctx: middleware.Context = Depends()):
if not (current_user := await User.by_id(uuid.UUID(claims.sub), ctx.database)):
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "Missing user")
return UserInfo.model_validate(current_user)
@router.post("/user/avatar")
async def avatar(file: UploadFile, user: User = Depends(middleware.user), ctx: middleware.Context = Depends()):
async with ctx.database.session() as session:
avatars: list[str] = (await session.scalars(sa.select(User.avatar))).all()
avatars = list(filter(lambda avatar_hash: avatar_hash, avatars))
avatar_id = Sqids(min_length = 10, blocklist = avatars).encode([len(avatars)])
try:
img = Image.open(io.BytesIO(await file.read()))
except OSError as _:
raise HTTPException(status.HTTP_422_UNPROCESSABLE_ENTITY, "Failed to read file data")
try:
if not (avatars_dir := Config.data_dir() / "avatars").exists():
avatars_dir.mkdir()
img.save(avatars_dir / avatar_id, format = img.format)
except OSError as _:
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, "Failed to save avatar")
if old_avatar := user.avatar:
if (old_file := Config.data_dir() / "avatars" / old_avatar).exists():
old_file.unlink()
async with ctx.database.session() as session:
await session.execute(sa.update(user.User).where(user.User.id == user.id).values(avatar = avatar_id))
await session.commit()