From 9eb2ee4df0478daec1172eec2289868105b72756 Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Tue, 10 Sep 2019 21:16:30 +0300 Subject: [PATCH] Allow importing old (emoji.txt / plain) packs from the filesystem --- lib/pleroma/web/emoji_api/emoji_api_controller.ex | 66 +++++++++++++++++++++ lib/pleroma/web/router.ex | 2 + .../emoji/test_pack_for_import/blank.png | Bin 0 -> 95 bytes test/web/emoji_api_controller_test.exs | 41 +++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 test/instance_static/emoji/test_pack_for_import/blank.png diff --git a/lib/pleroma/web/emoji_api/emoji_api_controller.ex b/lib/pleroma/web/emoji_api/emoji_api_controller.ex index f34a4e08c..dffb91b0f 100644 --- a/lib/pleroma/web/emoji_api/emoji_api_controller.ex +++ b/lib/pleroma/web/emoji_api/emoji_api_controller.ex @@ -446,4 +446,70 @@ keeping it in cache for #{div(cache_ms, 1000)}s") e end end + + def import_from_fs(conn, _params) do + case File.ls(@emoji_dir_path) do + {:error, _} -> + conn + |> put_status(:internal_server_error) + |> text("Error accessing emoji pack directory") + + {:ok, results} -> + imported_pack_names = + results + |> Enum.filter(fn file -> + dir_path = Path.join(@emoji_dir_path, file) + # Find the directories that do NOT have pack.json + File.dir?(dir_path) and not File.exists?(Path.join(dir_path, "pack.json")) + end) + |> Enum.map(fn dir -> + dir_path = Path.join(@emoji_dir_path, dir) + emoji_txt_path = Path.join(dir_path, "emoji.txt") + + files_for_pack = + if File.exists?(emoji_txt_path) do + # There's an emoji.txt file, it's likely from a pack installed by the pack manager. + # Make a pack.json file from the contents of that emoji.txt fileh + + # FIXME: Copy-pasted from Pleroma.Emoji/load_from_file_stream/2 + + # Create a map of shortcodes to filenames from emoji.txt + + File.read!(emoji_txt_path) + |> String.split("\n") + |> Enum.map(&String.trim/1) + |> Enum.map(fn line -> + case String.split(line, ~r/,\s*/) do + # This matches both strings with and without tags and we don't care about tags here + [name, file | _] -> + {name, file} + + _ -> + nil + end + end) + |> Enum.filter(fn x -> not is_nil(x) end) + |> Enum.into(%{}) + else + # If there's no emoji.txt, assume all files that are of certain extensions from the config + # are emojis and import them all + Pleroma.Emoji.make_shortcode_to_file_map( + dir_path, + Pleroma.Config.get!([:emoji, :pack_extensions]) + ) + end + + pack_json_contents = Jason.encode!(%{pack: %{}, files: files_for_pack}) + + File.write!( + Path.join(dir_path, "pack.json"), + pack_json_contents + ) + + dir + end) + + conn |> json(imported_pack_names) + end + end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index a21fefc70..1252048f0 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -218,6 +218,8 @@ defmodule Pleroma.Web.Router do # Modifying packs pipe_through([:admin_api, :oauth_write]) + post("/import_from_fs", EmojiAPIController, :import_from_fs) + post("/update_file/:pack_name", EmojiAPIController, :update_file) post("/update_metadata/:pack_name", EmojiAPIController, :update_metadata) post("/create/:name", EmojiAPIController, :create) diff --git a/test/instance_static/emoji/test_pack_for_import/blank.png b/test/instance_static/emoji/test_pack_for_import/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..8f50fa02340e7e09e562f86e00b6e4bd6ad1d565 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^4Is=2Bp6=1#-sr$rjj7PU + File.rm!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt") + File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json") + end) + + conn = build_conn() + resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + + refute Map.has_key?(resp, "test_pack_for_import") + + admin = insert(:user, info: %{is_admin: true}) + + assert conn + |> assign(:user, admin) + |> post(emoji_api_path(conn, :import_from_fs)) + |> json_response(200) == ["test_pack_for_import"] + + resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"} + + File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json") + refute File.exists?("#{@emoji_dir_path}/test_pack_for_import/pack.json") + + emoji_txt_content = "blank, blank.png, Fun\n\nblank2, blank.png" + + File.write!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt", emoji_txt_content) + + assert conn + |> assign(:user, admin) + |> post(emoji_api_path(conn, :import_from_fs)) + |> json_response(200) == ["test_pack_for_import"] + + resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + + assert resp["test_pack_for_import"]["files"] == %{ + "blank" => "blank.png", + "blank2" => "blank.png" + } + end end