F(backend): add public media derivatives pipeline
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from ninja import Schema, ModelSchema
|
||||
from typing import Optional
|
||||
|
||||
from core.media import PREVIEW_VARIANT, THUMBNAIL_VARIANT, derivative_url
|
||||
from apps.users.models import User
|
||||
|
||||
|
||||
@@ -23,6 +24,8 @@ class UserLoginSchema(Schema):
|
||||
|
||||
class UserProfileSchema(ModelSchema):
|
||||
profile_picture: Optional[str] = None
|
||||
profile_picture_thumbnail_url: Optional[str] = None
|
||||
profile_picture_preview_url: Optional[str] = None
|
||||
student_id: Optional[str] = None
|
||||
major: Optional[str] = None
|
||||
university: Optional[str] = None
|
||||
@@ -68,6 +71,18 @@ class UserProfileSchema(ModelSchema):
|
||||
return request.build_absolute_uri(obj.profile_picture.url)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def resolve_profile_picture_thumbnail_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.profile_picture, THUMBNAIL_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
@staticmethod
|
||||
def resolve_profile_picture_preview_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.profile_picture, PREVIEW_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
|
||||
class UserListSchema(ModelSchema):
|
||||
major: Optional[str] = None
|
||||
|
||||
@@ -5,13 +5,13 @@ from django.contrib.auth import authenticate
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils import timezone
|
||||
from django.core.files.storage import default_storage
|
||||
from django.core.files.base import ContentFile
|
||||
|
||||
import uuid
|
||||
import jwt
|
||||
from ninja import Query, Router
|
||||
|
||||
from core.media import delete_image_derivatives
|
||||
from apps.users.models import User, Major, University
|
||||
from apps.users.tasks import send_verification_email, send_password_reset_email
|
||||
from apps.users.api.schemas import (
|
||||
@@ -254,10 +254,6 @@ def upload_profile_picture(request):
|
||||
|
||||
user = request.auth
|
||||
|
||||
# Delete old profile picture if exists
|
||||
if user.profile_picture:
|
||||
default_storage.delete(user.profile_picture.name)
|
||||
|
||||
# Save new profile picture
|
||||
filename = f"profile_pictures/{user.id}_{uuid.uuid4().hex}.{file.name.split('.')[-1]}"
|
||||
user.profile_picture.save(filename, ContentFile(file.read()))
|
||||
@@ -270,7 +266,7 @@ def delete_profile_picture(request):
|
||||
user = request.auth
|
||||
|
||||
if user.profile_picture:
|
||||
default_storage.delete(user.profile_picture.name)
|
||||
delete_image_derivatives(user.profile_picture, "profile_picture", delete_original=True)
|
||||
user.profile_picture = None
|
||||
user.save(update_fields=['profile_picture'])
|
||||
|
||||
@@ -400,4 +396,3 @@ def check_username_availability(request, username: str):
|
||||
"""Check if a username is available for registration"""
|
||||
exists = User.objects.filter(username=username).exists()
|
||||
return {"exists": exists}
|
||||
|
||||
|
||||
@@ -5,6 +5,11 @@ from django.db import models
|
||||
import uuid
|
||||
from datetime import timedelta
|
||||
|
||||
from core.media import (
|
||||
delete_image_derivatives_by_name,
|
||||
get_image_previous_name,
|
||||
safe_process_public_image,
|
||||
)
|
||||
from core.models import BaseModel
|
||||
|
||||
|
||||
@@ -95,6 +100,8 @@ class User(AbstractUser, BaseModel):
|
||||
self.save(update_fields=['password_reset_token', 'password_reset_token_expires_at'])
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
previous_image_name = get_image_previous_name(self, "profile_picture")
|
||||
current_image_name = self.profile_picture.name if self.profile_picture else None
|
||||
send_verified_success = False
|
||||
|
||||
if self.pk is not None:
|
||||
@@ -104,6 +111,17 @@ class User(AbstractUser, BaseModel):
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
if previous_image_name != current_image_name and previous_image_name:
|
||||
delete_image_derivatives_by_name(
|
||||
self.profile_picture.storage if self.profile_picture else None,
|
||||
previous_image_name,
|
||||
"profile_picture",
|
||||
delete_original=True,
|
||||
)
|
||||
|
||||
if previous_image_name != current_image_name and self.profile_picture:
|
||||
safe_process_public_image(self.profile_picture, "profile_picture")
|
||||
|
||||
if send_verified_success:
|
||||
try:
|
||||
from apps.users.tasks import send_email_verified_success
|
||||
|
||||
Reference in New Issue
Block a user