X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=inline;f=lib%2Fpleroma%2Femoji.ex;h=933f4275af1d6cec7625b52ad00c9491b620798e;hb=fe7045632b77576b727281b0fa7a8d87b9b9b44a;hp=b246bfbe672c417036a15ea858ba3d6a27dd0cd2;hpb=6ef0103ca0b194971a2e6f61685316536b742a11;p=akkoma
diff --git a/lib/pleroma/emoji.ex b/lib/pleroma/emoji.ex
index b246bfbe6..933f4275a 100644
--- a/lib/pleroma/emoji.ex
+++ b/lib/pleroma/emoji.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors
+# Copyright © 2017-2021 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emoji do
@@ -9,6 +9,7 @@ defmodule Pleroma.Emoji do
"""
use GenServer
+ alias Pleroma.Emoji.Combinations
alias Pleroma.Emoji.Loader
require Logger
@@ -20,6 +21,7 @@ defmodule Pleroma.Emoji do
:named_table,
{:read_concurrency, true}
]
+ @emoji_regex ~r/:[A-Za-z0-9_-]+(@.+)?:/
defstruct [:code, :file, :tags, :safe_code, :safe_file]
@@ -50,18 +52,33 @@ defmodule Pleroma.Emoji do
@doc "Returns the path of the emoji `name`."
@spec get(String.t()) :: String.t() | nil
def get(name) do
+ name =
+ if String.starts_with?(name, ":") do
+ name
+ |> String.replace_leading(":", "")
+ |> String.replace_trailing(":", "")
+ else
+ name
+ end
+
case :ets.lookup(@ets, name) do
[{_, path}] -> path
_ -> nil
end
end
+ @spec exist?(String.t()) :: boolean()
+ def exist?(name), do: not is_nil(get(name))
+
@doc "Returns all the emojos!!"
@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)
@@ -95,4 +112,101 @@ defmodule Pleroma.Emoji do
defp update_emojis(emojis) do
:ets.insert(@ets, emojis)
end
+
+ @external_resource "lib/pleroma/emoji-test.txt"
+
+ regional_indicators =
+ Enum.map(127_462..127_487, fn codepoint ->
+ <>
+ end)
+
+ emojis =
+ @external_resource
+ |> File.read!()
+ |> String.split("\n")
+ |> Enum.filter(fn line ->
+ line != "" and not String.starts_with?(line, "#") and
+ String.contains?(line, "fully-qualified")
+ end)
+ |> Enum.map(fn line ->
+ line
+ |> String.split(";", parts: 2)
+ |> hd()
+ |> String.trim()
+ |> String.split()
+ |> Enum.map(fn codepoint ->
+ <>
+ end)
+ |> Enum.join()
+ end)
+ |> Enum.uniq()
+
+ emojis = emojis ++ regional_indicators
+
+ for emoji <- emojis do
+ def is_unicode_emoji?(unquote(emoji)), do: true
+ end
+
+ def is_unicode_emoji?(_), do: false
+
+ def stripped_name(name) when is_binary(name) do
+ name
+ |> String.replace_leading(":", "")
+ |> String.replace_trailing(":", "")
+ end
+
+ def stripped_name(name), do: name
+
+ def maybe_quote(name) when is_binary(name) do
+ if is_unicode_emoji?(name) do
+ name
+ else
+ if String.starts_with?(name, ":") do
+ name
+ else
+ ":#{name}:"
+ end
+ end
+ end
+
+ def maybe_quote(name), do: name
+
+ def emoji_url(%{"type" => "EmojiReact", "content" => _, "tag" => []}), do: nil
+
+ def emoji_url(%{"type" => "EmojiReact", "content" => emoji, "tag" => tags}) do
+ tag =
+ tags
+ |> Enum.find(fn tag -> tag["type"] == "Emoji" && tag["name"] == stripped_name(emoji) end)
+
+ if is_nil(tag) do
+ nil
+ else
+ tag
+ |> Map.get("icon")
+ |> Map.get("url")
+ end
+ end
+
+ def emoji_url(_), do: nil
+
+ def emoji_name_with_instance(name, url) do
+ url = url |> URI.parse() |> Map.get(:host)
+ "#{name}@#{url}"
+ end
+
+ emoji_qualification_map =
+ emojis
+ |> Enum.filter(&String.contains?(&1, "\uFE0F"))
+ |> Combinations.variate_emoji_qualification()
+
+ for {qualified, unqualified_list} <- emoji_qualification_map do
+ for unqualified <- unqualified_list do
+ def fully_qualify_emoji(unquote(unqualified)), do: unquote(qualified)
+ end
+ end
+
+ def fully_qualify_emoji(emoji), do: emoji
+
+ def matches_shortcode?(nil), do: false
+ def matches_shortcode?(s), do: Regex.match?(@emoji_regex, s)
end