Merge branch 'support/2255_posix_errors' into 'develop'
[#2255] added error messages for posix error code See merge request pleroma/pleroma!3138
This commit is contained in:
commit
6bb4f4e172
|
@ -22,14 +22,14 @@ defmodule Pleroma.Emoji.Pack do
|
||||||
|
|
||||||
alias Pleroma.Emoji
|
alias Pleroma.Emoji
|
||||||
alias Pleroma.Emoji.Pack
|
alias Pleroma.Emoji.Pack
|
||||||
|
alias Pleroma.Utils
|
||||||
|
|
||||||
@spec create(String.t()) :: {:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
|
@spec create(String.t()) :: {:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
|
||||||
def create(name) do
|
def create(name) do
|
||||||
with :ok <- validate_not_empty([name]),
|
with :ok <- validate_not_empty([name]),
|
||||||
dir <- Path.join(emoji_path(), name),
|
dir <- Path.join(emoji_path(), name),
|
||||||
:ok <- File.mkdir(dir) do
|
:ok <- File.mkdir(dir) do
|
||||||
%__MODULE__{pack_file: Path.join(dir, "pack.json")}
|
save_pack(%__MODULE__{pack_file: Path.join(dir, "pack.json")})
|
||||||
|> save_pack()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,10 +62,9 @@ def show(opts) do
|
||||||
@spec delete(String.t()) ::
|
@spec delete(String.t()) ::
|
||||||
{:ok, [binary()]} | {:error, File.posix(), binary()} | {:error, :empty_values}
|
{:ok, [binary()]} | {:error, File.posix(), binary()} | {:error, :empty_values}
|
||||||
def delete(name) do
|
def delete(name) do
|
||||||
with :ok <- validate_not_empty([name]) do
|
with :ok <- validate_not_empty([name]),
|
||||||
emoji_path()
|
pack_path <- Path.join(emoji_path(), name) do
|
||||||
|> Path.join(name)
|
File.rm_rf(pack_path)
|
||||||
|> File.rm_rf()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ defp unpack_zip_emojies(zip_files) do
|
||||||
def add_file(%Pack{} = pack, _, _, %Plug.Upload{content_type: "application/zip"} = file) do
|
def add_file(%Pack{} = pack, _, _, %Plug.Upload{content_type: "application/zip"} = file) do
|
||||||
with {:ok, zip_files} <- :zip.table(to_charlist(file.path)),
|
with {:ok, zip_files} <- :zip.table(to_charlist(file.path)),
|
||||||
[_ | _] = emojies <- unpack_zip_emojies(zip_files),
|
[_ | _] = emojies <- unpack_zip_emojies(zip_files),
|
||||||
{:ok, tmp_dir} <- Pleroma.Utils.tmp_dir("emoji") do
|
{:ok, tmp_dir} <- Utils.tmp_dir("emoji") do
|
||||||
try do
|
try do
|
||||||
{:ok, _emoji_files} =
|
{:ok, _emoji_files} =
|
||||||
:zip.unzip(
|
:zip.unzip(
|
||||||
|
@ -282,18 +281,21 @@ def update_metadata(name, data) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec load_pack(String.t()) :: {:ok, t()} | {:error, :not_found}
|
@spec load_pack(String.t()) :: {:ok, t()} | {:error, :file.posix()}
|
||||||
def load_pack(name) do
|
def load_pack(name) do
|
||||||
pack_file = Path.join([emoji_path(), name, "pack.json"])
|
pack_file = Path.join([emoji_path(), name, "pack.json"])
|
||||||
|
|
||||||
if File.exists?(pack_file) do
|
with {:ok, _} <- File.stat(pack_file),
|
||||||
|
{:ok, pack_data} <- File.read(pack_file) do
|
||||||
pack =
|
pack =
|
||||||
pack_file
|
from_json(
|
||||||
|> File.read!()
|
pack_data,
|
||||||
|> from_json()
|
%{
|
||||||
|> Map.put(:pack_file, pack_file)
|
pack_file: pack_file,
|
||||||
|> Map.put(:path, Path.dirname(pack_file))
|
path: Path.dirname(pack_file),
|
||||||
|> Map.put(:name, name)
|
name: name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
files_count =
|
files_count =
|
||||||
pack.files
|
pack.files
|
||||||
|
@ -301,8 +303,6 @@ def load_pack(name) do
|
||||||
|> length()
|
|> length()
|
||||||
|
|
||||||
{:ok, Map.put(pack, :files_count, files_count)}
|
{:ok, Map.put(pack, :files_count, files_count)}
|
||||||
else
|
|
||||||
{:error, :not_found}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -434,10 +434,17 @@ defp save_pack(pack) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp from_json(json) do
|
defp from_json(json, attrs) do
|
||||||
map = Jason.decode!(json)
|
map = Jason.decode!(json)
|
||||||
|
|
||||||
struct(__MODULE__, %{files: map["files"], pack: map["pack"]})
|
pack_attrs =
|
||||||
|
attrs
|
||||||
|
|> Map.merge(%{
|
||||||
|
files: map["files"],
|
||||||
|
pack: map["pack"]
|
||||||
|
})
|
||||||
|
|
||||||
|
struct(__MODULE__, pack_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp validate_shareable_packs_available(uri) do
|
defp validate_shareable_packs_available(uri) do
|
||||||
|
@ -491,10 +498,10 @@ defp rename_file(pack, filename, new_filename) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp create_subdirs(file_path) do
|
defp create_subdirs(file_path) do
|
||||||
if String.contains?(file_path, "/") do
|
with true <- String.contains?(file_path, "/"),
|
||||||
file_path
|
path <- Path.dirname(file_path),
|
||||||
|> Path.dirname()
|
false <- File.exists?(path) do
|
||||||
|> File.mkdir_p!()
|
File.mkdir_p!(path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -518,10 +525,15 @@ defp remove_dir_if_empty(emoji, filename) do
|
||||||
|
|
||||||
defp get_filename(pack, shortcode) do
|
defp get_filename(pack, shortcode) do
|
||||||
with %{^shortcode => filename} when is_binary(filename) <- pack.files,
|
with %{^shortcode => filename} when is_binary(filename) <- pack.files,
|
||||||
true <- pack.path |> Path.join(filename) |> File.exists?() do
|
file_path <- Path.join(pack.path, filename),
|
||||||
|
{:ok, _} <- File.stat(file_path) do
|
||||||
{:ok, filename}
|
{:ok, filename}
|
||||||
else
|
else
|
||||||
_ -> {:error, :doesnt_exist}
|
{:error, _} = error ->
|
||||||
|
error
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
{:error, :doesnt_exist}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Utils do
|
defmodule Pleroma.Utils do
|
||||||
|
@posix_error_codes ~w(
|
||||||
|
eacces eagain ebadf ebadmsg ebusy edeadlk edeadlock edquot eexist efault
|
||||||
|
efbig eftype eintr einval eio eisdir eloop emfile emlink emultihop
|
||||||
|
enametoolong enfile enobufs enodev enolck enolink enoent enomem enospc
|
||||||
|
enosr enostr enosys enotblk enotdir enotsup enxio eopnotsupp eoverflow
|
||||||
|
eperm epipe erange erofs espipe esrch estale etxtbsy exdev
|
||||||
|
)a
|
||||||
|
|
||||||
def compile_dir(dir) when is_binary(dir) do
|
def compile_dir(dir) when is_binary(dir) do
|
||||||
dir
|
dir
|
||||||
|> File.ls!()
|
|> File.ls!()
|
||||||
|
@ -44,4 +52,12 @@ def tmp_dir(prefix \\ "") do
|
||||||
error -> error
|
error -> error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec posix_error_message(atom()) :: binary()
|
||||||
|
def posix_error_message(code) when code in @posix_error_codes do
|
||||||
|
error_message = Gettext.dgettext(Pleroma.Web.Gettext, "posix_errors", "#{code}")
|
||||||
|
"(POSIX error: #{error_message})"
|
||||||
|
end
|
||||||
|
|
||||||
|
def posix_error_message(_), do: ""
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,7 +27,8 @@ def create_operation do
|
||||||
422 => Operation.response("Unprocessable Entity", "application/json", ApiError),
|
422 => Operation.response("Unprocessable Entity", "application/json", ApiError),
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError),
|
404 => Operation.response("Not Found", "application/json", ApiError),
|
||||||
400 => Operation.response("Bad Request", "application/json", ApiError),
|
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||||
409 => Operation.response("Conflict", "application/json", ApiError)
|
409 => Operation.response("Conflict", "application/json", ApiError),
|
||||||
|
500 => Operation.response("Error", "application/json", ApiError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -169,7 +169,8 @@ def delete_operation do
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => ok_response(),
|
200 => ok_response(),
|
||||||
400 => Operation.response("Bad Request", "application/json", ApiError),
|
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
404 => Operation.response("Not Found", "application/json", ApiError),
|
||||||
|
500 => Operation.response("Error", "application/json", ApiError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -184,7 +185,8 @@ def update_operation do
|
||||||
parameters: [name_param()],
|
parameters: [name_param()],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Metadata", "application/json", metadata()),
|
200 => Operation.response("Metadata", "application/json", metadata()),
|
||||||
400 => Operation.response("Bad Request", "application/json", ApiError)
|
400 => Operation.response("Bad Request", "application/json", ApiError),
|
||||||
|
500 => Operation.response("Error", "application/json", ApiError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,7 +42,10 @@ def create(%{body_params: params} = conn, %{name: pack_name}) do
|
||||||
|> json(%{error: "pack name, shortcode or filename cannot be empty"})
|
|> json(%{error: "pack name, shortcode or filename cannot be empty"})
|
||||||
|
|
||||||
{:error, _} = error ->
|
{:error, _} = error ->
|
||||||
handle_error(conn, error, %{pack_name: pack_name})
|
handle_error(conn, error, %{
|
||||||
|
pack_name: pack_name,
|
||||||
|
message: "Unexpected error occurred while adding file to pack."
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -69,7 +72,11 @@ def update(%{body_params: %{shortcode: shortcode} = params} = conn, %{name: pack
|
||||||
|> json(%{error: "new_shortcode or new_filename cannot be empty"})
|
|> json(%{error: "new_shortcode or new_filename cannot be empty"})
|
||||||
|
|
||||||
{:error, _} = error ->
|
{:error, _} = error ->
|
||||||
handle_error(conn, error, %{pack_name: pack_name, code: shortcode})
|
handle_error(conn, error, %{
|
||||||
|
pack_name: pack_name,
|
||||||
|
code: shortcode,
|
||||||
|
message: "Unexpected error occurred while updating."
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -84,7 +91,11 @@ def delete(conn, %{name: pack_name, shortcode: shortcode}) do
|
||||||
|> json(%{error: "pack name or shortcode cannot be empty"})
|
|> json(%{error: "pack name or shortcode cannot be empty"})
|
||||||
|
|
||||||
{:error, _} = error ->
|
{:error, _} = error ->
|
||||||
handle_error(conn, error, %{pack_name: pack_name, code: shortcode})
|
handle_error(conn, error, %{
|
||||||
|
pack_name: pack_name,
|
||||||
|
code: shortcode,
|
||||||
|
message: "Unexpected error occurred while deleting emoji file."
|
||||||
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -94,18 +105,24 @@ defp handle_error(conn, {:error, :doesnt_exist}, %{code: emoji_code}) do
|
||||||
|> json(%{error: "Emoji \"#{emoji_code}\" does not exist"})
|
|> json(%{error: "Emoji \"#{emoji_code}\" does not exist"})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp handle_error(conn, {:error, :not_found}, %{pack_name: pack_name}) do
|
defp handle_error(conn, {:error, :enoent}, %{pack_name: pack_name}) do
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|> json(%{error: "pack \"#{pack_name}\" is not found"})
|
|> json(%{error: "pack \"#{pack_name}\" is not found"})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp handle_error(conn, {:error, _}, _) do
|
defp handle_error(conn, {:error, error}, opts) do
|
||||||
render_error(
|
message =
|
||||||
conn,
|
[
|
||||||
:internal_server_error,
|
Map.get(opts, :message, "Unexpected error occurred."),
|
||||||
"Unexpected error occurred while adding file to pack."
|
Pleroma.Utils.posix_error_message(error)
|
||||||
)
|
]
|
||||||
|
|> Enum.join(" ")
|
||||||
|
|> String.trim()
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_status(:internal_server_error)
|
||||||
|
|> json(%{error: message})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_filename(%Plug.Upload{filename: filename}), do: filename
|
defp get_filename(%Plug.Upload{filename: filename}), do: filename
|
||||||
|
|
|
@ -71,7 +71,7 @@ def show(conn, %{name: name, page: page, page_size: page_size}) do
|
||||||
with {:ok, pack} <- Pack.show(name: name, page: page, page_size: page_size) do
|
with {:ok, pack} <- Pack.show(name: name, page: page, page_size: page_size) do
|
||||||
json(conn, pack)
|
json(conn, pack)
|
||||||
else
|
else
|
||||||
{:error, :not_found} ->
|
{:error, :enoent} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|> json(%{error: "Pack #{name} does not exist"})
|
|> json(%{error: "Pack #{name} does not exist"})
|
||||||
|
@ -80,6 +80,17 @@ def show(conn, %{name: name, page: page, page_size: page_size}) do
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "pack name cannot be empty"})
|
|> json(%{error: "pack name cannot be empty"})
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
error_message =
|
||||||
|
add_posix_error(
|
||||||
|
"Failed to get the contents of the `#{name}` pack.",
|
||||||
|
error
|
||||||
|
)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_status(:internal_server_error)
|
||||||
|
|> json(%{error: error_message})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -95,7 +106,7 @@ def archive(conn, %{name: name}) do
|
||||||
"Pack #{name} cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
|
"Pack #{name} cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
|
||||||
})
|
})
|
||||||
|
|
||||||
{:error, :not_found} ->
|
{:error, :enoent} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|> json(%{error: "Pack #{name} does not exist"})
|
|> json(%{error: "Pack #{name} does not exist"})
|
||||||
|
@ -116,10 +127,10 @@ def download(%{body_params: %{url: url, name: name} = params} = conn, _) do
|
||||||
|> put_status(:internal_server_error)
|
|> put_status(:internal_server_error)
|
||||||
|> json(%{error: "SHA256 for the pack doesn't match the one sent by the server"})
|
|> json(%{error: "SHA256 for the pack doesn't match the one sent by the server"})
|
||||||
|
|
||||||
{:error, e} ->
|
{:error, error} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:internal_server_error)
|
|> put_status(:internal_server_error)
|
||||||
|> json(%{error: e})
|
|> json(%{error: error})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -139,12 +150,16 @@ def create(conn, %{name: name}) do
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "pack name cannot be empty"})
|
|> json(%{error: "pack name cannot be empty"})
|
||||||
|
|
||||||
{:error, _} ->
|
{:error, error} ->
|
||||||
render_error(
|
error_message =
|
||||||
conn,
|
add_posix_error(
|
||||||
:internal_server_error,
|
"Unexpected error occurred while creating pack.",
|
||||||
"Unexpected error occurred while creating pack."
|
error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_status(:internal_server_error)
|
||||||
|
|> json(%{error: error_message})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -164,10 +179,12 @@ def delete(conn, %{name: name}) do
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "pack name cannot be empty"})
|
|> json(%{error: "pack name cannot be empty"})
|
||||||
|
|
||||||
{:error, _, _} ->
|
{:error, error, _} ->
|
||||||
|
error_message = add_posix_error("Couldn't delete the `#{name}` pack", error)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_status(:internal_server_error)
|
|> put_status(:internal_server_error)
|
||||||
|> json(%{error: "Couldn't delete the pack #{name}"})
|
|> json(%{error: error_message})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -180,12 +197,16 @@ def update(%{body_params: %{metadata: metadata}} = conn, %{name: name}) do
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "The fallback archive does not have all files specified in pack.json"})
|
|> json(%{error: "The fallback archive does not have all files specified in pack.json"})
|
||||||
|
|
||||||
{:error, _} ->
|
{:error, error} ->
|
||||||
render_error(
|
error_message =
|
||||||
conn,
|
add_posix_error(
|
||||||
:internal_server_error,
|
"Unexpected error occurred while updating pack metadata.",
|
||||||
"Unexpected error occurred while updating pack metadata."
|
error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_status(:internal_server_error)
|
||||||
|
|> json(%{error: error_message})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -204,4 +225,10 @@ def import_from_filesystem(conn, _params) do
|
||||||
|> json(%{error: "Error accessing emoji pack directory"})
|
|> json(%{error: "Error accessing emoji pack directory"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp add_posix_error(msg, error) do
|
||||||
|
[msg, Pleroma.Utils.posix_error_message(error)]
|
||||||
|
|> Enum.join(" ")
|
||||||
|
|> String.trim()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
141
priv/gettext/en/LC_MESSAGES/posix_errors.po
Normal file
141
priv/gettext/en/LC_MESSAGES/posix_errors.po
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
## This file is a PO Template file.
|
||||||
|
msgid "eperm"
|
||||||
|
msgstr "Operation not permitted"
|
||||||
|
|
||||||
|
msgid "eacces"
|
||||||
|
msgstr "Permission denied"
|
||||||
|
|
||||||
|
msgid "eagain"
|
||||||
|
msgstr "Resource temporarily unavailable"
|
||||||
|
|
||||||
|
msgid "ebadf"
|
||||||
|
msgstr "Bad file descriptor"
|
||||||
|
|
||||||
|
msgid "ebadmsg"
|
||||||
|
msgstr "Bad message"
|
||||||
|
|
||||||
|
msgid "ebusy"
|
||||||
|
msgstr "Device or resource busy"
|
||||||
|
|
||||||
|
msgid "edeadlk"
|
||||||
|
msgstr "Resource deadlock avoided"
|
||||||
|
|
||||||
|
msgid "edeadlock"
|
||||||
|
msgstr "Resource deadlock avoided"
|
||||||
|
|
||||||
|
msgid "edquot"
|
||||||
|
msgstr "Disk quota exceeded"
|
||||||
|
|
||||||
|
msgid "eexist"
|
||||||
|
msgstr "File exists"
|
||||||
|
|
||||||
|
msgid "efault"
|
||||||
|
msgstr "Bad address"
|
||||||
|
|
||||||
|
msgid "efbig"
|
||||||
|
msgstr "File is too large"
|
||||||
|
|
||||||
|
msgid "eftype"
|
||||||
|
msgstr "Inappropriate file type or format"
|
||||||
|
|
||||||
|
msgid "eintr"
|
||||||
|
msgstr "Interrupted system call"
|
||||||
|
|
||||||
|
msgid "einval"
|
||||||
|
msgstr "Invalid argument"
|
||||||
|
|
||||||
|
msgid "eio"
|
||||||
|
msgstr "Input/output error"
|
||||||
|
|
||||||
|
msgid "eisdir"
|
||||||
|
msgstr "Illegal operation on a directory"
|
||||||
|
|
||||||
|
msgid "eloop"
|
||||||
|
msgstr "Too many levels of symbolic links"
|
||||||
|
|
||||||
|
msgid "emfile"
|
||||||
|
msgstr "Too many open files"
|
||||||
|
|
||||||
|
msgid "emlink"
|
||||||
|
msgstr "Too many links"
|
||||||
|
|
||||||
|
msgid "emultihop"
|
||||||
|
msgstr "Multihop attempted"
|
||||||
|
|
||||||
|
msgid "enametoolong"
|
||||||
|
msgstr "File name is too long"
|
||||||
|
|
||||||
|
msgid "enfile"
|
||||||
|
msgstr "Too many open files in system"
|
||||||
|
|
||||||
|
msgid "enobufs"
|
||||||
|
msgstr "No buffer space available"
|
||||||
|
|
||||||
|
msgid "enodev"
|
||||||
|
msgstr "No such device"
|
||||||
|
|
||||||
|
msgid "enolck"
|
||||||
|
msgstr "No locks available"
|
||||||
|
|
||||||
|
msgid "enolink"
|
||||||
|
msgstr "Link has been severed"
|
||||||
|
|
||||||
|
msgid "enoent"
|
||||||
|
msgstr "No such file or directory"
|
||||||
|
|
||||||
|
msgid "enomem"
|
||||||
|
msgstr "Cannot allocate memory"
|
||||||
|
|
||||||
|
msgid "enospc"
|
||||||
|
msgstr "No space left on device"
|
||||||
|
|
||||||
|
msgid "enosr"
|
||||||
|
msgstr "Out of streams resources"
|
||||||
|
|
||||||
|
msgid "enostr"
|
||||||
|
msgstr "Device is not a stream"
|
||||||
|
|
||||||
|
msgid "enosys"
|
||||||
|
msgstr "Function not implemented"
|
||||||
|
|
||||||
|
msgid "enotblk"
|
||||||
|
msgstr "Block device required"
|
||||||
|
|
||||||
|
msgid "enotdir"
|
||||||
|
msgstr "Not a directory"
|
||||||
|
|
||||||
|
msgid "enotsup"
|
||||||
|
msgstr "Operation not supported"
|
||||||
|
|
||||||
|
msgid "enxio"
|
||||||
|
msgstr "No such device or address"
|
||||||
|
|
||||||
|
msgid "eopnotsupp"
|
||||||
|
msgstr "Operation not supported"
|
||||||
|
|
||||||
|
msgid "eoverflow"
|
||||||
|
msgstr "Value too large for defined data type"
|
||||||
|
|
||||||
|
msgid "epipe"
|
||||||
|
msgstr "Broken pipe"
|
||||||
|
|
||||||
|
msgid "erange"
|
||||||
|
msgstr "Numerical result out of range"
|
||||||
|
|
||||||
|
msgid "erofs"
|
||||||
|
msgstr "Read-only file system"
|
||||||
|
|
||||||
|
msgid "espipe"
|
||||||
|
msgstr "Illegal seek"
|
||||||
|
|
||||||
|
msgid "esrch"
|
||||||
|
msgstr "No such process"
|
||||||
|
|
||||||
|
msgid "estale"
|
||||||
|
msgstr "Stale file handle"
|
||||||
|
|
||||||
|
msgid "etxtbsy"
|
||||||
|
msgstr "Text file busy"
|
||||||
|
|
||||||
|
msgid "exdev"
|
||||||
|
msgstr "Invalid cross-device link"
|
149
priv/gettext/posix_errors.pot
Normal file
149
priv/gettext/posix_errors.pot
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
## This file is a PO Template file.
|
||||||
|
##
|
||||||
|
## `msgid`s here are often extracted from source code.
|
||||||
|
## Add new translations manually only if they're dynamic
|
||||||
|
## translations that can't be statically extracted.
|
||||||
|
##
|
||||||
|
## Run `mix gettext.extract` to bring this file up to
|
||||||
|
## date. Leave `msgstr`s empty as changing them here as no
|
||||||
|
## effect: edit them in PO (`.po`) files instead.
|
||||||
|
msgid "eperm"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eacces"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eagain"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "ebadf"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "ebadmsg"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "ebusy"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "edeadlk"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "edeadlock"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "edquot"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eexist"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "efault"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "efbig"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eftype"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eintr"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "einval"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eio"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eisdir"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eloop"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "emfile"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "emlink"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "emultihop"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enametoolong"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enfile"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enobufs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enodev"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enolck"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enolink"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enoent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enomem"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enospc"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enosr"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enostr"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enosys"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enotblk"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enotdir"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enotsup"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "enxio"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eopnotsupp"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "eoverflow"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "epipe"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "erange"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "erofs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "espipe"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "esrch"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "estale"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "etxtbsy"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "exdev"
|
||||||
|
msgstr ""
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
|
defmodule Pleroma.Web.PleromaAPI.EmojiFileControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
|
|
||||||
|
import Mock
|
||||||
import Tesla.Mock
|
import Tesla.Mock
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
@ -200,6 +201,31 @@ test "add file with not loaded pack", %{admin_conn: admin_conn} do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "returns an error on add file when file system is not writable", %{
|
||||||
|
admin_conn: admin_conn
|
||||||
|
} do
|
||||||
|
pack_file = Path.join([@emoji_path, "not_loaded", "pack.json"])
|
||||||
|
|
||||||
|
with_mocks([
|
||||||
|
{File, [:passthrough], [stat: fn ^pack_file -> {:error, :eacces} end]}
|
||||||
|
]) do
|
||||||
|
assert admin_conn
|
||||||
|
|> put_req_header("content-type", "multipart/form-data")
|
||||||
|
|> post("/api/pleroma/emoji/packs/files?name=not_loaded", %{
|
||||||
|
shortcode: "blank3",
|
||||||
|
filename: "dir/blank.png",
|
||||||
|
file: %Plug.Upload{
|
||||||
|
filename: "blank.png",
|
||||||
|
path: "#{@emoji_path}/test_pack/blank.png"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|> json_response_and_validate_schema(500) == %{
|
||||||
|
"error" =>
|
||||||
|
"Unexpected error occurred while adding file to pack. (POSIX error: Permission denied)"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "remove file with not loaded pack", %{admin_conn: admin_conn} do
|
test "remove file with not loaded pack", %{admin_conn: admin_conn} do
|
||||||
assert admin_conn
|
assert admin_conn
|
||||||
|> delete("/api/pleroma/emoji/packs/files?name=not_loaded&shortcode=blank3")
|
|> delete("/api/pleroma/emoji/packs/files?name=not_loaded&shortcode=blank3")
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase, async: false
|
||||||
|
|
||||||
|
import Mock
|
||||||
import Tesla.Mock
|
import Tesla.Mock
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
@ -346,7 +347,7 @@ test "other error", %{admin_conn: admin_conn} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "PATCH /api/pleroma/emoji/pack?name=:name" do
|
describe "PATCH/update /api/pleroma/emoji/pack?name=:name" do
|
||||||
setup do
|
setup do
|
||||||
pack_file = "#{@emoji_path}/test_pack/pack.json"
|
pack_file = "#{@emoji_path}/test_pack/pack.json"
|
||||||
original_content = File.read!(pack_file)
|
original_content = File.read!(pack_file)
|
||||||
|
@ -365,6 +366,20 @@ test "other error", %{admin_conn: admin_conn} do
|
||||||
}}
|
}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "returns error when file system not writable", %{admin_conn: conn} = ctx do
|
||||||
|
with_mocks([
|
||||||
|
{File, [:passthrough], [stat: fn _ -> {:error, :eacces} end]}
|
||||||
|
]) do
|
||||||
|
assert conn
|
||||||
|
|> put_req_header("content-type", "multipart/form-data")
|
||||||
|
|> patch(
|
||||||
|
"/api/pleroma/emoji/pack?name=test_pack",
|
||||||
|
%{"metadata" => ctx[:new_data]}
|
||||||
|
)
|
||||||
|
|> json_response_and_validate_schema(500)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "for a pack without a fallback source", ctx do
|
test "for a pack without a fallback source", ctx do
|
||||||
assert ctx[:admin_conn]
|
assert ctx[:admin_conn]
|
||||||
|> put_req_header("content-type", "multipart/form-data")
|
|> put_req_header("content-type", "multipart/form-data")
|
||||||
|
@ -424,6 +439,46 @@ test "when the fallback source doesn't have all the files", ctx do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST/DELETE /api/pleroma/emoji/pack?name=:name" do
|
describe "POST/DELETE /api/pleroma/emoji/pack?name=:name" do
|
||||||
|
test "returns an error on creates pack when file system not writable", %{
|
||||||
|
admin_conn: admin_conn
|
||||||
|
} do
|
||||||
|
path_pack = Path.join(@emoji_path, "test_pack")
|
||||||
|
|
||||||
|
with_mocks([
|
||||||
|
{File, [:passthrough], [mkdir: fn ^path_pack -> {:error, :eacces} end]}
|
||||||
|
]) do
|
||||||
|
assert admin_conn
|
||||||
|
|> post("/api/pleroma/emoji/pack?name=test_pack")
|
||||||
|
|> json_response_and_validate_schema(500) == %{
|
||||||
|
"error" =>
|
||||||
|
"Unexpected error occurred while creating pack. (POSIX error: Permission denied)"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns an error on deletes pack when the file system is not writable", %{
|
||||||
|
admin_conn: admin_conn
|
||||||
|
} do
|
||||||
|
path_pack = Path.join(@emoji_path, "test_emoji_pack")
|
||||||
|
|
||||||
|
try do
|
||||||
|
{:ok, _pack} = Pleroma.Emoji.Pack.create("test_emoji_pack")
|
||||||
|
|
||||||
|
with_mocks([
|
||||||
|
{File, [:passthrough], [rm_rf: fn ^path_pack -> {:error, :eacces, path_pack} end]}
|
||||||
|
]) do
|
||||||
|
assert admin_conn
|
||||||
|
|> delete("/api/pleroma/emoji/pack?name=test_emoji_pack")
|
||||||
|
|> json_response_and_validate_schema(500) == %{
|
||||||
|
"error" =>
|
||||||
|
"Couldn't delete the `test_emoji_pack` pack (POSIX error: Permission denied)"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
after
|
||||||
|
File.rm_rf(path_pack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "creating and deleting a pack", %{admin_conn: admin_conn} do
|
test "creating and deleting a pack", %{admin_conn: admin_conn} do
|
||||||
assert admin_conn
|
assert admin_conn
|
||||||
|> post("/api/pleroma/emoji/pack?name=test_created")
|
|> post("/api/pleroma/emoji/pack?name=test_created")
|
||||||
|
|
Loading…
Reference in a new issue