refactoring of emoji tags config to use groups

This commit is contained in:
Alex S 2019-04-02 15:44:56 +07:00
parent 49733f6176
commit 9b2188da7c
3 changed files with 129 additions and 47 deletions

View File

@ -56,10 +56,11 @@
config :pleroma, :emoji, config :pleroma, :emoji,
shortcode_globs: ["/emoji/custom/**/*.png"], shortcode_globs: ["/emoji/custom/**/*.png"],
custom_tag: "Custom", groups: [
finmoji_tag: "Finmoji", # Place here groups, which have more priority on defaults. Example in `docs/config/custom_emoji.md`
emoji_tag: "Emoji", Finmoji: "/finmoji/128px/*-128.png",
custom_emoji_tag: "Custom" Custom: ["/emoji/*.png", "/emoji/custom/*.png"]
]
config :pleroma, :uri_schemes, config :pleroma, :uri_schemes,
valid_schemes: [ valid_schemes: [

View 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. This GenServer stores in an ETS table the list of the loaded emojis, and also allows to reload the list at runtime.
""" """
use GenServer use GenServer
@type pattern :: Regex.t() | module() | String.t()
@type patterns :: pattern | [pattern]
@type group_patterns :: keyword(patterns)
@ets __MODULE__.Ets @ets __MODULE__.Ets
@ets_options [:ordered_set, :protected, :named_table, {:read_concurrency, true}] @ets_options [:ordered_set, :protected, :named_table, {:read_concurrency, true}]
@groups Application.get_env(:pleroma, :emoji)[:groups]
@doc false @doc false
def start_link do def start_link do
@ -73,13 +79,14 @@ def code_change(_old_vsn, state, _extra) do
end end
defp load do 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/emoji.txt") ++
load_from_file("config/custom_emoji.txt") ++ load_from_file("config/custom_emoji.txt") ++
load_from_globs( load_from_globs(shortcode_globs))
Keyword.get(Application.get_env(:pleroma, :emoji, []), :shortcode_globs, [])
))
|> Enum.reject(fn value -> value == nil end) |> Enum.reject(fn value -> value == nil end)
true = :ets.insert(@ets, emojis) true = :ets.insert(@ets, emojis)
@ -151,11 +158,12 @@ defp load do
"white_nights", "white_nights",
"woollysocks" "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 @@ defp load_from_file(file) do
end end
defp load_from_file_stream(stream) do defp load_from_file_stream(stream) do
default_tag =
stream.path
|> Path.basename(".txt")
|> get_default_tag()
stream stream
|> Stream.map(&String.trim/1) |> Stream.map(&String.trim/1)
|> Stream.map(fn line -> |> Stream.map(fn line ->
@ -183,7 +186,7 @@ defp load_from_file_stream(stream) do
{name, file, tags} {name, file, tags}
[name, file] -> [name, file] ->
{name, file, default_tag} {name, file, to_string(match_extra(@groups, file))}
_ -> _ ->
nil nil
@ -192,48 +195,51 @@ defp load_from_file_stream(stream) do
|> Enum.to_list() |> Enum.to_list()
end 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 defp load_from_globs(globs) do
static_path = Path.join(:code.priv_dir(:pleroma), "static") static_path = Path.join(:code.priv_dir(:pleroma), "static")
paths = paths =
Enum.map(globs, fn glob -> Enum.map(globs, fn glob ->
static_part =
Path.dirname(glob)
|> String.replace_trailing("**", "")
Path.join(static_path, glob) Path.join(static_path, glob)
|> Path.wildcard() |> 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) end)
|> Enum.concat() |> Enum.concat()
Enum.map(paths, fn [path, custom_folder] -> Enum.map(paths, fn path ->
tag = tag = match_extra(@groups, Path.join("/", Path.relative_to(path, static_path)))
case custom_folder do
"." -> Keyword.get(Application.get_env(:pleroma, :emoji), :custom_tag)
tag -> tag
end
shortcode = Path.basename(path, Path.extname(path)) shortcode = Path.basename(path, Path.extname(path))
external_path = Path.join("/", Path.relative_to(path, static_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

View File

@ -28,4 +28,79 @@ test "random emoji", %{emoji_list: emoji_list} do
assert is_binary(tags) assert is_binary(tags)
end end
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