aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEkaterina Vaartis <vaartis@cock.li>2019-08-18 22:05:38 +0300
committerEkaterina Vaartis <vaartis@cock.li>2019-09-19 00:16:33 +0300
commit9afe7258dd5ca1e5a6333a5a9f93d9ab43d4aaf4 (patch)
tree82efa68d308e97a439bd57eaa7ed4fc064fcd29c
parent261d92f9c2605c720e7fce8b05025e5ac452e5c9 (diff)
downloadpleroma-9afe7258dd5ca1e5a6333a5a9f93d9ab43d4aaf4.tar.gz
Implememt emoji pack file updating + write tests
-rw-r--r--lib/pleroma/web/emoji_api/emoji_api_controller.ex132
-rw-r--r--lib/pleroma/web/router.ex3
-rw-r--r--test/web/emoji_api_controller_test.exs69
3 files changed, 196 insertions, 8 deletions
diff --git a/lib/pleroma/web/emoji_api/emoji_api_controller.ex b/lib/pleroma/web/emoji_api/emoji_api_controller.ex
index 4873129c4..dc3dcf1ea 100644
--- a/lib/pleroma/web/emoji_api/emoji_api_controller.ex
+++ b/lib/pleroma/web/emoji_api/emoji_api_controller.ex
@@ -223,7 +223,7 @@ keeping it in cache for #{div(cache_ms, 1000)}s")
end
end
- def update_metadata(conn, %{"name" => name, "new_data" => new_data}) do
+ def update_metadata(conn, %{"pack_name" => name, "new_data" => new_data}) do
pack_dir = Path.join(@emoji_dir_path, name)
pack_file_p = Path.join(pack_dir, "pack.json")
@@ -274,4 +274,134 @@ keeping it in cache for #{div(cache_ms, 1000)}s")
e
end
end
+
+ def update_file(
+ conn,
+ %{"pack_name" => pack_name, "action" => action, "shortcode" => shortcode} = params
+ ) do
+ pack_dir = Path.join(@emoji_dir_path, pack_name)
+ pack_file_p = Path.join(pack_dir, "pack.json")
+
+ full_pack = Jason.decode!(File.read!(pack_file_p))
+
+ res =
+ case action do
+ "add" ->
+ unless Map.has_key?(full_pack["files"], shortcode) do
+ with %{"file" => %Plug.Upload{filename: filename, path: upload_path}} <- params do
+ # If there was a file name provided with the request, use it, otherwise just use the
+ # uploaded file name
+ filename =
+ if Map.has_key?(params, "filename") do
+ params["filename"]
+ else
+ filename
+ end
+
+ file_path = Path.join(pack_dir, filename)
+
+ # If the name contains directories, create them
+ if String.contains?(file_path, "/") do
+ File.mkdir_p!(Path.dirname(file_path))
+ end
+
+ # Copy the uploaded file from the temporary directory
+ File.copy!(upload_path, file_path)
+
+ updated_full_pack = put_in(full_pack, ["files", shortcode], filename)
+
+ {:ok, updated_full_pack}
+ else
+ _ -> {:error, conn |> put_status(:bad_request) |> text("\"file\" not provided")}
+ end
+ else
+ {:error,
+ conn
+ |> put_status(:conflict)
+ |> text("An emoji with the \"#{shortcode}\" shortcode already exists")}
+ end
+
+ "remove" ->
+ if Map.has_key?(full_pack["files"], shortcode) do
+ {emoji_file_path, updated_full_pack} = pop_in(full_pack, ["files", shortcode])
+
+ emoji_file_path = Path.join(pack_dir, emoji_file_path)
+
+ # Delete the emoji file
+ File.rm!(emoji_file_path)
+
+ # If the old directory has no more files, remove it
+ if String.contains?(emoji_file_path, "/") do
+ dir = Path.dirname(emoji_file_path)
+
+ if Enum.empty?(File.ls!(dir)) do
+ File.rmdir!(dir)
+ end
+ end
+
+ {:ok, updated_full_pack}
+ else
+ {:error,
+ conn |> put_status(:bad_request) |> text("Emoji \"#{shortcode}\" does not exist")}
+ end
+
+ "update" ->
+ if Map.has_key?(full_pack["files"], shortcode) do
+ with %{"new_shortcode" => new_shortcode, "new_filename" => new_filename} <- params do
+ # First, remove the old shortcode, saving the old path
+ {old_emoji_file_path, updated_full_pack} = pop_in(full_pack, ["files", shortcode])
+ old_emoji_file_path = Path.join(pack_dir, old_emoji_file_path)
+ new_emoji_file_path = Path.join(pack_dir, new_filename)
+
+ # If the name contains directories, create them
+ if String.contains?(new_emoji_file_path, "/") do
+ File.mkdir_p!(Path.dirname(new_emoji_file_path))
+ end
+
+ # Move/Rename the old filename to a new filename
+ # These are probably on the same filesystem, so just rename should work
+ :ok = File.rename(old_emoji_file_path, new_emoji_file_path)
+
+ # If the old directory has no more files, remove it
+ if String.contains?(old_emoji_file_path, "/") do
+ dir = Path.dirname(old_emoji_file_path)
+
+ if Enum.empty?(File.ls!(dir)) do
+ File.rmdir!(dir)
+ end
+ end
+
+ # Then, put in the new shortcode with the new path
+ updated_full_pack =
+ put_in(updated_full_pack, ["files", new_shortcode], new_filename)
+
+ {:ok, updated_full_pack}
+ else
+ _ ->
+ {:error,
+ conn
+ |> put_status(:bad_request)
+ |> text("new_shortcode or new_file were not specified")}
+ end
+ else
+ {:error,
+ conn |> put_status(:bad_request) |> text("Emoji \"#{shortcode}\" does not exist")}
+ end
+
+ _ ->
+ {:error, conn |> put_status(:bad_request) |> text("Unknown action: #{action}")}
+ end
+
+ case res do
+ {:ok, updated_full_pack} ->
+ # Write the emoji pack file
+ File.write!(pack_file_p, Jason.encode!(updated_full_pack, pretty: true))
+
+ # Return the modified file list
+ conn |> json(updated_full_pack["files"])
+
+ {:error, e} ->
+ e
+ end
+ end
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 471d09c43..acd6f740b 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -218,7 +218,8 @@ defmodule Pleroma.Web.Router do
# Modifying packs
pipe_through([:admin_api, :oauth_write])
- post("/update_metadata/:name", EmojiAPIController, :update_metadata)
+ post("/update_file/:pack_name", EmojiAPIController, :update_file)
+ post("/update_metadata/:pack_name", EmojiAPIController, :update_metadata)
delete("/delete/:name", EmojiAPIController, :delete)
post("/download_from", EmojiAPIController, :download_from)
end
diff --git a/test/web/emoji_api_controller_test.exs b/test/web/emoji_api_controller_test.exs
index 759a4dc04..6d3603da5 100644
--- a/test/web/emoji_api_controller_test.exs
+++ b/test/web/emoji_api_controller_test.exs
@@ -85,11 +85,10 @@ defmodule Pleroma.Web.EmojiAPI.EmojiAPIControllerTest do
admin = insert(:user, info: %{is_admin: true})
- conn = build_conn()
+ conn = build_conn() |> assign(:user, admin)
assert conn
|> put_req_header("content-type", "application/json")
- |> assign(:user, admin)
|> post(
emoji_api_path(
conn,
@@ -108,7 +107,6 @@ defmodule Pleroma.Web.EmojiAPI.EmojiAPIControllerTest do
assert File.exists?("#{@emoji_dir_path}/test_pack2/blank.png")
assert conn
- |> assign(:user, admin)
|> delete(emoji_api_path(conn, :delete, "test_pack2"))
|> response(200) == "ok"
@@ -116,11 +114,10 @@ defmodule Pleroma.Web.EmojiAPI.EmojiAPIControllerTest do
# non-shared, downloaded from the fallback URL
- conn = build_conn()
+ conn = build_conn() |> assign(:user, admin)
assert conn
|> put_req_header("content-type", "application/json")
- |> assign(:user, admin)
|> post(
emoji_api_path(
conn,
@@ -139,7 +136,6 @@ defmodule Pleroma.Web.EmojiAPI.EmojiAPIControllerTest do
assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/blank.png")
assert conn
- |> assign(:user, admin)
|> delete(emoji_api_path(conn, :delete, "test_pack_nonshared2"))
|> response(200) == "ok"
@@ -240,4 +236,65 @@ defmodule Pleroma.Web.EmojiAPI.EmojiAPIControllerTest do
|> text_response(:bad_request) =~ "does not have all"
end
end
+
+ test "updating pack files" do
+ pack_file = "#{@emoji_dir_path}/test_pack/pack.json"
+ original_content = File.read!(pack_file)
+
+ on_exit(fn ->
+ File.write!(pack_file, original_content)
+
+ File.rm_rf!("#{@emoji_dir_path}/test_pack/dir")
+ File.rm_rf!("#{@emoji_dir_path}/test_pack/dir_2")
+ end)
+
+ admin = insert(:user, info: %{is_admin: true})
+
+ conn = build_conn()
+
+ same_name = %{
+ "action" => "add",
+ "shortcode" => "blank",
+ "filename" => "dir/blank.png",
+ "file" => %Plug.Upload{
+ filename: "blank.png",
+ path: "#{@emoji_dir_path}/test_pack/blank.png"
+ }
+ }
+
+ different_name = %{same_name | "shortcode" => "blank_2"}
+
+ conn = conn |> assign(:user, admin)
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), same_name)
+ |> text_response(:conflict) =~ "already exists"
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), different_name)
+ |> json_response(200) == %{"blank" => "blank.png", "blank_2" => "dir/blank.png"}
+
+ assert File.exists?("#{@emoji_dir_path}/test_pack/dir/blank.png")
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
+ "action" => "update",
+ "shortcode" => "blank_2",
+ "new_shortcode" => "blank_3",
+ "new_filename" => "dir_2/blank_3.png"
+ })
+ |> json_response(200) == %{"blank" => "blank.png", "blank_3" => "dir_2/blank_3.png"}
+
+ refute File.exists?("#{@emoji_dir_path}/test_pack/dir/")
+ assert File.exists?("#{@emoji_dir_path}/test_pack/dir_2/blank_3.png")
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
+ "action" => "remove",
+ "shortcode" => "blank_3"
+ })
+ |> json_response(200) == %{"blank" => "blank.png"}
+
+ refute File.exists?("#{@emoji_dir_path}/test_pack/dir_2/")
+ end
end