berrypod/lib/simpleshop_theme/images/optimize_worker.ex
Jamey Greenwood 252ca2268a feat: optimize mockup images with WebP and auto-regeneration
Convert mockup source images from JPG to WebP format for 76% size
reduction (20MB → 4.7MB). Variants are now auto-generated on startup
via Oban, keeping the same DRY approach as database images.

Changes:
- Add OptimizeWorker.enqueue_mockup/1 for filesystem images
- Extend VariantCache to check mockup sources on startup
- Update MockupGenerator to save source as optimized WebP
- Update .gitignore to ignore generated variants
- Convert 55 source mockups from JPG to WebP

The mockup pipeline now uses the same code paths as database images:
- Optimizer.to_optimized_webp/1 for source conversion
- Optimizer.process_file/3 for variant generation
- OptimizeWorker for Oban background processing
- VariantCache for startup cache validation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 00:30:42 +00:00

54 lines
1.4 KiB
Elixir

defmodule SimpleshopTheme.Images.OptimizeWorker do
@moduledoc """
Oban worker for processing image variants in the background.
Handles both database images and filesystem mockups.
"""
use Oban.Worker, queue: :images, max_attempts: 3
alias SimpleshopTheme.Images.Optimizer
@impl Oban.Worker
def perform(%Oban.Job{args: %{"type" => "mockup", "source_path" => source_path}}) do
output_dir = Path.dirname(source_path)
basename = Path.basename(source_path, Path.extname(source_path))
case File.read(source_path) do
{:ok, data} ->
case Optimizer.process_file(data, basename, output_dir) do
{:ok, _} -> :ok
{:error, reason} -> {:error, reason}
end
{:error, reason} ->
{:error, reason}
end
end
def perform(%Oban.Job{args: %{"image_id" => image_id}}) do
case Optimizer.process_for_image(image_id) do
{:ok, _} -> :ok
{:error, :not_found} -> {:cancel, :image_not_found}
{:error, :no_data} -> {:cancel, :no_image_data}
{:error, reason} -> {:error, reason}
end
end
@doc """
Enqueue a database image for optimization.
"""
def enqueue(image_id) do
%{image_id: image_id}
|> new()
|> Oban.insert()
end
@doc """
Enqueue a mockup file for variant generation.
"""
def enqueue_mockup(source_path) when is_binary(source_path) do
%{type: "mockup", source_path: source_path}
|> new()
|> Oban.insert()
end
end