diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 0ffb55358..c0b5db9f1 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -47,6 +47,7 @@ defmodule Pleroma.Application do Pleroma.ApplicationRequirements.verify!() setup_instrumenters() load_custom_modules() + check_system_commands() Pleroma.Docs.JSON.compile() adapter = Application.get_env(:tesla, :adapter) @@ -249,4 +250,21 @@ defmodule Pleroma.Application do end defp http_children(_, _), do: [] + + defp check_system_commands do + filters = Config.get([Pleroma.Upload, :filters]) + + check_filter = fn filter, command_required -> + with true <- filter in filters, + false <- Pleroma.Utils.command_available?(command_required) do + Logger.error( + "#{filter} is specified in list of Pleroma.Upload filters, but the #{command_required} command is not found" + ) + end + end + + check_filter.(Pleroma.Upload.Filters.Exiftool, "exiftool") + check_filter.(Pleroma.Upload.Filters.Mogrify, "mogrify") + check_filter.(Pleroma.Upload.Filters.Mogrifun, "mogrify") + end end diff --git a/lib/pleroma/upload/filter/exiftool.ex b/lib/pleroma/upload/filter/exiftool.ex index c7fb6aefa..ea8798fe3 100644 --- a/lib/pleroma/upload/filter/exiftool.ex +++ b/lib/pleroma/upload/filter/exiftool.ex @@ -9,9 +9,17 @@ defmodule Pleroma.Upload.Filter.Exiftool do """ @behaviour Pleroma.Upload.Filter + @spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()} def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do - System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) - :ok + try do + case System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) do + {_response, 0} -> :ok + {error, 1} -> {:error, error} + end + rescue + _e in ErlangError -> + {:error, "exiftool command not found"} + end end def filter(_), do: :ok diff --git a/lib/pleroma/upload/filter/mogrifun.ex b/lib/pleroma/upload/filter/mogrifun.ex index 7d95577a4..a8503ac24 100644 --- a/lib/pleroma/upload/filter/mogrifun.ex +++ b/lib/pleroma/upload/filter/mogrifun.ex @@ -34,10 +34,15 @@ defmodule Pleroma.Upload.Filter.Mogrifun do [{"fill", "yellow"}, {"tint", "40"}] ] + @spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()} def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do - Filter.Mogrify.do_filter(file, [Enum.random(@filters)]) - - :ok + try do + Filter.Mogrify.do_filter(file, [Enum.random(@filters)]) + :ok + rescue + _e in ErlangError -> + {:error, "mogrify command not found"} + end end def filter(_), do: :ok diff --git a/lib/pleroma/upload/filter/mogrify.ex b/lib/pleroma/upload/filter/mogrify.ex index 2eb758006..7a45add5a 100644 --- a/lib/pleroma/upload/filter/mogrify.ex +++ b/lib/pleroma/upload/filter/mogrify.ex @@ -8,11 +8,15 @@ defmodule Pleroma.Upload.Filter.Mogrify do @type conversion :: action :: String.t() | {action :: String.t(), opts :: String.t()} @type conversions :: conversion() | [conversion()] + @spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()} def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do - filters = Pleroma.Config.get!([__MODULE__, :args]) - - do_filter(file, filters) - :ok + try do + do_filter(file, Pleroma.Config.get!([__MODULE__, :args])) + :ok + rescue + _e in ErlangError -> + {:error, "mogrify command not found"} + end end def filter(_), do: :ok diff --git a/lib/pleroma/utils.ex b/lib/pleroma/utils.ex index 6b8e3accf..21d1159be 100644 --- a/lib/pleroma/utils.ex +++ b/lib/pleroma/utils.ex @@ -9,4 +9,19 @@ defmodule Pleroma.Utils do |> Enum.map(&Path.join(dir, &1)) |> Kernel.ParallelCompiler.compile() end + + @doc """ + POSIX-compliant check if command is available in the system + + ## Examples + iex> command_available?("git") + true + iex> command_available?("wrongcmd") + false + + """ + @spec command_available?(String.t()) :: boolean() + def command_available?(command) do + match?({_output, 0}, System.cmd("sh", ["-c", "command -v #{command}"])) + end end diff --git a/mix.exs b/mix.exs index 63142dee7..aab833c5e 100644 --- a/mix.exs +++ b/mix.exs @@ -229,10 +229,10 @@ defmodule Pleroma.Mixfile do defp version(version) do identifier_filter = ~r/[^0-9a-z\-]+/i - {_cmdgit, cmdgit_err} = System.cmd("sh", ["-c", "command -v git"]) + git_available? = match?({_output, 0}, System.cmd("sh", ["-c", "command -v git"])) git_pre_release = - if cmdgit_err == 0 do + if git_available? do {tag, tag_err} = System.cmd("git", ["describe", "--tags", "--abbrev=0"], stderr_to_stdout: true) @@ -258,7 +258,7 @@ defmodule Pleroma.Mixfile do # Branch name as pre-release version component, denoted with a dot branch_name = - with 0 <- cmdgit_err, + with true <- git_available?, {branch_name, 0} <- System.cmd("git", ["rev-parse", "--abbrev-ref", "HEAD"]), branch_name <- String.trim(branch_name), branch_name <- System.get_env("PLEROMA_BUILD_BRANCH") || branch_name, diff --git a/test/upload/filter/exiftool_test.exs b/test/upload/filter/exiftool_test.exs index a1b7e46cd..8ed7d650b 100644 --- a/test/upload/filter/exiftool_test.exs +++ b/test/upload/filter/exiftool_test.exs @@ -7,6 +7,8 @@ defmodule Pleroma.Upload.Filter.ExiftoolTest do alias Pleroma.Upload.Filter test "apply exiftool filter" do + assert Pleroma.Utils.command_available?("exiftool") + File.cp!( "test/fixtures/DSCN0010.jpg", "test/fixtures/DSCN0010_tmp.jpg"