Cleanup Pleroma.Emoji.Pack
This commit is contained in:
parent
6e4de715b3
commit
8bde8dfec2
|
@ -16,162 +16,78 @@ defmodule Pleroma.Emoji.Pack do
|
||||||
|
|
||||||
alias Pleroma.Emoji
|
alias Pleroma.Emoji
|
||||||
|
|
||||||
@spec emoji_path() :: Path.t()
|
|
||||||
def emoji_path do
|
|
||||||
static = Pleroma.Config.get!([:instance, :static_dir])
|
|
||||||
Path.join(static, "emoji")
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec create(String.t()) :: :ok | {:error, File.posix()} | {:error, :empty_values}
|
@spec create(String.t()) :: :ok | {:error, File.posix()} | {:error, :empty_values}
|
||||||
def create(name) when byte_size(name) > 0 do
|
def create(name) do
|
||||||
dir = Path.join(emoji_path(), name)
|
with :ok <- validate_not_empty([name]),
|
||||||
|
dir <- Path.join(emoji_path(), name),
|
||||||
with :ok <- File.mkdir(dir) do
|
:ok <- File.mkdir(dir) do
|
||||||
%__MODULE__{
|
%__MODULE__{pack_file: Path.join(dir, "pack.json")}
|
||||||
pack_file: Path.join(dir, "pack.json")
|
|
||||||
}
|
|
||||||
|> save_pack()
|
|> save_pack()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(_), do: {:error, :empty_values}
|
@spec show(String.t()) :: {:ok, t()} | {:error, atom()}
|
||||||
|
def show(name) do
|
||||||
@spec show(String.t()) :: {:ok, t()} | {:loaded, nil} | {:error, :empty_values}
|
with :ok <- validate_not_empty([name]),
|
||||||
def show(name) when byte_size(name) > 0 do
|
{:ok, pack} <- load_pack(name) do
|
||||||
with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)},
|
{:ok, validate_pack(pack)}
|
||||||
{_, pack} <- validate_pack(pack) do
|
|
||||||
{:ok, pack}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show(_), do: {:error, :empty_values}
|
|
||||||
|
|
||||||
@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) when byte_size(name) > 0 do
|
def delete(name) do
|
||||||
|
with :ok <- validate_not_empty([name]) do
|
||||||
emoji_path()
|
emoji_path()
|
||||||
|> Path.join(name)
|
|> Path.join(name)
|
||||||
|> File.rm_rf()
|
|> File.rm_rf()
|
||||||
end
|
end
|
||||||
|
end
|
||||||
def delete(_), do: {:error, :empty_values}
|
|
||||||
|
|
||||||
@spec add_file(String.t(), String.t(), Path.t(), Plug.Upload.t() | String.t()) ::
|
@spec add_file(String.t(), String.t(), Path.t(), Plug.Upload.t() | String.t()) ::
|
||||||
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
|
{:ok, t()} | {:error, File.posix() | atom()}
|
||||||
def add_file(name, shortcode, filename, file)
|
def add_file(name, shortcode, filename, file) do
|
||||||
when byte_size(name) > 0 and byte_size(shortcode) > 0 and byte_size(filename) > 0 do
|
with :ok <- validate_not_empty([name, shortcode, filename]),
|
||||||
with {_, nil} <- {:exists, Emoji.get(shortcode)},
|
:ok <- validate_emoji_not_exists(shortcode),
|
||||||
{_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)} do
|
{:ok, pack} <- load_pack(name),
|
||||||
file_path = Path.join(pack.path, filename)
|
:ok <- save_file(file, pack, filename),
|
||||||
|
{:ok, updated_pack} <- pack |> put_emoji(shortcode, filename) |> save_pack() do
|
||||||
create_subdirs(file_path)
|
|
||||||
|
|
||||||
case file do
|
|
||||||
%Plug.Upload{path: upload_path} ->
|
|
||||||
# Copy the uploaded file from the temporary directory
|
|
||||||
File.copy!(upload_path, file_path)
|
|
||||||
|
|
||||||
url when is_binary(url) ->
|
|
||||||
# Download and write the file
|
|
||||||
file_contents = Tesla.get!(url).body
|
|
||||||
File.write!(file_path, file_contents)
|
|
||||||
end
|
|
||||||
|
|
||||||
files = Map.put(pack.files, shortcode, filename)
|
|
||||||
|
|
||||||
updated_pack = %{pack | files: files}
|
|
||||||
|
|
||||||
case save_pack(updated_pack) do
|
|
||||||
:ok ->
|
|
||||||
Emoji.reload()
|
Emoji.reload()
|
||||||
{:ok, updated_pack}
|
{:ok, updated_pack}
|
||||||
|
|
||||||
e ->
|
|
||||||
e
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_file(_, _, _, _), do: {:error, :empty_values}
|
|
||||||
|
|
||||||
defp create_subdirs(file_path) do
|
|
||||||
if String.contains?(file_path, "/") do
|
|
||||||
file_path
|
|
||||||
|> Path.dirname()
|
|
||||||
|> File.mkdir_p!()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec delete_file(String.t(), String.t()) ::
|
@spec delete_file(String.t(), String.t()) ::
|
||||||
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
|
{:ok, t()} | {:error, File.posix() | atom()}
|
||||||
def delete_file(name, shortcode) when byte_size(name) > 0 and byte_size(shortcode) > 0 do
|
def delete_file(name, shortcode) do
|
||||||
with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)},
|
with :ok <- validate_not_empty([name, shortcode]),
|
||||||
{_, {filename, files}} when not is_nil(filename) <-
|
{:ok, pack} <- load_pack(name),
|
||||||
{:exists, Map.pop(pack.files, shortcode)},
|
:ok <- remove_file(pack, shortcode),
|
||||||
emoji <- Path.join(pack.path, filename),
|
{:ok, updated_pack} <- pack |> delete_emoji(shortcode) |> save_pack() do
|
||||||
{_, true} <- {:exists, File.exists?(emoji)} do
|
|
||||||
emoji_dir = Path.dirname(emoji)
|
|
||||||
|
|
||||||
File.rm!(emoji)
|
|
||||||
|
|
||||||
if String.contains?(filename, "/") and File.ls!(emoji_dir) == [] do
|
|
||||||
File.rmdir!(emoji_dir)
|
|
||||||
end
|
|
||||||
|
|
||||||
updated_pack = %{pack | files: files}
|
|
||||||
|
|
||||||
case save_pack(updated_pack) do
|
|
||||||
:ok ->
|
|
||||||
Emoji.reload()
|
Emoji.reload()
|
||||||
{:ok, updated_pack}
|
{:ok, updated_pack}
|
||||||
|
|
||||||
e ->
|
|
||||||
e
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def delete_file(_, _), do: {:error, :empty_values}
|
|
||||||
|
|
||||||
@spec update_file(String.t(), String.t(), String.t(), String.t(), boolean()) ::
|
@spec update_file(String.t(), String.t(), String.t(), String.t(), boolean()) ::
|
||||||
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
|
{:ok, t()} | {:error, File.posix() | atom()}
|
||||||
def update_file(name, shortcode, new_shortcode, new_filename, force)
|
def update_file(name, shortcode, new_shortcode, new_filename, force) do
|
||||||
when byte_size(name) > 0 and byte_size(shortcode) > 0 and byte_size(new_shortcode) > 0 and
|
with :ok <- validate_not_empty([name, shortcode, new_shortcode, new_filename]),
|
||||||
byte_size(new_filename) > 0 do
|
{:ok, pack} <- load_pack(name),
|
||||||
with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)},
|
{:ok, filename} <- get_filename(pack, shortcode),
|
||||||
{_, {filename, files}} when not is_nil(filename) <-
|
:ok <- validate_emoji_not_exists(new_shortcode, force),
|
||||||
{:exists, Map.pop(pack.files, shortcode)},
|
:ok <- rename_file(pack, filename, new_filename),
|
||||||
{_, true} <- {:not_used, force or is_nil(Emoji.get(new_shortcode))} do
|
{:ok, updated_pack} <-
|
||||||
old_path = Path.join(pack.path, filename)
|
pack
|
||||||
old_dir = Path.dirname(old_path)
|
|> delete_emoji(shortcode)
|
||||||
new_path = Path.join(pack.path, new_filename)
|
|> put_emoji(new_shortcode, new_filename)
|
||||||
|
|> save_pack() do
|
||||||
create_subdirs(new_path)
|
|
||||||
|
|
||||||
:ok = File.rename(old_path, new_path)
|
|
||||||
|
|
||||||
if String.contains?(filename, "/") and File.ls!(old_dir) == [] do
|
|
||||||
File.rmdir!(old_dir)
|
|
||||||
end
|
|
||||||
|
|
||||||
files = Map.put(files, new_shortcode, new_filename)
|
|
||||||
|
|
||||||
updated_pack = %{pack | files: files}
|
|
||||||
|
|
||||||
case save_pack(updated_pack) do
|
|
||||||
:ok ->
|
|
||||||
Emoji.reload()
|
Emoji.reload()
|
||||||
{:ok, updated_pack}
|
{:ok, updated_pack}
|
||||||
|
|
||||||
e ->
|
|
||||||
e
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_file(_, _, _, _, _), do: {:error, :empty_values}
|
@spec import_from_filesystem() :: {:ok, [String.t()]} | {:error, File.posix() | atom()}
|
||||||
|
|
||||||
@spec import_from_filesystem() :: {:ok, [String.t()]} | {:error, atom()}
|
|
||||||
def import_from_filesystem do
|
def import_from_filesystem do
|
||||||
emoji_path = emoji_path()
|
emoji_path = emoji_path()
|
||||||
|
|
||||||
|
@ -184,7 +100,7 @@ def import_from_filesystem do
|
||||||
File.dir?(path) and File.exists?(Path.join(path, "pack.json"))
|
File.dir?(path) and File.exists?(Path.join(path, "pack.json"))
|
||||||
end)
|
end)
|
||||||
|> Enum.map(&write_pack_contents/1)
|
|> Enum.map(&write_pack_contents/1)
|
||||||
|> Enum.filter(& &1)
|
|> Enum.reject(&is_nil/1)
|
||||||
|
|
||||||
{:ok, names}
|
{:ok, names}
|
||||||
else
|
else
|
||||||
|
@ -193,6 +109,117 @@ def import_from_filesystem do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec list_remote(String.t()) :: {:ok, map()} | {:error, atom()}
|
||||||
|
def list_remote(url) do
|
||||||
|
uri = url |> String.trim() |> URI.parse()
|
||||||
|
|
||||||
|
with :ok <- validate_shareable_packs_available(uri) do
|
||||||
|
uri
|
||||||
|
|> URI.merge("/api/pleroma/emoji/packs")
|
||||||
|
|> http_get()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec list_local() :: {:ok, map()}
|
||||||
|
def list_local do
|
||||||
|
with {:ok, results} <- list_packs_dir() do
|
||||||
|
packs =
|
||||||
|
results
|
||||||
|
|> Enum.map(fn name ->
|
||||||
|
case load_pack(name) do
|
||||||
|
{:ok, pack} -> pack
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|> Enum.reject(&is_nil/1)
|
||||||
|
|> Map.new(fn pack -> {pack.name, validate_pack(pack)} end)
|
||||||
|
|
||||||
|
{:ok, packs}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_archive(String.t()) :: {:ok, binary()} | {:error, atom()}
|
||||||
|
def get_archive(name) do
|
||||||
|
with {:ok, pack} <- load_pack(name),
|
||||||
|
:ok <- validate_downloadable(pack) do
|
||||||
|
{:ok, fetch_archive(pack)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec download(String.t(), String.t(), String.t()) :: :ok | {:error, atom()}
|
||||||
|
def download(name, url, as) do
|
||||||
|
uri = url |> String.trim() |> URI.parse()
|
||||||
|
|
||||||
|
with :ok <- validate_shareable_packs_available(uri),
|
||||||
|
{:ok, remote_pack} <- uri |> URI.merge("/api/pleroma/emoji/packs/#{name}") |> http_get(),
|
||||||
|
{:ok, %{sha: sha, url: url} = pack_info} <- fetch_pack_info(remote_pack, uri, name),
|
||||||
|
{:ok, archive} <- download_archive(url, sha),
|
||||||
|
pack <- copy_as(remote_pack, as || name),
|
||||||
|
{:ok, _} = unzip(archive, pack_info, remote_pack, pack) do
|
||||||
|
# Fallback can't contain a pack.json file, since that would cause the fallback-src-sha256
|
||||||
|
# in it to depend on itself
|
||||||
|
if pack_info[:fallback] do
|
||||||
|
save_pack(pack)
|
||||||
|
else
|
||||||
|
{:ok, pack}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec save_metadata(map(), t()) :: {:ok, t()} | {:error, File.posix()}
|
||||||
|
def save_metadata(metadata, %__MODULE__{} = pack) do
|
||||||
|
pack
|
||||||
|
|> Map.put(:pack, metadata)
|
||||||
|
|> save_pack()
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec update_metadata(String.t(), map()) :: {:ok, t()} | {:error, File.posix()}
|
||||||
|
def update_metadata(name, data) do
|
||||||
|
with {:ok, pack} <- load_pack(name) do
|
||||||
|
if fallback_sha_changed?(pack, data) do
|
||||||
|
update_sha_and_save_metadata(pack, data)
|
||||||
|
else
|
||||||
|
save_metadata(data, pack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec load_pack(String.t()) :: {:ok, t()} | {:error, :not_found}
|
||||||
|
def load_pack(name) do
|
||||||
|
pack_file = Path.join([emoji_path(), name, "pack.json"])
|
||||||
|
|
||||||
|
if File.exists?(pack_file) do
|
||||||
|
pack =
|
||||||
|
pack_file
|
||||||
|
|> File.read!()
|
||||||
|
|> from_json()
|
||||||
|
|> Map.put(:pack_file, pack_file)
|
||||||
|
|> Map.put(:path, Path.dirname(pack_file))
|
||||||
|
|> Map.put(:name, name)
|
||||||
|
|
||||||
|
{:ok, pack}
|
||||||
|
else
|
||||||
|
{:error, :not_found}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec emoji_path() :: Path.t()
|
||||||
|
defp emoji_path do
|
||||||
|
[:instance, :static_dir]
|
||||||
|
|> Pleroma.Config.get!()
|
||||||
|
|> Path.join("emoji")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_emoji_not_exists(shortcode, force \\ false)
|
||||||
|
defp validate_emoji_not_exists(_shortcode, true), do: :ok
|
||||||
|
|
||||||
|
defp validate_emoji_not_exists(shortcode, _) do
|
||||||
|
case Emoji.get(shortcode) do
|
||||||
|
nil -> :ok
|
||||||
|
_ -> {:error, :already_exists}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp write_pack_contents(path) do
|
defp write_pack_contents(path) do
|
||||||
pack = %__MODULE__{
|
pack = %__MODULE__{
|
||||||
files: files_from_path(path),
|
files: files_from_path(path),
|
||||||
|
@ -201,7 +228,7 @@ defp write_pack_contents(path) do
|
||||||
}
|
}
|
||||||
|
|
||||||
case save_pack(pack) do
|
case save_pack(pack) do
|
||||||
:ok -> Path.basename(path)
|
{:ok, _pack} -> Path.basename(path)
|
||||||
_ -> nil
|
_ -> nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -216,7 +243,8 @@ defp files_from_path(path) do
|
||||||
# FIXME: Copy-pasted from Pleroma.Emoji/load_from_file_stream/2
|
# FIXME: Copy-pasted from Pleroma.Emoji/load_from_file_stream/2
|
||||||
|
|
||||||
# Create a map of shortcodes to filenames from emoji.txt
|
# Create a map of shortcodes to filenames from emoji.txt
|
||||||
File.read!(txt_path)
|
txt_path
|
||||||
|
|> File.read!()
|
||||||
|> String.split("\n")
|
|> String.split("\n")
|
||||||
|> Enum.map(&String.trim/1)
|
|> Enum.map(&String.trim/1)
|
||||||
|> Enum.map(fn line ->
|
|> Enum.map(fn line ->
|
||||||
|
@ -226,21 +254,18 @@ defp files_from_path(path) do
|
||||||
[name, file | _] ->
|
[name, file | _] ->
|
||||||
file_dir_name = Path.dirname(file)
|
file_dir_name = Path.dirname(file)
|
||||||
|
|
||||||
file =
|
|
||||||
if String.ends_with?(path, file_dir_name) do
|
if String.ends_with?(path, file_dir_name) do
|
||||||
Path.basename(file)
|
{name, Path.basename(file)}
|
||||||
else
|
else
|
||||||
file
|
|
||||||
end
|
|
||||||
|
|
||||||
{name, file}
|
{name, file}
|
||||||
|
end
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|> Enum.filter(& &1)
|
|> Enum.reject(&is_nil/1)
|
||||||
|> Enum.into(%{})
|
|> Map.new()
|
||||||
else
|
else
|
||||||
# If there's no emoji.txt, assume all files
|
# If there's no emoji.txt, assume all files
|
||||||
# that are of certain extensions from the config are emojis and import them all
|
# that are of certain extensions from the config are emojis and import them all
|
||||||
|
@ -249,60 +274,20 @@ defp files_from_path(path) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec list_remote(String.t()) :: {:ok, map()}
|
|
||||||
def list_remote(url) do
|
|
||||||
uri =
|
|
||||||
url
|
|
||||||
|> String.trim()
|
|
||||||
|> URI.parse()
|
|
||||||
|
|
||||||
with {_, true} <- {:shareable, shareable_packs_available?(uri)} do
|
|
||||||
packs =
|
|
||||||
uri
|
|
||||||
|> URI.merge("/api/pleroma/emoji/packs")
|
|
||||||
|> to_string()
|
|
||||||
|> Tesla.get!()
|
|
||||||
|> Map.get(:body)
|
|
||||||
|> Jason.decode!()
|
|
||||||
|
|
||||||
{:ok, packs}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec list_local() :: {:ok, map()}
|
|
||||||
def list_local do
|
|
||||||
emoji_path = emoji_path()
|
|
||||||
|
|
||||||
# Create the directory first if it does not exist. This is probably the first request made
|
|
||||||
# with the API so it should be sufficient
|
|
||||||
with {:create_dir, :ok} <- {:create_dir, File.mkdir_p(emoji_path)},
|
|
||||||
{:ls, {:ok, results}} <- {:ls, File.ls(emoji_path)} do
|
|
||||||
packs =
|
|
||||||
results
|
|
||||||
|> Enum.map(&load_pack/1)
|
|
||||||
|> Enum.filter(& &1)
|
|
||||||
|> Enum.map(&validate_pack/1)
|
|
||||||
|> Map.new()
|
|
||||||
|
|
||||||
{:ok, packs}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp validate_pack(pack) do
|
defp validate_pack(pack) do
|
||||||
|
info =
|
||||||
if downloadable?(pack) do
|
if downloadable?(pack) do
|
||||||
archive = fetch_archive(pack)
|
archive = fetch_archive(pack)
|
||||||
archive_sha = :crypto.hash(:sha256, archive) |> Base.encode16()
|
archive_sha = :crypto.hash(:sha256, archive) |> Base.encode16()
|
||||||
|
|
||||||
info =
|
|
||||||
pack.pack
|
pack.pack
|
||||||
|> Map.put("can-download", true)
|
|> Map.put("can-download", true)
|
||||||
|> Map.put("download-sha256", archive_sha)
|
|> Map.put("download-sha256", archive_sha)
|
||||||
|
|
||||||
{pack.name, Map.put(pack, :pack, info)}
|
|
||||||
else
|
else
|
||||||
info = Map.put(pack.pack, "can-download", false)
|
Map.put(pack.pack, "can-download", false)
|
||||||
{pack.name, Map.put(pack, :pack, info)}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Map.put(pack, :pack, info)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp downloadable?(pack) do
|
defp downloadable?(pack) do
|
||||||
|
@ -315,26 +300,6 @@ defp downloadable?(pack) do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec get_archive(String.t()) :: {:ok, binary()}
|
|
||||||
def get_archive(name) do
|
|
||||||
with {_, %__MODULE__{} = pack} <- {:exists?, load_pack(name)},
|
|
||||||
{_, true} <- {:can_download?, downloadable?(pack)} do
|
|
||||||
{:ok, fetch_archive(pack)}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp fetch_archive(pack) do
|
|
||||||
hash = :crypto.hash(:md5, File.read!(pack.pack_file))
|
|
||||||
|
|
||||||
case Cachex.get!(:emoji_packs_cache, pack.name) do
|
|
||||||
%{hash: ^hash, pack_data: archive} ->
|
|
||||||
archive
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
create_archive_and_cache(pack, hash)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp create_archive_and_cache(pack, hash) do
|
defp create_archive_and_cache(pack, hash) do
|
||||||
files = ['pack.json' | Enum.map(pack.files, fn {_, file} -> to_charlist(file) end)]
|
files = ['pack.json' | Enum.map(pack.files, fn {_, file} -> to_charlist(file) end)]
|
||||||
|
|
||||||
|
@ -356,23 +321,158 @@ defp create_archive_and_cache(pack, hash) do
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec download(String.t(), String.t(), String.t()) :: :ok
|
defp save_pack(pack) do
|
||||||
def download(name, url, as) do
|
with {:ok, json} <- Jason.encode(pack, pretty: true),
|
||||||
uri =
|
:ok <- File.write(pack.pack_file, json) do
|
||||||
url
|
{:ok, pack}
|
||||||
|> String.trim()
|
end
|
||||||
|> URI.parse()
|
end
|
||||||
|
|
||||||
with {_, true} <- {:shareable, shareable_packs_available?(uri)} do
|
defp from_json(json) do
|
||||||
remote_pack =
|
map = Jason.decode!(json)
|
||||||
uri
|
|
||||||
|> URI.merge("/api/pleroma/emoji/packs/#{name}")
|
|
||||||
|> to_string()
|
|
||||||
|> Tesla.get!()
|
|
||||||
|> Map.get(:body)
|
|
||||||
|> Jason.decode!()
|
|
||||||
|
|
||||||
result =
|
struct(__MODULE__, %{files: map["files"], pack: map["pack"]})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_shareable_packs_available(uri) do
|
||||||
|
with {:ok, %{"links" => links}} <- uri |> URI.merge("/.well-known/nodeinfo") |> http_get(),
|
||||||
|
# Get the actual nodeinfo address and fetch it
|
||||||
|
{:ok, %{"metadata" => %{"features" => features}}} <-
|
||||||
|
links |> List.last() |> Map.get("href") |> http_get() do
|
||||||
|
if Enum.member?(features, "shareable_emoji_packs") do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
|
{:error, :not_shareable}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_not_empty(list) do
|
||||||
|
if Enum.all?(list, fn i -> is_binary(i) and i != "" end) do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
|
{:error, :empty_values}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp save_file(file, pack, filename) do
|
||||||
|
file_path = Path.join(pack.path, filename)
|
||||||
|
create_subdirs(file_path)
|
||||||
|
|
||||||
|
case file do
|
||||||
|
%Plug.Upload{path: upload_path} ->
|
||||||
|
# Copy the uploaded file from the temporary directory
|
||||||
|
with {:ok, _} <- File.copy(upload_path, file_path), do: :ok
|
||||||
|
|
||||||
|
url when is_binary(url) ->
|
||||||
|
# Download and write the file
|
||||||
|
file_contents = Tesla.get!(url).body
|
||||||
|
File.write(file_path, file_contents)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp put_emoji(pack, shortcode, filename) do
|
||||||
|
files = Map.put(pack.files, shortcode, filename)
|
||||||
|
%{pack | files: files}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp delete_emoji(pack, shortcode) do
|
||||||
|
files = Map.delete(pack.files, shortcode)
|
||||||
|
%{pack | files: files}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp rename_file(pack, filename, new_filename) do
|
||||||
|
old_path = Path.join(pack.path, filename)
|
||||||
|
new_path = Path.join(pack.path, new_filename)
|
||||||
|
create_subdirs(new_path)
|
||||||
|
|
||||||
|
with :ok <- File.rename(old_path, new_path) do
|
||||||
|
remove_dir_if_empty(old_path, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp create_subdirs(file_path) do
|
||||||
|
if String.contains?(file_path, "/") do
|
||||||
|
file_path
|
||||||
|
|> Path.dirname()
|
||||||
|
|> File.mkdir_p!()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp remove_file(pack, shortcode) do
|
||||||
|
with {:ok, filename} <- get_filename(pack, shortcode),
|
||||||
|
emoji <- Path.join(pack.path, filename),
|
||||||
|
:ok <- File.rm(emoji) do
|
||||||
|
remove_dir_if_empty(emoji, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp remove_dir_if_empty(emoji, filename) do
|
||||||
|
dir = Path.dirname(emoji)
|
||||||
|
|
||||||
|
if String.contains?(filename, "/") and File.ls!(dir) == [] do
|
||||||
|
File.rmdir!(dir)
|
||||||
|
else
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_filename(pack, shortcode) do
|
||||||
|
with %{^shortcode => filename} when is_binary(filename) <- pack.files,
|
||||||
|
true <- pack.path |> Path.join(filename) |> File.exists?() do
|
||||||
|
{:ok, filename}
|
||||||
|
else
|
||||||
|
_ -> {:error, :doesnt_exist}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp http_get(%URI{} = url), do: url |> to_string() |> http_get()
|
||||||
|
|
||||||
|
defp http_get(url) do
|
||||||
|
with {:ok, %{body: body}} <- url |> Pleroma.HTTP.get() do
|
||||||
|
Jason.decode(body)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp list_packs_dir do
|
||||||
|
emoji_path = emoji_path()
|
||||||
|
# Create the directory first if it does not exist. This is probably the first request made
|
||||||
|
# with the API so it should be sufficient
|
||||||
|
with {:create_dir, :ok} <- {:create_dir, File.mkdir_p(emoji_path)},
|
||||||
|
{:ls, {:ok, results}} <- {:ls, File.ls(emoji_path)} do
|
||||||
|
{:ok, results}
|
||||||
|
else
|
||||||
|
{:create_dir, {:error, e}} -> {:error, :create_dir, e}
|
||||||
|
{:ls, {:error, e}} -> {:error, :ls, e}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_downloadable(pack) do
|
||||||
|
if downloadable?(pack), do: :ok, else: {:error, :cant_download}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp copy_as(remote_pack, local_name) do
|
||||||
|
path = Path.join(emoji_path(), local_name)
|
||||||
|
|
||||||
|
%__MODULE__{
|
||||||
|
name: local_name,
|
||||||
|
path: path,
|
||||||
|
files: remote_pack["files"],
|
||||||
|
pack_file: Path.join(path, "pack.json")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp unzip(archive, pack_info, remote_pack, local_pack) do
|
||||||
|
with :ok <- File.mkdir_p!(local_pack.path) do
|
||||||
|
files = Enum.map(remote_pack["files"], fn {_, path} -> to_charlist(path) end)
|
||||||
|
# Fallback cannot contain a pack.json file
|
||||||
|
files = if pack_info[:fallback], do: files, else: ['pack.json' | files]
|
||||||
|
|
||||||
|
:zip.unzip(archive, cwd: to_charlist(local_pack.path), file_list: files)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp fetch_pack_info(remote_pack, uri, name) do
|
||||||
case remote_pack["pack"] do
|
case remote_pack["pack"] do
|
||||||
%{"share-files" => true, "can-download" => true, "download-sha256" => sha} ->
|
%{"share-files" => true, "can-download" => true, "download-sha256" => sha} ->
|
||||||
{:ok,
|
{:ok,
|
||||||
|
@ -390,118 +490,52 @@ def download(name, url, as) do
|
||||||
}}
|
}}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
{:error,
|
{:error, "The pack was not set as shared and there is no fallback src to download from"}
|
||||||
"The pack was not set as shared and there is no fallback src to download from"}
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
with {:ok, %{sha: sha, url: url} = pinfo} <- result,
|
defp download_archive(url, sha) do
|
||||||
%{body: archive} <- Tesla.get!(url),
|
with {:ok, %{body: archive}} <- Tesla.get(url) do
|
||||||
{_, true} <- {:checksum, Base.decode16!(sha) == :crypto.hash(:sha256, archive)} do
|
if Base.decode16!(sha) == :crypto.hash(:sha256, archive) do
|
||||||
local_name = as || name
|
{:ok, archive}
|
||||||
|
else
|
||||||
path = Path.join(emoji_path(), local_name)
|
{:error, :imvalid_checksum}
|
||||||
|
|
||||||
pack = %__MODULE__{
|
|
||||||
name: local_name,
|
|
||||||
path: path,
|
|
||||||
files: remote_pack["files"],
|
|
||||||
pack_file: Path.join(path, "pack.json")
|
|
||||||
}
|
|
||||||
|
|
||||||
File.mkdir_p!(pack.path)
|
|
||||||
|
|
||||||
files = Enum.map(remote_pack["files"], fn {_, path} -> to_charlist(path) end)
|
|
||||||
# Fallback cannot contain a pack.json file
|
|
||||||
files = if pinfo[:fallback], do: files, else: ['pack.json' | files]
|
|
||||||
|
|
||||||
{:ok, _} = :zip.unzip(archive, cwd: to_charlist(pack.path), file_list: files)
|
|
||||||
|
|
||||||
# Fallback can't contain a pack.json file, since that would cause the fallback-src-sha256
|
|
||||||
# in it to depend on itself
|
|
||||||
if pinfo[:fallback] do
|
|
||||||
save_pack(pack)
|
|
||||||
end
|
|
||||||
|
|
||||||
:ok
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp save_pack(pack), do: File.write(pack.pack_file, Jason.encode!(pack, pretty: true))
|
defp fetch_archive(pack) do
|
||||||
|
hash = :crypto.hash(:md5, File.read!(pack.pack_file))
|
||||||
|
|
||||||
@spec save_metadata(map(), t()) :: {:ok, t()} | {:error, File.posix()}
|
case Cachex.get!(:emoji_packs_cache, pack.name) do
|
||||||
def save_metadata(metadata, %__MODULE__{} = pack) do
|
%{hash: ^hash, pack_data: archive} -> archive
|
||||||
pack = Map.put(pack, :pack, metadata)
|
_ -> create_archive_and_cache(pack, hash)
|
||||||
|
|
||||||
with :ok <- save_pack(pack) do
|
|
||||||
{:ok, pack}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec update_metadata(String.t(), map()) :: {:ok, t()} | {:error, File.posix()}
|
defp fallback_sha_changed?(pack, data) do
|
||||||
def update_metadata(name, data) do
|
is_binary(data[:"fallback-src"]) and data[:"fallback-src"] != pack.pack["fallback-src"]
|
||||||
pack = load_pack(name)
|
end
|
||||||
|
|
||||||
fb_sha_changed? =
|
defp update_sha_and_save_metadata(pack, data) do
|
||||||
not is_nil(data[:"fallback-src"]) and data[:"fallback-src"] != pack.pack[:"fallback-src"]
|
with {:ok, %{body: zip}} <- Tesla.get(data[:"fallback-src"]),
|
||||||
|
:ok <- validate_has_all_files(pack, zip) do
|
||||||
with {_, true} <- {:update?, fb_sha_changed?},
|
fallback_sha = :sha256 |> :crypto.hash(zip) |> Base.encode16()
|
||||||
{:ok, %{body: zip}} <- Tesla.get(data[:"fallback-src"]),
|
|
||||||
{:ok, f_list} <- :zip.unzip(zip, [:memory]),
|
|
||||||
{_, true} <- {:has_all_files?, has_all_files?(pack.files, f_list)} do
|
|
||||||
fallback_sha = :crypto.hash(:sha256, zip) |> Base.encode16()
|
|
||||||
|
|
||||||
data
|
data
|
||||||
|> Map.put("fallback-src-sha256", fallback_sha)
|
|> Map.put("fallback-src-sha256", fallback_sha)
|
||||||
|> save_metadata(pack)
|
|> save_metadata(pack)
|
||||||
else
|
|
||||||
{:update?, _} -> save_metadata(data, pack)
|
|
||||||
e -> e
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp validate_has_all_files(pack, zip) do
|
||||||
|
with {:ok, f_list} <- :zip.unzip(zip, [:memory]) do
|
||||||
# Check if all files from the pack.json are in the archive
|
# Check if all files from the pack.json are in the archive
|
||||||
defp has_all_files?(files, f_list) do
|
pack.files
|
||||||
Enum.all?(files, fn {_, from_manifest} ->
|
|> Enum.all?(fn {_, from_manifest} ->
|
||||||
List.keyfind(f_list, to_charlist(from_manifest), 0)
|
List.keyfind(f_list, to_charlist(from_manifest), 0)
|
||||||
end)
|
end)
|
||||||
|
|> if(do: :ok, else: {:error, :incomplete})
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec load_pack(String.t()) :: t() | nil
|
|
||||||
def load_pack(name) do
|
|
||||||
pack_file = Path.join([emoji_path(), name, "pack.json"])
|
|
||||||
|
|
||||||
if File.exists?(pack_file) do
|
|
||||||
pack_file
|
|
||||||
|> File.read!()
|
|
||||||
|> from_json()
|
|
||||||
|> Map.put(:pack_file, pack_file)
|
|
||||||
|> Map.put(:path, Path.dirname(pack_file))
|
|
||||||
|> Map.put(:name, name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp from_json(json) do
|
|
||||||
map = Jason.decode!(json)
|
|
||||||
|
|
||||||
struct(__MODULE__, %{files: map["files"], pack: map["pack"]})
|
|
||||||
end
|
|
||||||
|
|
||||||
defp shareable_packs_available?(uri) do
|
|
||||||
uri
|
|
||||||
|> URI.merge("/.well-known/nodeinfo")
|
|
||||||
|> to_string()
|
|
||||||
|> Tesla.get!()
|
|
||||||
|> Map.get(:body)
|
|
||||||
|> Jason.decode!()
|
|
||||||
|> Map.get("links")
|
|
||||||
|> List.last()
|
|
||||||
|> Map.get("href")
|
|
||||||
# Get the actual nodeinfo address and fetch it
|
|
||||||
|> Tesla.get!()
|
|
||||||
|> Map.get(:body)
|
|
||||||
|> Jason.decode!()
|
|
||||||
|> get_in(["metadata", "features"])
|
|
||||||
|> Enum.member?("shareable_emoji_packs")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ def remote(conn, %{url: url}) do
|
||||||
with {:ok, packs} <- Pack.list_remote(url) do
|
with {:ok, packs} <- Pack.list_remote(url) do
|
||||||
json(conn, packs)
|
json(conn, packs)
|
||||||
else
|
else
|
||||||
{:shareable, _} ->
|
{:error, :not_shareable} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:internal_server_error)
|
|> put_status(:internal_server_error)
|
||||||
|> json(%{error: "The requested instance does not support sharing emoji packs"})
|
|> json(%{error: "The requested instance does not support sharing emoji packs"})
|
||||||
|
@ -46,12 +46,12 @@ def index(conn, _params) do
|
||||||
with {:ok, packs} <- Pack.list_local() do
|
with {:ok, packs} <- Pack.list_local() do
|
||||||
json(conn, packs)
|
json(conn, packs)
|
||||||
else
|
else
|
||||||
{:create_dir, {:error, e}} ->
|
{:error, :create_dir, e} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:internal_server_error)
|
|> put_status(:internal_server_error)
|
||||||
|> json(%{error: "Failed to create the emoji pack directory at #{emoji_path}: #{e}"})
|
|> json(%{error: "Failed to create the emoji pack directory at #{emoji_path}: #{e}"})
|
||||||
|
|
||||||
{:ls, {:error, e}} ->
|
{:error, :ls, e} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:internal_server_error)
|
|> put_status(:internal_server_error)
|
||||||
|> json(%{
|
|> json(%{
|
||||||
|
@ -66,7 +66,7 @@ def show(conn, %{name: name}) do
|
||||||
with {:ok, pack} <- Pack.show(name) do
|
with {:ok, pack} <- Pack.show(name) do
|
||||||
json(conn, pack)
|
json(conn, pack)
|
||||||
else
|
else
|
||||||
{:loaded, _} ->
|
{:error, :not_found} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|> json(%{error: "Pack #{name} does not exist"})
|
|> json(%{error: "Pack #{name} does not exist"})
|
||||||
|
@ -82,7 +82,7 @@ def archive(conn, %{name: name}) do
|
||||||
with {:ok, archive} <- Pack.get_archive(name) do
|
with {:ok, archive} <- Pack.get_archive(name) do
|
||||||
send_download(conn, {:binary, archive}, filename: "#{name}.zip")
|
send_download(conn, {:binary, archive}, filename: "#{name}.zip")
|
||||||
else
|
else
|
||||||
{:can_download?, _} ->
|
{:error, :cant_download} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:forbidden)
|
|> put_status(:forbidden)
|
||||||
|> json(%{
|
|> json(%{
|
||||||
|
@ -90,7 +90,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"
|
||||||
})
|
})
|
||||||
|
|
||||||
{:exists?, _} ->
|
{:error, :not_found} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|> json(%{error: "Pack #{name} does not exist"})
|
|> json(%{error: "Pack #{name} does not exist"})
|
||||||
|
@ -98,15 +98,15 @@ def archive(conn, %{name: name}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def download(%{body_params: %{url: url, name: name} = params} = conn, _) do
|
def download(%{body_params: %{url: url, name: name} = params} = conn, _) do
|
||||||
with :ok <- Pack.download(name, url, params[:as]) do
|
with {:ok, _pack} <- Pack.download(name, url, params[:as]) do
|
||||||
json(conn, "ok")
|
json(conn, "ok")
|
||||||
else
|
else
|
||||||
{:shareable, _} ->
|
{:error, :not_shareable} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:internal_server_error)
|
|> put_status(:internal_server_error)
|
||||||
|> json(%{error: "The requested instance does not support sharing emoji packs"})
|
|> json(%{error: "The requested instance does not support sharing emoji packs"})
|
||||||
|
|
||||||
{:checksum, _} ->
|
{:error, :imvalid_checksum} ->
|
||||||
conn
|
conn
|
||||||
|> 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"})
|
||||||
|
@ -121,7 +121,7 @@ def download(%{body_params: %{url: url, name: name} = params} = conn, _) do
|
||||||
def create(conn, %{name: name}) do
|
def create(conn, %{name: name}) do
|
||||||
name = String.trim(name)
|
name = String.trim(name)
|
||||||
|
|
||||||
with :ok <- Pack.create(name) do
|
with {:ok, _pack} <- Pack.create(name) do
|
||||||
json(conn, "ok")
|
json(conn, "ok")
|
||||||
else
|
else
|
||||||
{:error, :eexist} ->
|
{:error, :eexist} ->
|
||||||
|
@ -170,7 +170,7 @@ def update(%{body_params: %{metadata: metadata}} = conn, %{name: name}) do
|
||||||
with {:ok, pack} <- Pack.update_metadata(name, metadata) do
|
with {:ok, pack} <- Pack.update_metadata(name, metadata) do
|
||||||
json(conn, pack.pack)
|
json(conn, pack.pack)
|
||||||
else
|
else
|
||||||
{:has_all_files?, _} ->
|
{:error, :incomplete} ->
|
||||||
conn
|
conn
|
||||||
|> 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"})
|
||||||
|
@ -191,12 +191,12 @@ def add_file(%{body_params: params} = conn, %{name: name}) do
|
||||||
with {:ok, pack} <- Pack.add_file(name, shortcode, filename, params[:file]) do
|
with {:ok, pack} <- Pack.add_file(name, shortcode, filename, params[:file]) do
|
||||||
json(conn, pack.files)
|
json(conn, pack.files)
|
||||||
else
|
else
|
||||||
{:exists, _} ->
|
{:error, :already_exists} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:conflict)
|
|> put_status(:conflict)
|
||||||
|> json(%{error: "An emoji with the \"#{shortcode}\" shortcode already exists"})
|
|> json(%{error: "An emoji with the \"#{shortcode}\" shortcode already exists"})
|
||||||
|
|
||||||
{:loaded, _} ->
|
{:error, :not_found} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "pack \"#{name}\" is not found"})
|
|> json(%{error: "pack \"#{name}\" is not found"})
|
||||||
|
@ -223,12 +223,12 @@ def update_file(%{body_params: %{shortcode: shortcode} = params} = conn, %{name:
|
||||||
with {:ok, pack} <- Pack.update_file(name, shortcode, new_shortcode, new_filename, force) do
|
with {:ok, pack} <- Pack.update_file(name, shortcode, new_shortcode, new_filename, force) do
|
||||||
json(conn, pack.files)
|
json(conn, pack.files)
|
||||||
else
|
else
|
||||||
{:exists, _} ->
|
{:error, :doesnt_exist} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
|
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
|
||||||
|
|
||||||
{:not_used, _} ->
|
{:error, :already_exists} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:conflict)
|
|> put_status(:conflict)
|
||||||
|> json(%{
|
|> json(%{
|
||||||
|
@ -236,7 +236,7 @@ def update_file(%{body_params: %{shortcode: shortcode} = params} = conn, %{name:
|
||||||
"New shortcode \"#{new_shortcode}\" is already used. If you want to override emoji use 'force' option"
|
"New shortcode \"#{new_shortcode}\" is already used. If you want to override emoji use 'force' option"
|
||||||
})
|
})
|
||||||
|
|
||||||
{:loaded, _} ->
|
{:error, :not_found} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "pack \"#{name}\" is not found"})
|
|> json(%{error: "pack \"#{name}\" is not found"})
|
||||||
|
@ -259,12 +259,12 @@ def delete_file(conn, %{name: name, shortcode: shortcode}) do
|
||||||
with {:ok, pack} <- Pack.delete_file(name, shortcode) do
|
with {:ok, pack} <- Pack.delete_file(name, shortcode) do
|
||||||
json(conn, pack.files)
|
json(conn, pack.files)
|
||||||
else
|
else
|
||||||
{:exists, _} ->
|
{:error, :doesnt_exist} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
|
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
|
||||||
|
|
||||||
{:loaded, _} ->
|
{:error, :not_found} ->
|
||||||
conn
|
conn
|
||||||
|> put_status(:bad_request)
|
|> put_status(:bad_request)
|
||||||
|> json(%{error: "pack \"#{name}\" is not found"})
|
|> json(%{error: "pack \"#{name}\" is not found"})
|
||||||
|
|
|
@ -234,10 +234,8 @@ test "checksum fail", %{admin_conn: admin_conn} do
|
||||||
method: :get,
|
method: :get,
|
||||||
url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha"
|
url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha"
|
||||||
} ->
|
} ->
|
||||||
%Tesla.Env{
|
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha")
|
||||||
status: 200,
|
%Tesla.Env{status: 200, body: Jason.encode!(pack)}
|
||||||
body: Pleroma.Emoji.Pack.load_pack("pack_bad_sha") |> Jason.encode!()
|
|
||||||
}
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
method: :get,
|
method: :get,
|
||||||
|
@ -273,10 +271,8 @@ test "other error", %{admin_conn: admin_conn} do
|
||||||
method: :get,
|
method: :get,
|
||||||
url: "https://example.com/api/pleroma/emoji/packs/test_pack"
|
url: "https://example.com/api/pleroma/emoji/packs/test_pack"
|
||||||
} ->
|
} ->
|
||||||
%Tesla.Env{
|
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack")
|
||||||
status: 200,
|
%Tesla.Env{status: 200, body: Jason.encode!(pack)}
|
||||||
body: Pleroma.Emoji.Pack.load_pack("test_pack") |> Jason.encode!()
|
|
||||||
}
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert admin_conn
|
assert admin_conn
|
||||||
|
|
Loading…
Reference in New Issue