F(backend): add public media derivatives pipeline
This commit is contained in:
71
core/management/commands/backfill_media_derivatives.py
Normal file
71
core/management/commands/backfill_media_derivatives.py
Normal file
@@ -0,0 +1,71 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from apps.blog.models import Post
|
||||
from apps.events.models import Event
|
||||
from apps.gallery.models import Gallery
|
||||
from apps.users.models import User
|
||||
from core.media import safe_process_public_image
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BackfillTarget:
|
||||
label: str
|
||||
queryset: object
|
||||
field_name: str
|
||||
family: str
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Generate missing public image derivatives for existing media."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Regenerate derivatives even when sidecar files already exist.",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
force = options["force"]
|
||||
processed = 0
|
||||
skipped = 0
|
||||
failed = 0
|
||||
|
||||
targets = (
|
||||
BackfillTarget("events", Event.objects.exclude(featured_image="").exclude(featured_image__isnull=True), "featured_image", "event_featured"),
|
||||
BackfillTarget("gallery", Gallery.objects.exclude(image="").exclude(image__isnull=True), "image", "gallery"),
|
||||
BackfillTarget("blog", Post.objects.exclude(featured_image="").exclude(featured_image__isnull=True), "featured_image", "blog_featured"),
|
||||
BackfillTarget("users", User.objects.exclude(profile_picture="").exclude(profile_picture__isnull=True), "profile_picture", "profile_picture"),
|
||||
)
|
||||
|
||||
for target in targets:
|
||||
self.stdout.write(self.style.NOTICE(f"Backfilling {target.label}..."))
|
||||
for instance in target.queryset.iterator():
|
||||
file_field = getattr(instance, target.field_name)
|
||||
result = safe_process_public_image(file_field, target.family, force=force)
|
||||
if result is None:
|
||||
failed += 1
|
||||
self.stdout.write(self.style.WARNING(f"failed: {target.label}#{instance.pk}"))
|
||||
continue
|
||||
|
||||
if hasattr(instance, "file_size") and hasattr(instance, "width") and hasattr(instance, "height"):
|
||||
type(instance).objects.filter(pk=instance.pk).update(
|
||||
file_size=result.file_size,
|
||||
width=result.width,
|
||||
height=result.height,
|
||||
)
|
||||
|
||||
if result.processed:
|
||||
processed += 1
|
||||
else:
|
||||
skipped += 1
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"Media derivative backfill finished. processed={processed} skipped={skipped} failed={failed}"
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user