move to 2.5.5
[anni] / lib / pleroma / upload / filter / exiftool / read_description.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Upload.Filter.Exiftool.ReadDescription do
6   @moduledoc """
7   Gets a valid description from the related EXIF tags and provides them in the response if no description is provided yet.
8   It will first check ImageDescription, when that doesn't probide a valid description, it will check iptc:Caption-Abstract.
9   A valid description means the fields are filled in and not too long (see `:instance, :description_limit`).
10   """
11   @behaviour Pleroma.Upload.Filter
12
13   @spec filter(Pleroma.Upload.t()) :: {:ok, any()} | {:error, String.t()}
14
15   def filter(%Pleroma.Upload{description: description})
16       when is_binary(description),
17       do: {:ok, :noop}
18
19   def filter(%Pleroma.Upload{tempfile: file} = upload),
20     do: {:ok, :filtered, upload |> Map.put(:description, read_description_from_exif_data(file))}
21
22   def filter(_, _), do: {:ok, :noop}
23
24   defp read_description_from_exif_data(file) do
25     nil
26     |> read_when_empty(file, "-ImageDescription")
27     |> read_when_empty(file, "-iptc:Caption-Abstract")
28   end
29
30   defp read_when_empty(current_description, _, _) when is_binary(current_description),
31     do: current_description
32
33   defp read_when_empty(_, file, tag) do
34     try do
35       {tag_content, 0} =
36         System.cmd("exiftool", ["-b", "-s3", tag, file],
37           stderr_to_stdout: false,
38           parallelism: true
39         )
40
41       tag_content = String.trim(tag_content)
42
43       if tag_content != "" and
44            String.length(tag_content) <=
45              Pleroma.Config.get([:instance, :description_limit]),
46          do: tag_content,
47          else: nil
48     rescue
49       _ in ErlangError -> nil
50     end
51   end
52 end