arc_ecto
arc_ecto copied to clipboard
Adding or changing versions
What is the best way to regenerate a version for an attachment when having added a new version definition or changed an existing one.
For instance, let's say I have the following version definitions:
defmodule MyAppWeb.PhotoFile do
use Arc.Definition
use Arc.Ecto.Definition
@versions [:original, :large, :thumb]
@extension_whitelist ~w(.jpg .jpeg .gif .png)
def acl(:large, _), do: :public_read
def acl(:thumb, _), do: :public_read
def validate({file, photo}) do
file_extension = file.file_name |> Path.extname |> String.downcase
Enum.member?(@extension_whitelist, file_extension)
end
def transform(:large, _) do
{:convert, "-define jpeg:size=2400x2400 -auto-orient -strip -resize 1200x1200>"}
end
def transform(:thumb, _) do
{:convert, "-define jpeg:size=500x500 -auto-orient -strip -thumbnail 250x250^ -gravity center -extent 250x250"}
end
def filename(version, _) do
version
end
def storage_dir(_version, {_file, photo}) do
"uploads/photos/#{photo.uuid}"
end
end
Supposed I've been having this running in production for a while and I now find out that I also need a tiny_thumb
version, I would change the definitions to add:
defmodule MyAppWeb.PhotoFile do
use Arc.Definition
use Arc.Ecto.Definition
@versions [:original, :large, :thumb, :tiny_thumb]
@extension_whitelist ~w(.jpg .jpeg .gif .png)
def acl(:large, _), do: :public_read
def acl(:thumb, _), do: :public_read
def acl(:tiny_thumb, _), do: :public_read
def validate({file, photo}) do
file_extension = file.file_name |> Path.extname |> String.downcase
Enum.member?(@extension_whitelist, file_extension)
end
def transform(:large, _) do
{:convert, "-define jpeg:size=2400x2400 -auto-orient -strip -resize 1200x1200>"}
end
def transform(:thumb, _) do
{:convert, "-define jpeg:size=500x500 -auto-orient -strip -thumbnail 250x250^ -gravity center -extent 250x250"}
end
def transform(:tiny_thumb, _) do
{:convert, "-define jpeg:size=500x500 -auto-orient -strip -thumbnail 32x32^ -gravity center -extent 32x32"}
end
def filename(version, _) do
version
end
def storage_dir(_version, {_file, photo}) do
"uploads/photos/#{photo.uuid}"
end
end
This will work fine for new photos uploaded after the change has been deployed, but existing photos will now fail when requesting MyAppWeb.PhotoFile.url({@photo.file, @photo}, :tiny_thumb)
.
So what would be the best way to traverse through all existing photos and create the missing version?
Hi,
You just create a function and call it to process all files before deploying a new feature which uses these file sizes.
@achempion sure, but is there a function that can be called to generate this version or do I manually have to write code that downloads the original images from S3 and re-attaches them to regenerate all versions?
I looks like you can't process only one version for now and have to trigger cropping for all versions at once upon adding a new version.