move to 2.5.5
[anni] / lib / pleroma / utils.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Utils do
6   @posix_error_codes ~w(
7     eacces eagain ebadf ebadmsg ebusy edeadlk edeadlock edquot eexist efault
8     efbig eftype eintr einval eio eisdir eloop emfile emlink emultihop
9     enametoolong enfile enobufs enodev enolck enolink enoent enomem enospc
10     enosr enostr enosys enotblk enotdir enotsup enxio eopnotsupp eoverflow
11     eperm epipe erange erofs espipe esrch estale etxtbsy exdev
12   )a
13
14   @repo_timeout Pleroma.Config.get([Pleroma.Repo, :timeout], 15_000)
15
16   def compile_dir(dir) when is_binary(dir) do
17     dir
18     |> File.ls!()
19     |> Enum.map(&Path.join(dir, &1))
20     |> Kernel.ParallelCompiler.compile()
21   end
22
23   @doc """
24   POSIX-compliant check if command is available in the system
25
26   ## Examples
27       iex> command_available?("git")
28       true
29       iex> command_available?("wrongcmd")
30       false
31
32   """
33   @spec command_available?(String.t()) :: boolean()
34   def command_available?(command) do
35     case :os.find_executable(String.to_charlist(command)) do
36       false -> false
37       _ -> true
38     end
39   end
40
41   @doc "creates the uniq temporary directory"
42   @spec tmp_dir(String.t()) :: {:ok, String.t()} | {:error, :file.posix()}
43   def tmp_dir(prefix \\ "") do
44     sub_dir =
45       [
46         prefix,
47         Timex.to_unix(Timex.now()),
48         :os.getpid(),
49         String.downcase(Integer.to_string(:rand.uniform(0x100000000), 36))
50       ]
51       |> Enum.join("-")
52
53     tmp_dir = Path.join(System.tmp_dir!(), sub_dir)
54
55     case File.mkdir(tmp_dir) do
56       :ok -> {:ok, tmp_dir}
57       error -> error
58     end
59   end
60
61   @spec posix_error_message(atom()) :: binary()
62   def posix_error_message(code) when code in @posix_error_codes do
63     error_message = Gettext.dgettext(Pleroma.Web.Gettext, "posix_errors", "#{code}")
64     "(POSIX error: #{error_message})"
65   end
66
67   def posix_error_message(_), do: ""
68
69   @doc """
70   Returns [timeout: integer] suitable for passing as an option to Repo functions.
71
72   This function detects if the execution was triggered from IEx shell, Mix task, or
73   ./bin/pleroma_ctl and sets the timeout to :infinity, else returns the default timeout value.
74   """
75   @spec query_timeout() :: [timeout: integer]
76   def query_timeout do
77     {parent, _, _, _} = Process.info(self(), :current_stacktrace) |> elem(1) |> Enum.fetch!(2)
78
79     cond do
80       parent |> to_string |> String.starts_with?("Elixir.Mix.Task") -> [timeout: :infinity]
81       parent == :erl_eval -> [timeout: :infinity]
82       true -> [timeout: @repo_timeout]
83     end
84   end
85 end