mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: implement backend avatar update
This commit is contained in:
parent
cec178c479
commit
a51a128fcb
11 changed files with 103 additions and 19 deletions
|
|
@ -1,5 +1,5 @@
|
|||
from typing import Literal
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi import APIRouter, Depends, Request, UploadFile
|
||||
from sqlmodel import Session
|
||||
from src.security.auth import get_current_user
|
||||
from src.core.events.database import get_db_session
|
||||
|
|
@ -22,6 +22,7 @@ from src.services.users.users import (
|
|||
read_user_by_id,
|
||||
read_user_by_uuid,
|
||||
update_user,
|
||||
update_user_avatar,
|
||||
update_user_password,
|
||||
)
|
||||
|
||||
|
|
@ -137,6 +138,20 @@ async def api_update_user(
|
|||
return await update_user(request, db_session, user_id, current_user, user_object)
|
||||
|
||||
|
||||
@router.put("/update_avatar/{user_id}", response_model=UserRead, tags=["users"])
|
||||
async def api_update_avatar_user(
|
||||
*,
|
||||
request: Request,
|
||||
db_session: Session = Depends(get_db_session),
|
||||
current_user: PublicUser = Depends(get_current_user),
|
||||
avatar_file: UploadFile | None = None,
|
||||
) -> UserRead:
|
||||
"""
|
||||
Update User
|
||||
"""
|
||||
return await update_user_avatar(request, db_session, current_user, avatar_file)
|
||||
|
||||
|
||||
@router.put("/change_password/{user_id}", response_model=UserRead, tags=["users"])
|
||||
async def api_update_user_password(
|
||||
*,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ async def upload_file_and_return_file_object(
|
|||
|
||||
await upload_content(
|
||||
f"courses/{course_uuid}/activities/{activity_uuid}/dynamic/blocks/{type_of_block}/{block_id}",
|
||||
org_uuid=org_uuid,
|
||||
type_of_dir='orgs',
|
||||
uuid=org_uuid,
|
||||
file_binary=file_binary,
|
||||
file_and_format=f"{file_id}.{file_format}",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ async def upload_pdf(pdf_file, activity_uuid, org_uuid, course_uuid):
|
|||
try:
|
||||
await upload_content(
|
||||
f"courses/{course_uuid}/activities/{activity_uuid}/documentpdf",
|
||||
"orgs",
|
||||
org_uuid,
|
||||
contents,
|
||||
f"documentpdf.{pdf_format}",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ async def upload_video(video_file, activity_uuid, org_uuid, course_uuid):
|
|||
await upload_content(
|
||||
f"courses/{course_uuid}/activities/{activity_uuid}/video",
|
||||
org_uuid,
|
||||
org_uuid,
|
||||
contents,
|
||||
f"video.{video_format}",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ async def update_course_thumbnail(
|
|||
if thumbnail_file and thumbnail_file.filename:
|
||||
name_in_disk = f"{course_uuid}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
|
||||
await upload_thumbnail(
|
||||
thumbnail_file, name_in_disk, org.org_uuid, course.course_uuid
|
||||
thumbnail_file, name_in_disk, 'users', course.course_uuid
|
||||
)
|
||||
|
||||
# Update course
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
|
||||
from src.services.utils.upload_content import upload_content
|
||||
|
||||
|
||||
async def upload_thumbnail(thumbnail_file, name_in_disk, org_id, course_id):
|
||||
async def upload_thumbnail(thumbnail_file, name_in_disk, org_uuid, course_id):
|
||||
contents = thumbnail_file.file.read()
|
||||
try:
|
||||
await upload_content(
|
||||
f"courses/{course_id}/thumbnails",
|
||||
org_id,
|
||||
"orgs",
|
||||
org_uuid,
|
||||
contents,
|
||||
f"{name_in_disk}",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ async def upload_org_logo(logo_file, org_uuid):
|
|||
await upload_content(
|
||||
"logos",
|
||||
org_uuid,
|
||||
org_uuid,
|
||||
contents,
|
||||
name_in_disk,
|
||||
)
|
||||
|
|
|
|||
16
apps/api/src/services/users/avatars.py
Normal file
16
apps/api/src/services/users/avatars.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from src.services.utils.upload_content import upload_content
|
||||
|
||||
|
||||
async def upload_avatar(avatar_file, name_in_disk, user_uuid):
|
||||
contents = avatar_file.file.read()
|
||||
try:
|
||||
await upload_content(
|
||||
f"avatars",
|
||||
"users",
|
||||
user_uuid,
|
||||
contents,
|
||||
f"{name_in_disk}",
|
||||
)
|
||||
|
||||
except Exception:
|
||||
return {"message": "There was an error uploading the file"}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
from datetime import datetime
|
||||
from typing import Literal
|
||||
from uuid import uuid4
|
||||
from fastapi import HTTPException, Request, status
|
||||
from fastapi import HTTPException, Request, UploadFile, status
|
||||
from sqlmodel import Session, select
|
||||
from src.services.users.avatars import upload_avatar
|
||||
from src.db.roles import Role, RoleRead
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
)
|
||||
from src.db.organizations import Organization, OrganizationRead
|
||||
from src.db.users import (
|
||||
AnonymousUser,
|
||||
|
|
@ -195,6 +196,49 @@ async def update_user(
|
|||
return user
|
||||
|
||||
|
||||
async def update_user_avatar(
|
||||
request: Request,
|
||||
db_session: Session,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
avatar_file: UploadFile | None = None,
|
||||
):
|
||||
# Get user
|
||||
statement = select(User).where(User.id == current_user.id)
|
||||
user = db_session.exec(statement).first()
|
||||
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="User does not exist",
|
||||
)
|
||||
|
||||
# RBAC check
|
||||
await rbac_check(request, current_user, "update", user.user_uuid, db_session)
|
||||
|
||||
# Upload thumbnail
|
||||
if avatar_file and avatar_file.filename:
|
||||
name_in_disk = f"{user.user_uuid}_avatar_{uuid4()}.{avatar_file.filename.split('.')[-1]}"
|
||||
await upload_avatar(avatar_file, name_in_disk, user.user_uuid)
|
||||
|
||||
# Update course
|
||||
if name_in_disk:
|
||||
user.avatar_image = name_in_disk
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Issue with Avatar upload",
|
||||
)
|
||||
|
||||
# Update user in database
|
||||
db_session.add(user)
|
||||
db_session.commit()
|
||||
db_session.refresh(user)
|
||||
|
||||
user = UserRead.from_orm(user)
|
||||
|
||||
return user
|
||||
|
||||
|
||||
async def update_user_password(
|
||||
request: Request,
|
||||
db_session: Session,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from typing import Literal
|
||||
import boto3
|
||||
from botocore.exceptions import ClientError
|
||||
import os
|
||||
|
|
@ -6,7 +7,11 @@ from config.config import get_learnhouse_config
|
|||
|
||||
|
||||
async def upload_content(
|
||||
directory: str, org_uuid: str, file_binary: bytes, file_and_format: str
|
||||
directory: str,
|
||||
type_of_dir: Literal["orgs", "users"],
|
||||
uuid: str, # org_uuid or user_uuid
|
||||
file_binary: bytes,
|
||||
file_and_format: str,
|
||||
):
|
||||
# Get Learnhouse Config
|
||||
learnhouse_config = get_learnhouse_config()
|
||||
|
|
@ -16,12 +21,12 @@ async def upload_content(
|
|||
|
||||
if content_delivery == "filesystem":
|
||||
# create folder for activity
|
||||
if not os.path.exists(f"content/{org_uuid}/{directory}"):
|
||||
if not os.path.exists(f"content/{type_of_dir}/{uuid}/{directory}"):
|
||||
# create folder for activity
|
||||
os.makedirs(f"content/{org_uuid}/{directory}")
|
||||
os.makedirs(f"content/{type_of_dir}/{uuid}/{directory}")
|
||||
# upload file to server
|
||||
with open(
|
||||
f"content/{org_uuid}/{directory}/{file_and_format}",
|
||||
f"content/{type_of_dir}/{uuid}/{directory}/{file_and_format}",
|
||||
"wb",
|
||||
) as f:
|
||||
f.write(file_binary)
|
||||
|
|
@ -37,13 +42,13 @@ async def upload_content(
|
|||
)
|
||||
|
||||
# Create folder for activity
|
||||
if not os.path.exists(f"content/{org_uuid}/{directory}"):
|
||||
if not os.path.exists(f"content/{type_of_dir}/{uuid}/{directory}"):
|
||||
# create folder for activity
|
||||
os.makedirs(f"content/{org_uuid}/{directory}")
|
||||
os.makedirs(f"content/{type_of_dir}/{uuid}/{directory}")
|
||||
|
||||
# Upload file to server
|
||||
with open(
|
||||
f"content/{org_uuid}/{directory}/{file_and_format}",
|
||||
f"content/{type_of_dir}/{uuid}/{directory}/{file_and_format}",
|
||||
"wb",
|
||||
) as f:
|
||||
f.write(file_binary)
|
||||
|
|
@ -52,9 +57,9 @@ async def upload_content(
|
|||
print("Uploading to s3 using boto3...")
|
||||
try:
|
||||
s3.upload_file(
|
||||
f"content/{org_uuid}/{directory}/{file_and_format}",
|
||||
f"content/{type_of_dir}/{uuid}/{directory}/{file_and_format}",
|
||||
"learnhouse-media",
|
||||
f"content/{org_uuid}/{directory}/{file_and_format}",
|
||||
f"content/{type_of_dir}/{uuid}/{directory}/{file_and_format}",
|
||||
)
|
||||
except ClientError as e:
|
||||
print(e)
|
||||
|
|
@ -63,7 +68,7 @@ async def upload_content(
|
|||
try:
|
||||
s3.head_object(
|
||||
Bucket="learnhouse-media",
|
||||
Key=f"content/{org_uuid}/{directory}/{file_and_format}",
|
||||
Key=f"content/{type_of_dir}/{uuid}/{directory}/{file_and_format}",
|
||||
)
|
||||
print("File upload successful!")
|
||||
except Exception as e:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue