Skip to content

Commit

Permalink
Merge pull request #117 from elixir-waffle/feature/custom-transformat…
Browse files Browse the repository at this point in the history
…ions-with-extensions

Add support for extensions to custom transformations
  • Loading branch information
achempion authored Feb 7, 2024
2 parents c781d5a + 12d0085 commit 038f62c
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 13 deletions.
15 changes: 12 additions & 3 deletions lib/waffle/definition/versioning.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,18 @@ defmodule Waffle.Definition.Versioning do
conversion = definition.transform(version, {file, scope})

case conversion do
:skip -> nil
{_, _, ext} -> "#{name}.#{ext}"
_ -> "#{name}#{Path.extname(file.file_name)}"
:skip ->
nil

{_, _, ext} ->
[name, ext] |> Enum.join(".")

{fn_transform, fn_extension}
when is_function(fn_transform) and is_function(fn_extension) ->
[name, fn_extension.(version, file)] |> Enum.join(".")

_ ->
[name, Path.extname(file.file_name)] |> Enum.join()
end
end

Expand Down
23 changes: 14 additions & 9 deletions lib/waffle/processor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ defmodule Waffle.Processor do
transformation as elixir function,
[read more about custom transformations](custom_transformation.livemd)
* `{transform/2, fn version, file -> :png end}` - A custom
transformation converting a file into a different extension
## ImageMagick transformations
As images are one of the most commonly uploaded filetypes, Waffle
Expand Down Expand Up @@ -149,25 +152,27 @@ defmodule Waffle.Processor do
apply_transformation(file, transform, version)
end

@spec apply_transformation(
Waffle.File.t(),
(Waffle.File.t() -> {:ok, Waffle.File.t()} | {:error, String.t()}),
atom()
) :: {:ok, Waffle.File.t()} | {:error, String.t()}

defp apply_transformation(_, :skip, _), do: {:ok, nil}
defp apply_transformation(file, :noaction, _), do: {:ok, file}
# Deprecated
defp apply_transformation(file, {:noaction}, _), do: {:ok, file}

defp apply_transformation(file, func, version) when is_function(func), do: func.(version, file)

defp apply_transformation(file, {func, _}, version) when is_function(func),
do: func.(version, file)

defp apply_transformation(file, {cmd, conversion}, _) do
Convert.apply(cmd, file, conversion)
end

defp apply_transformation(file, {cmd, conversion, extension}, _) do
Convert.apply(cmd, file, conversion, extension)
end

@spec apply_transformation(
Waffle.File.t(),
(Waffle.File.t() -> {:ok, Waffle.File.t()} | {:error, String.t()}),
atom()
) :: {:ok, Waffle.File.t()} | {:error, String.t()}
defp apply_transformation(file, func, version) when is_function(func) do
func.(version, file)
end
end
28 changes: 28 additions & 0 deletions test/actions/store_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ defmodule WaffleTest.Actions.Store do
def __versions, do: [:original, :thumb, :skipped]
end

defmodule DummyDefinitionWithExtension do
use Waffle.Actions.Store
use Waffle.Definition.Storage

def validate({file, _}), do: String.ends_with?(file.file_name, ".png")

def transform(:convert_to_jpg, _),
do: {:convert, "-format jpg", :jpg}

def transform(:custom_to_jpg, {file, _}) do
{
fn _, _ -> {:ok, file} end,
fn _, _ -> :jpg end
}
end

def __versions, do: [:convert_to_jpg, :custom_to_jpg]
end

defmodule DummyDefinitionWithHeaders do
use Waffle.Actions.Store
use Waffle.Definition.Storage
Expand All @@ -36,6 +55,15 @@ defmodule WaffleTest.Actions.Store do
def __versions, do: [:original, :thumb, :skipped]
end

test "custom transformations change a file extension" do
with_mock Waffle.Storage.S3,
put: fn DummyDefinitionWithExtension, _, {%{file_name: "image.jpg", path: _}, nil} ->
{:ok, "resp"}
end do
assert DummyDefinitionWithExtension.store(@img) == {:ok, "image.png"}
end
end

test "checks file existence" do
assert DummyDefinition.store("non-existent-file.png") == {:error, :invalid_file_path}
end
Expand Down
33 changes: 32 additions & 1 deletion test/processor_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,23 @@ defmodule WaffleTest.Processor do
end
end

def transform(:custom_with_ext, _) do
{&transform_custom/2, &transform_custom_ext/2}
end

def transform(:skipped, _), do: :skip

defp transform_custom(version, file) do
Convert.apply(
:convert,
file,
fn input, output -> [input, "-strip", "-thumbnail", "1x1", output] end,
transform_custom_ext(version, file)
)
end

defp transform_custom_ext(_, _), do: :jpg

def __versions, do: [:original, :thumb]
end

Expand Down Expand Up @@ -119,7 +134,7 @@ defmodule WaffleTest.Processor do
cleanup(new_file.path)
end

test "transforms with custom function" do
test "transforms with a custom function" do
{:ok, new_file} =
Waffle.Processor.process(
DummyDefinition,
Expand All @@ -134,6 +149,22 @@ defmodule WaffleTest.Processor do
cleanup(new_file.path)
end

test "transforms with custom functions" do
{:ok, new_file} =
Waffle.Processor.process(
DummyDefinition,
:custom_with_ext,
{Waffle.File.new(@img, DummyDefinition), nil}
)

assert new_file.path != @img
# original file untouched
assert "128x128" == geometry(@img)
assert "1x1" == geometry(new_file.path)
assert Path.extname(new_file.path) == ".jpg"
cleanup(new_file.path)
end

test "transforms a file given as a binary" do
img_binary = File.read!(@img)

Expand Down

0 comments on commit 038f62c

Please sign in to comment.