X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Femoji.ex;h=f6016d73fb5c02a0118cfe250a5980d844dd4c99;hb=3d2989278c2f97fb5247d0b58b99b77f400f3185;hp=87c7f2ceca0313dbcc8170d80a89bffea431301e;hpb=9abf832b034bf3867272bd178d168c641129eff0;p=akkoma
diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex
index 87c7f2cec..f6016d73f 100644
--- a/lib/pleroma/emoji.ex
+++ b/lib/pleroma/emoji.ex
@@ -1,29 +1,43 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors
+# Copyright © 2017-2020 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emoji do
@moduledoc """
- The emojis are loaded from:
-
- * the built-in Finmojis (if enabled in configuration),
- * the files: `config/emoji.txt` and `config/custom_emoji.txt`
- * glob paths, nested folder is used as tag name for grouping e.g. priv/static/emoji/custom/nested_folder
-
- 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
- @type pattern :: Regex.t() | module() | String.t()
- @type patterns :: pattern() | [pattern()]
- @type group_patterns :: keyword(patterns())
+ alias Pleroma.Emoji.Loader
+
+ require Logger
@ets __MODULE__.Ets
- @ets_options [:ordered_set, :protected, :named_table, {:read_concurrency, true}]
- @groups Application.get_env(:pleroma, :emoji)[:groups]
+ @ets_options [
+ :ordered_set,
+ :protected,
+ :named_table,
+ {: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
+ def start_link(_) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
@@ -43,11 +57,14 @@ defmodule Pleroma.Emoji do
end
@doc "Returns all the emojos!!"
- @spec get_all() :: [{String.t(), String.t()}, ...]
+ @spec get_all() :: list({String.t(), String.t(), String.t()})
def get_all do
:ets.tab2list(@ets)
end
+ @doc "Clear out old emojis"
+ def clear_all, do: :ets.delete_all_objects(@ets)
+
@doc false
def init(_) do
@ets = :ets.new(@ets, @ets_options)
@@ -57,13 +74,13 @@ defmodule Pleroma.Emoji do
@doc false
def handle_cast(:reload, state) do
- load()
+ update_emojis(Loader.load())
{:noreply, state}
end
@doc false
def handle_call(:reload, _from, state) do
- load()
+ update_emojis(Loader.load())
{:reply, :ok, state}
end
@@ -74,172 +91,42 @@ defmodule Pleroma.Emoji do
@doc false
def code_change(_old_vsn, state, _extra) do
- load()
+ update_emojis(Loader.load())
{:ok, state}
end
- defp load do
- finmoji_enabled = Keyword.get(Application.get_env(:pleroma, :instance), :finmoji_enabled)
- shortcode_globs = Application.get_env(:pleroma, :emoji)[:shortcode_globs] || []
-
- emojis =
- (load_finmoji(finmoji_enabled) ++
- load_from_file("config/emoji.txt") ++
- load_from_file("config/custom_emoji.txt") ++
- load_from_globs(shortcode_globs))
- |> Enum.reject(fn value -> value == nil end)
-
- true = :ets.insert(@ets, emojis)
- :ok
- end
-
- @finmoji [
- "a_trusted_friend",
- "alandislands",
- "association",
- "auroraborealis",
- "baby_in_a_box",
- "bear",
- "black_gold",
- "christmasparty",
- "crosscountryskiing",
- "cupofcoffee",
- "education",
- "fashionista_finns",
- "finnishlove",
- "flag",
- "forest",
- "four_seasons_of_bbq",
- "girlpower",
- "handshake",
- "happiness",
- "headbanger",
- "icebreaker",
- "iceman",
- "joulutorttu",
- "kaamos",
- "kalsarikannit_f",
- "kalsarikannit_m",
- "karjalanpiirakka",
- "kicksled",
- "kokko",
- "lavatanssit",
- "losthopes_f",
- "losthopes_m",
- "mattinykanen",
- "meanwhileinfinland",
- "moominmamma",
- "nordicfamily",
- "out_of_office",
- "peacemaker",
- "perkele",
- "pesapallo",
- "polarbear",
- "pusa_hispida_saimensis",
- "reindeer",
- "sami",
- "sauna_f",
- "sauna_m",
- "sauna_whisk",
- "sisu",
- "stuck",
- "suomimainittu",
- "superfood",
- "swan",
- "the_cap",
- "the_conductor",
- "the_king",
- "the_voice",
- "theoriginalsanta",
- "tomoffinland",
- "torillatavataan",
- "unbreakable",
- "waiting",
- "white_nights",
- "woollysocks"
- ]
-
- defp load_finmoji(true) do
- Enum.map(@finmoji, fn finmoji ->
- file_name = "/finmoji/128px/#{finmoji}-128.png"
- group = match_extra(@groups, file_name)
- {finmoji, file_name, to_string(group)}
- end)
- end
-
- defp load_finmoji(_), do: []
-
- defp load_from_file(file) do
- if File.exists?(file) do
- load_from_file_stream(File.stream!(file))
- else
- []
- end
+ defp update_emojis(emojis) do
+ :ets.insert(@ets, emojis)
end
- defp load_from_file_stream(stream) do
- stream
- |> Stream.map(&String.trim/1)
- |> Stream.map(fn line ->
- case String.split(line, ~r/,\s*/) do
- [name, file, tags] ->
- {name, file, tags}
+ @external_resource "lib/pleroma/emoji-data.txt"
- [name, file] ->
- {name, file, to_string(match_extra(@groups, file))}
+ emojis =
+ @external_resource
+ |> File.read!()
+ |> String.split("\n")
+ |> Enum.filter(fn line -> line != "" and not String.starts_with?(line, "#") end)
+ |> Enum.map(fn line ->
+ line
+ |> String.split(";", parts: 2)
+ |> hd()
+ |> String.trim()
+ |> String.split("..")
+ |> case do
+ [number] ->
+ <>
- _ ->
- nil
+ [first, last] ->
+ String.to_integer(first, 16)..String.to_integer(last, 16)
+ |> Enum.map(&<<&1::utf8>>)
end
end)
- |> Enum.to_list()
- end
+ |> List.flatten()
+ |> Enum.uniq()
- defp load_from_globs(globs) do
- static_path = Path.join(:code.priv_dir(:pleroma), "static")
-
- paths =
- Enum.map(globs, fn glob ->
- Path.join(static_path, glob)
- |> Path.wildcard()
- end)
- |> Enum.concat()
-
- 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, external_path, to_string(tag)}
- end)
+ for emoji <- emojis do
+ def is_unicode_emoji?(unquote(emoji)), do: true
end
- @doc """
- Finds a matching group for the given emoji 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
+ def is_unicode_emoji?(_), do: false
end