refactoring of emoji tags config to use groups
authorAlex S <alex.strizhakov@gmail.com>
Tue, 2 Apr 2019 08:44:56 +0000 (15:44 +0700)
committerAlex S <alex.strizhakov@gmail.com>
Tue, 2 Apr 2019 08:44:56 +0000 (15:44 +0700)
config/config.exs
lib/pleroma/emoji.ex
test/emoji_test.exs

index 245c7d26844883b777f6e240638db3e18a1a6ba5..4a22167b2f69620b0cecc1282a2ee75f8df269ea 100644 (file)
@@ -56,10 +56,11 @@ config :pleroma, Pleroma.Uploaders.MDII,
 
 config :pleroma, :emoji,
   shortcode_globs: ["/emoji/custom/**/*.png"],
 
 config :pleroma, :emoji,
   shortcode_globs: ["/emoji/custom/**/*.png"],
-  custom_tag: "Custom",
-  finmoji_tag: "Finmoji",
-  emoji_tag: "Emoji",
-  custom_emoji_tag: "Custom"
+  groups: [
+    # Place here groups, which have more priority on defaults. Example in `docs/config/custom_emoji.md`
+    Finmoji: "/finmoji/128px/*-128.png",
+    Custom: ["/emoji/*.png", "/emoji/custom/*.png"]
+  ]
 
 config :pleroma, :uri_schemes,
   valid_schemes: [
 
 config :pleroma, :uri_schemes,
   valid_schemes: [
index ad3170f9a41546aa7ae583d198684820c209b337..b60d19e8949dfa044c99feb0d5c9453872f60fb7 100644 (file)
@@ -13,8 +13,14 @@ defmodule Pleroma.Emoji do
   This GenServer stores in an ETS table the list of the loaded emojis, and also allows to reload the list at runtime.
   """
   use GenServer
   This GenServer stores in an ETS table the list of the loaded emojis, and also allows to reload the list at runtime.
   """
   use GenServer
+
+  @type pattern :: Regex.t() | module() | String.t()
+  @type patterns :: pattern | [pattern]
+  @type group_patterns :: keyword(patterns)
+
   @ets __MODULE__.Ets
   @ets_options [:ordered_set, :protected, :named_table, {:read_concurrency, true}]
   @ets __MODULE__.Ets
   @ets_options [:ordered_set, :protected, :named_table, {:read_concurrency, true}]
+  @groups Application.get_env(:pleroma, :emoji)[:groups]
 
   @doc false
   def start_link do
 
   @doc false
   def start_link do
@@ -73,13 +79,14 @@ defmodule Pleroma.Emoji do
   end
 
   defp load do
   end
 
   defp load do
+    finmoji_enabled = Keyword.get(Application.get_env(:pleroma, :instance), :finmoji_enabled)
+    shortcode_globs = Keyword.get(Application.get_env(:pleroma, :emoji, []), :shortcode_globs, [])
+
     emojis =
     emojis =
-      (load_finmoji(Keyword.get(Application.get_env(:pleroma, :instance), :finmoji_enabled)) ++
+      (load_finmoji(finmoji_enabled) ++
          load_from_file("config/emoji.txt") ++
          load_from_file("config/custom_emoji.txt") ++
          load_from_file("config/emoji.txt") ++
          load_from_file("config/custom_emoji.txt") ++
-         load_from_globs(
-           Keyword.get(Application.get_env(:pleroma, :emoji, []), :shortcode_globs, [])
-         ))
+         load_from_globs(shortcode_globs))
       |> Enum.reject(fn value -> value == nil end)
 
     true = :ets.insert(@ets, emojis)
       |> Enum.reject(fn value -> value == nil end)
 
     true = :ets.insert(@ets, emojis)
@@ -151,11 +158,12 @@ defmodule Pleroma.Emoji do
     "white_nights",
     "woollysocks"
   ]
     "white_nights",
     "woollysocks"
   ]
-  defp load_finmoji(true) do
-    tag = Application.get_env(:pleroma, :emoji)[:finmoji_tag]
 
 
+  defp load_finmoji(true) do
     Enum.map(@finmoji, fn finmoji ->
     Enum.map(@finmoji, fn finmoji ->
-      {finmoji, "/finmoji/128px/#{finmoji}-128.png", tag}
+      file_name = "/finmoji/128px/#{finmoji}-128.png"
+      group = match_extra(@groups, file_name)
+      {finmoji, file_name, to_string(group)}
     end)
   end
 
     end)
   end
 
@@ -170,11 +178,6 @@ defmodule Pleroma.Emoji do
   end
 
   defp load_from_file_stream(stream) do
   end
 
   defp load_from_file_stream(stream) do
