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

Add support for extensions to custom transformations #117

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading