F(backend): add public media derivatives pipeline
This commit is contained in:
@@ -10,6 +10,7 @@ from apps.blog.api.schemas import AuthorSchema
|
||||
from apps.events.models import Event, Registration
|
||||
from apps.gallery.models import Gallery
|
||||
from apps.payments.models import Payment
|
||||
from core.media import BLUR_VARIANT, PREVIEW_VARIANT, THUMBNAIL_VARIANT, derivative_url
|
||||
|
||||
|
||||
class EventGallerySchema(ModelSchema):
|
||||
@@ -18,6 +19,8 @@ class EventGallerySchema(ModelSchema):
|
||||
file_size_mb: float
|
||||
markdown_url: str
|
||||
absolute_image_url: Optional[str] = None
|
||||
absolute_image_preview_url: Optional[str] = None
|
||||
absolute_image_blur_url: Optional[str] = None
|
||||
|
||||
class Config:
|
||||
model = Gallery
|
||||
@@ -31,12 +34,26 @@ class EventGallerySchema(ModelSchema):
|
||||
return request.build_absolute_uri(obj.image.url)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def resolve_absolute_image_preview_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.image, PREVIEW_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
@staticmethod
|
||||
def resolve_absolute_image_blur_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.image, BLUR_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
class EventSchema(ModelSchema):
|
||||
"""Schema providing full event details for API responses."""
|
||||
gallery_images: List[EventGallerySchema]
|
||||
description_html: str
|
||||
registration_count: int
|
||||
absolute_featured_image_url: Optional[str] = None
|
||||
absolute_featured_image_thumbnail_url: Optional[str] = None
|
||||
absolute_featured_image_preview_url: Optional[str] = None
|
||||
|
||||
class Config:
|
||||
model = Event
|
||||
@@ -54,6 +71,18 @@ class EventSchema(ModelSchema):
|
||||
return request.build_absolute_uri(obj.featured_image.url)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def resolve_absolute_featured_image_thumbnail_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.featured_image, THUMBNAIL_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
@staticmethod
|
||||
def resolve_absolute_featured_image_preview_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.featured_image, PREVIEW_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
@staticmethod
|
||||
def resolve_registration_count(obj):
|
||||
return obj.registrations.filter(status__in=[Registration.StatusChoices.CONFIRMED, Registration.StatusChoices.ATTENDED]).count()
|
||||
@@ -70,6 +99,8 @@ class EventListSchema(Schema):
|
||||
slug: str
|
||||
featured_image: Optional[str] = None
|
||||
absolute_featured_image_url: Optional[str] = None
|
||||
absolute_featured_image_thumbnail_url: Optional[str] = None
|
||||
absolute_featured_image_preview_url: Optional[str] = None
|
||||
event_type: str
|
||||
start_time: datetime
|
||||
end_time: datetime
|
||||
@@ -88,6 +119,18 @@ class EventListSchema(Schema):
|
||||
return request.build_absolute_uri(obj.featured_image.url)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def resolve_absolute_featured_image_thumbnail_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.featured_image, THUMBNAIL_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
@staticmethod
|
||||
def resolve_absolute_featured_image_preview_url(obj, context):
|
||||
request = context["request"]
|
||||
url = derivative_url(obj.featured_image, PREVIEW_VARIANT)
|
||||
return request.build_absolute_uri(url) if url else None
|
||||
|
||||
@staticmethod
|
||||
def resolve_registration_count(obj):
|
||||
return obj.registrations.filter(status__in=[Registration.StatusChoices.CONFIRMED, Registration.StatusChoices.ATTENDED]).count()
|
||||
|
||||
@@ -10,6 +10,11 @@ import uuid
|
||||
import markdown
|
||||
from location_field.models.plain import PlainLocationField as LocationField
|
||||
|
||||
from core.media import (
|
||||
delete_image_derivatives_by_name,
|
||||
get_image_previous_name,
|
||||
safe_process_public_image,
|
||||
)
|
||||
from core.models import BaseModel
|
||||
|
||||
|
||||
@@ -68,10 +73,24 @@ class Event(BaseModel):
|
||||
return self.title
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
previous_image_name = get_image_previous_name(self, "featured_image")
|
||||
current_image_name = self.featured_image.name if self.featured_image else None
|
||||
|
||||
if not self.slug:
|
||||
self.slug = slugify(self.title)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
if previous_image_name != current_image_name and previous_image_name:
|
||||
delete_image_derivatives_by_name(
|
||||
self.featured_image.storage if self.featured_image else None,
|
||||
previous_image_name,
|
||||
"event_featured",
|
||||
delete_original=True,
|
||||
)
|
||||
|
||||
if previous_image_name != current_image_name and self.featured_image:
|
||||
safe_process_public_image(self.featured_image, "event_featured")
|
||||
|
||||
@property
|
||||
def description_html(self):
|
||||
"""Convert markdown description to HTML"""
|
||||
|
||||
Reference in New Issue
Block a user