Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding or changing versions #122

Open
dipth opened this issue Jan 10, 2021 · 3 comments
Open

Adding or changing versions #122

dipth opened this issue Jan 10, 2021 · 3 comments

Comments

@dipth
Copy link

dipth commented Jan 10, 2021

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?

@achempion
Copy link

Hi,

You just create a function and call it to process all files before deploying a new feature which uses these file sizes.

@dipth
Copy link
Author

dipth commented Jan 11, 2021

@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?

@achempion
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants