From aedbbec88aa0a9a38e588eabfbecb8058652002b Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sat, 11 Jul 2020 15:48:45 +0300 Subject: [PATCH 1/6] Add Pleroma.Utils.command_available?/1 and use where appropriate --- lib/pleroma/upload/filter/exiftool.ex | 9 ++++++++- lib/pleroma/utils.ex | 15 +++++++++++++++ mix.exs | 6 +++--- test/upload/filter/exiftool_test.exs | 2 ++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/pleroma/upload/filter/exiftool.ex b/lib/pleroma/upload/filter/exiftool.ex index c7fb6aefa..94622acd0 100644 --- a/lib/pleroma/upload/filter/exiftool.ex +++ b/lib/pleroma/upload/filter/exiftool.ex @@ -9,8 +9,15 @@ defmodule Pleroma.Upload.Filter.Exiftool do """ @behaviour Pleroma.Upload.Filter + require Logger + def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do - System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) + if Pleroma.Utils.command_available?("exiftool") do + System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) + else + Logger.warn("exiftool is not available, filter #{__MODULE__} skipped") + end + :ok end 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 @@ def compile_dir(dir) when is_binary(dir) 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 d7992ee37..5cd06e8fd 100644 --- a/mix.exs +++ b/mix.exs @@ -234,10 +234,10 @@ defp aliases do defp version(version) do identifier_filter = ~r/[^0-9a-z\-]+/i - {_cmdgit, cmdgit_err} = System.cmd("sh", ["-c", "command -v git"]) + git_available? = Pleroma.Utils.command_available?("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) @@ -263,7 +263,7 @@ defp version(version) 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" From 05187d497da1844005eaf96fbcab65840a578bb1 Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sat, 11 Jul 2020 16:09:46 +0300 Subject: [PATCH 2/6] One can not simply call application modules from mix.exs --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 5cd06e8fd..a775e54a4 100644 --- a/mix.exs +++ b/mix.exs @@ -234,7 +234,7 @@ defp aliases do defp version(version) do identifier_filter = ~r/[^0-9a-z\-]+/i - git_available? = Pleroma.Utils.command_available?("git") + git_available? = match?({_output, 0}, System.cmd("sh", ["-c", "command -v git"])) git_pre_release = if git_available? do From 45bd64e2a7a08377e260e93c8e1744166bfc133a Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sat, 11 Jul 2020 18:11:23 +0300 Subject: [PATCH 3/6] Error in Filter.Exiftool if exiftool not found --- lib/pleroma/upload/filter/exiftool.ex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/upload/filter/exiftool.ex b/lib/pleroma/upload/filter/exiftool.ex index 94622acd0..6a40e152f 100644 --- a/lib/pleroma/upload/filter/exiftool.ex +++ b/lib/pleroma/upload/filter/exiftool.ex @@ -14,11 +14,10 @@ defmodule Pleroma.Upload.Filter.Exiftool do def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do if Pleroma.Utils.command_available?("exiftool") do System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) + :ok else - Logger.warn("exiftool is not available, filter #{__MODULE__} skipped") + {:error, "exiftool command not found"} end - - :ok end def filter(_), do: :ok From 523f1b93a48d88ef8aa04ca17d51d1d0916b6093 Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sat, 11 Jul 2020 18:15:51 +0300 Subject: [PATCH 4/6] Remove Logger requirement --- lib/pleroma/upload/filter/exiftool.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/pleroma/upload/filter/exiftool.ex b/lib/pleroma/upload/filter/exiftool.ex index 6a40e152f..e1b976c98 100644 --- a/lib/pleroma/upload/filter/exiftool.ex +++ b/lib/pleroma/upload/filter/exiftool.ex @@ -9,8 +9,6 @@ defmodule Pleroma.Upload.Filter.Exiftool do """ @behaviour Pleroma.Upload.Filter - require Logger - def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do if Pleroma.Utils.command_available?("exiftool") do System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) From 3116a75e80144dff79232c8676bd28ed285a14d9 Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sat, 11 Jul 2020 18:22:03 +0300 Subject: [PATCH 5/6] Check if mogrify available before calling it --- lib/pleroma/upload/filter/mogrifun.ex | 9 ++++++--- lib/pleroma/upload/filter/mogrify.ex | 10 +++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/upload/filter/mogrifun.ex b/lib/pleroma/upload/filter/mogrifun.ex index 7d95577a4..8f362333d 100644 --- a/lib/pleroma/upload/filter/mogrifun.ex +++ b/lib/pleroma/upload/filter/mogrifun.ex @@ -35,9 +35,12 @@ defmodule Pleroma.Upload.Filter.Mogrifun do ] def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do - Filter.Mogrify.do_filter(file, [Enum.random(@filters)]) - - :ok + if Pleroma.Utils.command_available?("mogrify") do + Filter.Mogrify.do_filter(file, [Enum.random(@filters)]) + :ok + else + {: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..4bd0c2eb4 100644 --- a/lib/pleroma/upload/filter/mogrify.ex +++ b/lib/pleroma/upload/filter/mogrify.ex @@ -9,10 +9,14 @@ defmodule Pleroma.Upload.Filter.Mogrify do @type conversions :: conversion() | [conversion()] def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do - filters = Pleroma.Config.get!([__MODULE__, :args]) + if Pleroma.Utils.command_available?("mogrify") do + filters = Pleroma.Config.get!([__MODULE__, :args]) - do_filter(file, filters) - :ok + do_filter(file, filters) + :ok + else + {:error, "mogrify command not found"} + end end def filter(_), do: :ok From 7569f225f1d43c6435eda6b62fd5eff3cd3408e0 Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Wed, 5 Aug 2020 19:38:55 +0300 Subject: [PATCH 6/6] Move checks to application startup --- lib/pleroma/application.ex | 18 ++++++++++++++++++ lib/pleroma/upload/filter/exiftool.ex | 14 +++++++++----- lib/pleroma/upload/filter/mogrifun.ex | 8 +++++--- lib/pleroma/upload/filter/mogrify.ex | 12 ++++++------ 4 files changed, 38 insertions(+), 14 deletions(-) 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 @@ def start(_type, _args) 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 @@ defp http_children(Tesla.Adapter.Gun, _) 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 e1b976c98..ea8798fe3 100644 --- a/lib/pleroma/upload/filter/exiftool.ex +++ b/lib/pleroma/upload/filter/exiftool.ex @@ -9,12 +9,16 @@ 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 - if Pleroma.Utils.command_available?("exiftool") do - System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) - :ok - else - {:error, "exiftool command not found"} + 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 diff --git a/lib/pleroma/upload/filter/mogrifun.ex b/lib/pleroma/upload/filter/mogrifun.ex index 8f362333d..a8503ac24 100644 --- a/lib/pleroma/upload/filter/mogrifun.ex +++ b/lib/pleroma/upload/filter/mogrifun.ex @@ -34,12 +34,14 @@ 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 - if Pleroma.Utils.command_available?("mogrify") do + try do Filter.Mogrify.do_filter(file, [Enum.random(@filters)]) :ok - else - {:error, "mogrify command not found"} + rescue + _e in ErlangError -> + {:error, "mogrify command not found"} end end diff --git a/lib/pleroma/upload/filter/mogrify.ex b/lib/pleroma/upload/filter/mogrify.ex index 4bd0c2eb4..7a45add5a 100644 --- a/lib/pleroma/upload/filter/mogrify.ex +++ b/lib/pleroma/upload/filter/mogrify.ex @@ -8,14 +8,14 @@ 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 - if Pleroma.Utils.command_available?("mogrify") do - filters = Pleroma.Config.get!([__MODULE__, :args]) - - do_filter(file, filters) + try do + do_filter(file, Pleroma.Config.get!([__MODULE__, :args])) :ok - else - {:error, "mogrify command not found"} + rescue + _e in ErlangError -> + {:error, "mogrify command not found"} end end