-    default_tag =
-      stream.path
-      |> Path.basename(".txt")
-      |> get_default_tag()
-
     stream
     |> Stream.map(&String.trim/1)
     |> Stream.map(fn line ->
     stream
     |> Stream.map(&String.trim/1)
     |> Stream.map(fn line ->
@@ -183,7 +186,7 @@ defmodule Pleroma.Emoji do
           {name, file, tags}
 
         [name, file] ->
           {name, file, tags}
 
         [name, file] ->
-          {name, file, default_tag}
+          {name, file, to_string(match_extra(@groups, file))}
 
         _ ->
           nil
 
         _ ->
           nil
@@ -192,48 +195,51 @@ defmodule Pleroma.Emoji do
     |> Enum.to_list()
   end
 
     |> Enum.to_list()
   end
 
-  @spec get_default_tag(String.t()) :: String.t()
-  defp get_default_tag(file_name) when file_name in ["emoji", "custom_emoji"] do
-    Keyword.get(
-      Application.get_env(:pleroma, :emoji),
-      String.to_existing_atom(file_name <> "_tag")
-    )
-  end
-
-  defp get_default_tag(_), do: Application.get_env(:pleroma, :emoji)[:custom_tag]
-
   defp load_from_globs(globs) do
     static_path = Path.join(:code.priv_dir(:pleroma), "static")
 
     paths =
       Enum.map(globs, fn glob ->
   defp load_from_globs(globs) do
     static_path = Path.join(:code.priv_dir(:pleroma), "static")
 
     paths =
       Enum.map(globs, fn glob ->
-        static_part =
-          Path.dirname(glob)
-          |> String.replace_trailing("**", "")
-
         Path.join(static_path, glob)
         |> Path.wildcard()
         Path.join(static_path, glob)
         |> Path.wildcard()
-        |> Enum.map(fn path ->
-          custom_folder =
-            path
-            |> Path.relative_to(Path.join(static_path, static_part))
-            |> Path.dirname()
-
-          [path, custom_folder]
-        end)
       end)
       |> Enum.concat()
 
       end)
       |> Enum.concat()
 
-    Enum.map(paths, fn [path, custom_folder] ->
-      tag =
-        case custom_folder do
-          "." -> Keyword.get(Application.get_env(:pleroma, :emoji), :custom_tag)
-          tag -> tag
-        end
-
+    Enum.map(paths, fn path ->
+      tag = match_extra(@groups, Path.join("/", Path.relative_to(path, static_path)))
       shortcode = Path.basename(path, Path.extname(path))
       external_path = Path.join("/", Path.relative_to(path, static_path))
       shortcode = Path.basename(path, Path.extname(path))
       external_path = Path.join("/", Path.relative_to(path, static_path))
-      {shortcode, external_path, tag}
+      {shortcode, external_path, to_string(tag)}
+    end)
+  end
+
+  @doc """
+  Finds a matching group for the given extra filename
+  """
+  @spec match_extra(group_patterns(), String.t()) :: atom() | nil
+  def match_extra(group_patterns, filename) do
+    match_group_patterns(group_patterns, fn pattern ->
+      case pattern do
+        %Regex{} = regex -> Regex.match?(regex, filename)
+        string when is_binary(string) -> filename == string
+      end
+    end)
+  end
+
+  defp match_group_patterns(group_patterns, matcher) do
+    Enum.find_value(group_patterns, fn {group, patterns} ->
+      patterns =
+        patterns
+        |> List.wrap()
+        |> Enum.map(fn pattern ->
+          if String.contains?(pattern, "*") do
+            ~r(#{String.replace(pattern, "*", ".*")})
+          else
+            pattern
+          end
+        end)
+
+      Enum.any?(patterns, matcher) && group
     end)
   end
 end
     end)
   end
 end
index a90213d7dd2b8f4967c68b07d76ede0a7fd3820c..cb1d62d00876da2190cadf270c53088be953ed8c 100644 (file)
@@ -28,4 +28,79 @@ defmodule Pleroma.EmojiTest do
       assert is_binary(tags)
     end
   end
       assert is_binary(tags)
     end
   end
+
+  describe "match_extra/2" do
+    setup do
+      groups = [
+        "list of files": ["/emoji/custom/first_file.png", "/emoji/custom/second_file.png"],
+        "wildcard folder": "/emoji/custom/*/file.png",
+        "wildcard files": "/emoji/custom/folder/*.png",
+        "special file": "/emoji/custom/special.png"
+      ]
+
+      {:ok, groups: groups}
+    end
+
+    test "config for list of files", %{groups: groups} do
+      group =
+        groups
+        |> Emoji.match_extra("/emoji/custom/first_file.png")
+        |> to_string()
+
+      assert group == "list of files"
+    end
+
+    test "config with wildcard folder", %{groups: groups} do
+      group =
+        groups
+        |> Emoji.match_extra("/emoji/custom/some_folder/file.png")
+        |> to_string()
+
+      assert group == "wildcard folder"
+    end
+
+    test "config with wildcard folder and subfolders", %{groups: groups} do
+      group =
+        groups
+        |> Emoji.match_extra("/emoji/custom/some_folder/another_folder/file.png")
+        |> to_string()
+
+      assert group == "wildcard folder"
+    end
+
+    test "config with wildcard files", %{groups: groups} do
+      group =
+        groups
+        |> Emoji.match_extra("/emoji/custom/folder/some_file.png")
+        |> to_string()
+
+      assert group == "wildcard files"
+    end
+
+    test "config with wildcard files and subfolders", %{groups: groups} do
+      group =
+        groups
+        |> Emoji.match_extra("/emoji/custom/folder/another_folder/some_file.png")
+        |> to_string()
+
+      assert group == "wildcard files"
+    end
+
+    test "config for special file", %{groups: groups} do
+      group =
+        groups
+        |> Emoji.match_extra("/emoji/custom/special.png")
+        |> to_string()
+
+      assert group == "special file"
+    end
+
+    test "no mathing returns nil", %{groups: groups} do
+      group =
+        groups
+        |> Emoji.match_extra("/emoji/some_undefined.png")
+
+      refute group
+    end
+  end
 end
 end