Merge branch 'develop' into 'from/develop/tusooa/emit-move'
# Conflicts: # CHANGELOG.md # test/pleroma/user_test.exs
This commit is contained in:
commit
c80096522c
1458 changed files with 31249 additions and 2288 deletions
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity.HTML do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity.Ir.Topics do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity.Queries do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity.Search do
|
||||
|
|
|
|||
160
lib/pleroma/announcement.ex
Normal file
160
lib/pleroma/announcement.ex
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Announcement do
|
||||
use Ecto.Schema
|
||||
|
||||
import Ecto.Changeset, only: [cast: 3, validate_required: 2]
|
||||
import Ecto.Query
|
||||
|
||||
alias Pleroma.AnnouncementReadRelationship
|
||||
alias Pleroma.Repo
|
||||
|
||||
@type t :: %__MODULE__{}
|
||||
@primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true}
|
||||
|
||||
schema "announcements" do
|
||||
field(:data, :map)
|
||||
field(:starts_at, :utc_datetime)
|
||||
field(:ends_at, :utc_datetime)
|
||||
field(:rendered, :map)
|
||||
|
||||
timestamps(type: :utc_datetime)
|
||||
end
|
||||
|
||||
def change(struct, params \\ %{}) do
|
||||
struct
|
||||
|> cast(validate_params(struct, params), [:data, :starts_at, :ends_at, :rendered])
|
||||
|> validate_required([:data])
|
||||
end
|
||||
|
||||
defp validate_params(struct, params) do
|
||||
base_data =
|
||||
%{
|
||||
"content" => "",
|
||||
"all_day" => false
|
||||
}
|
||||
|> Map.merge((struct && struct.data) || %{})
|
||||
|
||||
merged_data =
|
||||
Map.merge(base_data, params.data)
|
||||
|> Map.take(["content", "all_day"])
|
||||
|
||||
params
|
||||
|> Map.merge(%{data: merged_data})
|
||||
|> add_rendered_properties()
|
||||
end
|
||||
|
||||
def add_rendered_properties(params) do
|
||||
{content_html, _, _} =
|
||||
Pleroma.Web.CommonAPI.Utils.format_input(params.data["content"], "text/plain",
|
||||
mentions_format: :full
|
||||
)
|
||||
|
||||
rendered = %{
|
||||
"content" => content_html
|
||||
}
|
||||
|
||||
params
|
||||
|> Map.put(:rendered, rendered)
|
||||
end
|
||||
|
||||
def add(params) do
|
||||
changeset = change(%__MODULE__{}, params)
|
||||
|
||||
Repo.insert(changeset)
|
||||
end
|
||||
|
||||
def update(announcement, params) do
|
||||
changeset = change(announcement, params)
|
||||
|
||||
Repo.update(changeset)
|
||||
end
|
||||
|
||||
def list_all do
|
||||
__MODULE__
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
def list_paginated(%{limit: limited_number, offset: offset_number}) do
|
||||
__MODULE__
|
||||
|> limit(^limited_number)
|
||||
|> offset(^offset_number)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
def get_by_id(id) do
|
||||
Repo.get_by(__MODULE__, id: id)
|
||||
end
|
||||
|
||||
def delete_by_id(id) do
|
||||
with announcement when not is_nil(announcement) <- get_by_id(id),
|
||||
{:ok, _} <- Repo.delete(announcement) do
|
||||
:ok
|
||||
else
|
||||
_ ->
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
||||
def read_by?(announcement, user) do
|
||||
AnnouncementReadRelationship.exists?(user, announcement)
|
||||
end
|
||||
|
||||
def mark_read_by(announcement, user) do
|
||||
AnnouncementReadRelationship.mark_read(user, announcement)
|
||||
end
|
||||
|
||||
def render_json(announcement, opts \\ []) do
|
||||
extra_params =
|
||||
case Keyword.fetch(opts, :for) do
|
||||
{:ok, user} when not is_nil(user) ->
|
||||
%{read: read_by?(announcement, user)}
|
||||
|
||||
_ ->
|
||||
%{}
|
||||
end
|
||||
|
||||
admin_extra_params =
|
||||
case Keyword.fetch(opts, :admin) do
|
||||
{:ok, true} ->
|
||||
%{pleroma: %{raw_content: announcement.data["content"]}}
|
||||
|
||||
_ ->
|
||||
%{}
|
||||
end
|
||||
|
||||
base = %{
|
||||
id: announcement.id,
|
||||
content: announcement.rendered["content"],
|
||||
starts_at: announcement.starts_at,
|
||||
ends_at: announcement.ends_at,
|
||||
all_day: announcement.data["all_day"],
|
||||
published_at: announcement.inserted_at,
|
||||
updated_at: announcement.updated_at,
|
||||
mentions: [],
|
||||
statuses: [],
|
||||
tags: [],
|
||||
emojis: [],
|
||||
reactions: []
|
||||
}
|
||||
|
||||
base
|
||||
|> Map.merge(extra_params)
|
||||
|> Map.merge(admin_extra_params)
|
||||
end
|
||||
|
||||
# "visible" means:
|
||||
# starts_at < time < ends_at
|
||||
def list_all_visible_when(time) do
|
||||
__MODULE__
|
||||
|> where([a], is_nil(a.starts_at) or a.starts_at < ^time)
|
||||
|> where([a], is_nil(a.ends_at) or a.ends_at > ^time)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
def list_all_visible do
|
||||
list_all_visible_when(DateTime.now("Etc/UTC") |> elem(1))
|
||||
end
|
||||
end
|
||||
55
lib/pleroma/announcement_read_relationship.ex
Normal file
55
lib/pleroma/announcement_read_relationship.ex
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.AnnouncementReadRelationship do
|
||||
use Ecto.Schema
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
alias FlakeId.Ecto.CompatType
|
||||
alias Pleroma.Announcement
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
|
||||
@type t :: %__MODULE__{}
|
||||
|
||||
schema "announcement_read_relationships" do
|
||||
belongs_to(:user, User, type: CompatType)
|
||||
belongs_to(:announcement, Announcement, type: CompatType)
|
||||
|
||||
timestamps(updated_at: false)
|
||||
end
|
||||
|
||||
def mark_read(user, announcement) do
|
||||
%__MODULE__{}
|
||||
|> cast(%{user_id: user.id, announcement_id: announcement.id}, [:user_id, :announcement_id])
|
||||
|> validate_required([:user_id, :announcement_id])
|
||||
|> foreign_key_constraint(:user_id)
|
||||
|> foreign_key_constraint(:announcement_id)
|
||||
|> unique_constraint([:user_id, :announcement_id])
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
def mark_unread(user, announcement) do
|
||||
with relationship <- get(user, announcement),
|
||||
{:exists, true} <- {:exists, not is_nil(relationship)},
|
||||
{:ok, _} <- Repo.delete(relationship) do
|
||||
:ok
|
||||
else
|
||||
{:exists, false} ->
|
||||
:ok
|
||||
|
||||
_ ->
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
||||
def get(user, announcement) do
|
||||
Repo.get_by(__MODULE__, user_id: user.id, announcement_id: announcement.id)
|
||||
end
|
||||
|
||||
def exists?(user, announcement) do
|
||||
not is_nil(get(user, announcement))
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Application do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ApplicationRequirements do
|
||||
|
|
@ -164,7 +164,8 @@ defmodule Pleroma.ApplicationRequirements do
|
|||
|
||||
defp check_system_commands!(:ok) do
|
||||
filter_commands_statuses = [
|
||||
check_filter(Pleroma.Upload.Filter.Exiftool, "exiftool"),
|
||||
check_filter(Pleroma.Upload.Filter.Exiftool.StripLocation, "exiftool"),
|
||||
check_filter(Pleroma.Upload.Filter.Exiftool.ReadDescription, "exiftool"),
|
||||
check_filter(Pleroma.Upload.Filter.Mogrify, "mogrify"),
|
||||
check_filter(Pleroma.Upload.Filter.Mogrifun, "mogrify"),
|
||||
check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "mogrify"),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.BBS.Authenticator do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.BBS.Handler do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Bookmark do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Caching do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Captcha do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Captcha.Kocaptcha do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Captcha.Native do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Captcha.Service do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Chat do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Chat.MessageReference do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Clippy do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.DeprecationWarnings do
|
||||
|
|
@ -20,6 +20,43 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
"\n* `config :pleroma, :instance, mrf_transparency_exclusions` is now `config :pleroma, :mrf, transparency_exclusions`"}
|
||||
]
|
||||
|
||||
def check_exiftool_filter do
|
||||
filters = Config.get([Pleroma.Upload]) |> Keyword.get(:filters, [])
|
||||
|
||||
if Pleroma.Upload.Filter.Exiftool in filters do
|
||||
Logger.warn("""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your config is using Exiftool as a filter instead of Exiftool.StripLocation. This should work for now, but you are advised to change to the new configuration to prevent possible issues later:
|
||||
|
||||
```
|
||||
config :pleroma, Pleroma.Upload,
|
||||
filters: [Pleroma.Upload.Filter.Exiftool]
|
||||
```
|
||||
|
||||
Is now
|
||||
|
||||
|
||||
```
|
||||
config :pleroma, Pleroma.Upload,
|
||||
filters: [Pleroma.Upload.Filter.Exiftool.StripLocation]
|
||||
```
|
||||
""")
|
||||
|
||||
new_config =
|
||||
filters
|
||||
|> Enum.map(fn
|
||||
Pleroma.Upload.Filter.Exiftool -> Pleroma.Upload.Filter.Exiftool.StripLocation
|
||||
filter -> filter
|
||||
end)
|
||||
|
||||
Config.put([Pleroma.Upload, :filters], new_config)
|
||||
|
||||
:error
|
||||
else
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
def check_simple_policy_tuples do
|
||||
has_strings =
|
||||
Config.get([:mrf_simple])
|
||||
|
|
@ -180,7 +217,8 @@ defmodule Pleroma.Config.DeprecationWarnings do
|
|||
check_old_chat_shoutbox(),
|
||||
check_quarantined_instances_tuples(),
|
||||
check_transparency_exclusions_tuples(),
|
||||
check_simple_policy_tuples()
|
||||
check_simple_policy_tuples(),
|
||||
check_exiftool_filter()
|
||||
]
|
||||
|> Enum.reduce(:ok, fn
|
||||
:ok, :ok -> :ok
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.Getting do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.Helpers do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.Holder do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.Loader do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.Oban do
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.ReleaseRuntimeProvider do
|
||||
@moduledoc """
|
||||
Imports runtime config and `{env}.exported_from_db.secret.exs` for releases.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.TransferTask do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ConfigDB do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Constants do
|
||||
|
|
@ -27,4 +27,10 @@ defmodule Pleroma.Constants do
|
|||
do:
|
||||
~w(index.html robots.txt static static-fe finmoji emoji packs sounds images instance sw.js sw-pleroma.js favicon.png schemas doc embed.js embed.css)
|
||||
)
|
||||
|
||||
# basic regex, just there to weed out potential mistakes
|
||||
# https://datatracker.ietf.org/doc/html/rfc2045#section-5.1
|
||||
const(mime_regex,
|
||||
do: ~r/^[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+\/[^[:cntrl:] ()<>@,;:\\"\/\[\]?=]+(; .*)?$/
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Conversation do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Conversation.Participation do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Conversation.Participation.RecipientShip do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.CounterCache do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.DataMigration do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Delivery do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Docs.Generator do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Docs.JSON do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Docs.Markdown do
|
||||
|
|
|
|||
10
lib/pleroma/docs/translator.ex
Normal file
10
lib/pleroma/docs/translator.ex
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Docs.Translator do
|
||||
require Pleroma.Docs.Translator.Compiler
|
||||
require Pleroma.Web.Gettext
|
||||
|
||||
@before_compile Pleroma.Docs.Translator.Compiler
|
||||
end
|
||||
119
lib/pleroma/docs/translator/compiler.ex
Normal file
119
lib/pleroma/docs/translator/compiler.ex
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Docs.Translator.Compiler do
|
||||
@external_resource "config/description.exs"
|
||||
@raw_config Pleroma.Config.Loader.read("config/description.exs")
|
||||
@raw_descriptions @raw_config[:pleroma][:config_description]
|
||||
|
||||
defmacro __before_compile__(_env) do
|
||||
strings =
|
||||
__MODULE__.descriptions()
|
||||
|> __MODULE__.extract_strings()
|
||||
|
||||
quote do
|
||||
def placeholder do
|
||||
unquote do
|
||||
Enum.map(
|
||||
strings,
|
||||
fn {path, type, string} ->
|
||||
ctxt = msgctxt_for(path, type)
|
||||
|
||||
quote do
|
||||
Pleroma.Web.Gettext.dpgettext_noop(
|
||||
"config_descriptions",
|
||||
unquote(ctxt),
|
||||
unquote(string)
|
||||
)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def descriptions do
|
||||
Pleroma.Web.ActivityPub.MRF.config_descriptions()
|
||||
|> Enum.reduce(@raw_descriptions, fn description, acc -> [description | acc] end)
|
||||
|> Pleroma.Docs.Generator.convert_to_strings()
|
||||
end
|
||||
|
||||
def extract_strings(descriptions) do
|
||||
descriptions
|
||||
|> Enum.reduce(%{strings: [], path: []}, &process_item/2)
|
||||
|> Map.get(:strings)
|
||||
end
|
||||
|
||||
defp process_item(entity, acc) do
|
||||
current_level =
|
||||
acc
|
||||
|> process_desc(entity)
|
||||
|> process_label(entity)
|
||||
|
||||
process_children(entity, current_level)
|
||||
end
|
||||
|
||||
defp process_desc(acc, %{description: desc} = item) do
|
||||
%{
|
||||
strings: [{acc.path ++ [key_for(item)], "description", desc} | acc.strings],
|
||||
path: acc.path
|
||||
}
|
||||
end
|
||||
|
||||
defp process_desc(acc, _) do
|
||||
acc
|
||||
end
|
||||
|
||||
defp process_label(acc, %{label: label} = item) do
|
||||
%{
|
||||
strings: [{acc.path ++ [key_for(item)], "label", label} | acc.strings],
|
||||
path: acc.path
|
||||
}
|
||||
end
|
||||
|
||||
defp process_label(acc, _) do
|
||||
acc
|
||||
end
|
||||
|
||||
defp process_children(%{children: children} = item, acc) do
|
||||
current_level = Map.put(acc, :path, acc.path ++ [key_for(item)])
|
||||
|
||||
children
|
||||
|> Enum.reduce(current_level, &process_item/2)
|
||||
|> Map.put(:path, acc.path)
|
||||
end
|
||||
|
||||
defp process_children(_, acc) do
|
||||
acc
|
||||
end
|
||||
|
||||
def msgctxt_for(path, type) do
|
||||
"config #{type} at #{Enum.join(path, " > ")}"
|
||||
end
|
||||
|
||||
defp convert_group({_, group}) do
|
||||
group
|
||||
end
|
||||
|
||||
defp convert_group(group) do
|
||||
group
|
||||
end
|
||||
|
||||
def key_for(%{group: group, key: key}) do
|
||||
"#{convert_group(group)}-#{key}"
|
||||
end
|
||||
|
||||
def key_for(%{group: group}) do
|
||||
convert_group(group)
|
||||
end
|
||||
|
||||
def key_for(%{key: key}) do
|
||||
key
|
||||
end
|
||||
|
||||
def key_for(_) do
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import EctoEnum
|
||||
|
|
@ -10,7 +10,8 @@ defenum(Pleroma.UserRelationship.Type,
|
|||
reblog_mute: 3,
|
||||
notification_mute: 4,
|
||||
inverse_subscription: 5,
|
||||
suggestion_dismiss: 6
|
||||
suggestion_dismiss: 6,
|
||||
endorsement: 7
|
||||
)
|
||||
|
||||
defenum(Pleroma.FollowingRelationship.State,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Emoji do
|
||||
|
|
|
|||
25
lib/pleroma/ecto_type/activity_pub/object_validators/mime.ex
Normal file
25
lib/pleroma/ecto_type/activity_pub/object_validators/mime.ex
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.MIME do
|
||||
use Ecto.Type
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
def type, do: :string
|
||||
|
||||
def cast(mime) when is_binary(mime) do
|
||||
if mime =~ Pleroma.Constants.mime_regex() do
|
||||
{:ok, mime}
|
||||
else
|
||||
{:ok, "application/octet-stream"}
|
||||
end
|
||||
end
|
||||
|
||||
def cast(_), do: :error
|
||||
|
||||
def dump(data), do: {:ok, data}
|
||||
|
||||
def load(data), do: {:ok, data}
|
||||
end
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.SafeText do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Uri do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.Config.Atom do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.Config.BinaryValue do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emails.AdminEmail do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emails.Mailer do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emails.NewUsersDigestEmail do
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emails.UserEmail do
|
||||
@moduledoc "User emails"
|
||||
|
||||
require Pleroma.Web.Gettext
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.Gettext
|
||||
alias Pleroma.Web.Router
|
||||
|
||||
import Swoosh.Email
|
||||
|
|
@ -27,29 +30,75 @@ defmodule Pleroma.Emails.UserEmail do
|
|||
|
||||
@spec welcome(User.t(), map()) :: Swoosh.Email.t()
|
||||
def welcome(user, opts \\ %{}) do
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(Map.get(opts, :sender, sender()))
|
||||
|> subject(Map.get(opts, :subject, "Welcome to #{instance_name()}!"))
|
||||
|> html_body(Map.get(opts, :html, "Welcome to #{instance_name()}!"))
|
||||
|> text_body(Map.get(opts, :text, "Welcome to #{instance_name()}!"))
|
||||
Gettext.with_locale_or_default user.language do
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(Map.get(opts, :sender, sender()))
|
||||
|> subject(
|
||||
Map.get(
|
||||
opts,
|
||||
:subject,
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"welcome email subject",
|
||||
"Welcome to %{instance_name}!",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
)
|
||||
)
|
||||
|> html_body(
|
||||
Map.get(
|
||||
opts,
|
||||
:html,
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"welcome email html body",
|
||||
"Welcome to %{instance_name}!",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
)
|
||||
)
|
||||
|> text_body(
|
||||
Map.get(
|
||||
opts,
|
||||
:text,
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"welcome email text body",
|
||||
"Welcome to %{instance_name}!",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def password_reset_email(user, token) when is_binary(token) do
|
||||
password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)
|
||||
Gettext.with_locale_or_default user.language do
|
||||
password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)
|
||||
|
||||
html_body = """
|
||||
<h3>Reset your password at #{instance_name()}</h3>
|
||||
<p>Someone has requested password change for your account at #{instance_name()}.</p>
|
||||
<p>If it was you, visit the following link to proceed: <a href="#{password_reset_url}">reset password</a>.</p>
|
||||
<p>If it was someone else, nothing to worry about: your data is secure and your password has not been changed.</p>
|
||||
"""
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"password reset email body",
|
||||
"""
|
||||
<h3>Reset your password at %{instance_name}</h3>
|
||||
<p>Someone has requested password change for your account at %{instance_name}.</p>
|
||||
<p>If it was you, visit the following link to proceed: <a href="%{password_reset_url}">reset password</a>.</p>
|
||||
<p>If it was someone else, nothing to worry about: your data is secure and your password has not been changed.</p>
|
||||
""",
|
||||
instance_name: instance_name(),
|
||||
password_reset_url: password_reset_url
|
||||
)
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("Password reset")
|
||||
|> html_body(html_body)
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject(
|
||||
Gettext.dpgettext("static_pages", "password reset email subject", "Password reset")
|
||||
)
|
||||
|> html_body(html_body)
|
||||
end
|
||||
end
|
||||
|
||||
def user_invitation_email(
|
||||
|
|
@ -58,73 +107,136 @@ defmodule Pleroma.Emails.UserEmail do
|
|||
to_email,
|
||||
to_name \\ nil
|
||||
) do
|
||||
registration_url =
|
||||
Router.Helpers.redirect_url(
|
||||
Endpoint,
|
||||
:registration_page,
|
||||
user_invite_token.token
|
||||
Gettext.with_locale_or_default user.language do
|
||||
registration_url =
|
||||
Router.Helpers.redirect_url(
|
||||
Endpoint,
|
||||
:registration_page,
|
||||
user_invite_token.token
|
||||
)
|
||||
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"user invitation email body",
|
||||
"""
|
||||
<h3>You are invited to %{instance_name}</h3>
|
||||
<p>%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.</p>
|
||||
<p>Click the following link to register: <a href="%{registration_url}">accept invitation</a>.</p>
|
||||
""",
|
||||
instance_name: instance_name(),
|
||||
inviter_name: user.name,
|
||||
registration_url: registration_url
|
||||
)
|
||||
|
||||
new()
|
||||
|> to(recipient(to_email, to_name))
|
||||
|> from(sender())
|
||||
|> subject(
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"user invitation email subject",
|
||||
"Invitation to %{instance_name}",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
)
|
||||
|
||||
html_body = """
|
||||
<h3>You are invited to #{instance_name()}</h3>
|
||||
<p>#{user.name} invites you to join #{instance_name()}, an instance of Pleroma federated social networking platform.</p>
|
||||
<p>Click the following link to register: <a href="#{registration_url}">accept invitation</a>.</p>
|
||||
"""
|
||||
|
||||
new()
|
||||
|> to(recipient(to_email, to_name))
|
||||
|> from(sender())
|
||||
|> subject("Invitation to #{instance_name()}")
|
||||
|> html_body(html_body)
|
||||
|> html_body(html_body)
|
||||
end
|
||||
end
|
||||
|
||||
def account_confirmation_email(user) do
|
||||
confirmation_url =
|
||||
Router.Helpers.confirm_email_url(
|
||||
Endpoint,
|
||||
:confirm_email,
|
||||
user.id,
|
||||
to_string(user.confirmation_token)
|
||||
Gettext.with_locale_or_default user.language do
|
||||
confirmation_url =
|
||||
Router.Helpers.confirm_email_url(
|
||||
Endpoint,
|
||||
:confirm_email,
|
||||
user.id,
|
||||
to_string(user.confirmation_token)
|
||||
)
|
||||
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"confirmation email body",
|
||||
"""
|
||||
<h3>Thank you for registering on %{instance_name}</h3>
|
||||
<p>Email confirmation is required to activate the account.</p>
|
||||
<p>Please click the following link to <a href="%{confirmation_url}">activate your account</a>.</p>
|
||||
""",
|
||||
instance_name: instance_name(),
|
||||
confirmation_url: confirmation_url
|
||||
)
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject(
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"confirmation email subject",
|
||||
"%{instance_name} account confirmation",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
)
|
||||
|
||||
html_body = """
|
||||
<h3>Thank you for registering on #{instance_name()}</h3>
|
||||
<p>Email confirmation is required to activate the account.</p>
|
||||
<p>Please click the following link to <a href="#{confirmation_url}">activate your account</a>.</p>
|
||||
"""
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("#{instance_name()} account confirmation")
|
||||
|> html_body(html_body)
|
||||
|> html_body(html_body)
|
||||
end
|
||||
end
|
||||
|
||||
def approval_pending_email(user) do
|
||||
html_body = """
|
||||
<h3>Awaiting Approval</h3>
|
||||
<p>Your account at #{instance_name()} is being reviewed by staff. You will receive another email once your account is approved.</p>
|
||||
"""
|
||||
Gettext.with_locale_or_default user.language do
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"approval pending email body",
|
||||
"""
|
||||
<h3>Awaiting Approval</h3>
|
||||
<p>Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.</p>
|
||||
""",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("Your account is awaiting approval")
|
||||
|> html_body(html_body)
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject(
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"approval pending email subject",
|
||||
"Your account is awaiting approval"
|
||||
)
|
||||
)
|
||||
|> html_body(html_body)
|
||||
end
|
||||
end
|
||||
|
||||
def successful_registration_email(user) do
|
||||
html_body = """
|
||||
<h3>Hello @#{user.nickname},</h3>
|
||||
<p>Your account at #{instance_name()} has been registered successfully.</p>
|
||||
<p>No further action is required to activate your account.</p>
|
||||
"""
|
||||
Gettext.with_locale_or_default user.language do
|
||||
html_body =
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"successful registration email body",
|
||||
"""
|
||||
<h3>Hello @%{nickname},</h3>
|
||||
<p>Your account at %{instance_name} has been registered successfully.</p>
|
||||
<p>No further action is required to activate your account.</p>
|
||||
""",
|
||||
nickname: user.nickname,
|
||||
instance_name: instance_name()
|
||||
)
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("Account registered on #{instance_name()}")
|
||||
|> html_body(html_body)
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject(
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"successful registration email subject",
|
||||
"Account registered on %{instance_name}",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
)
|
||||
|> html_body(html_body)
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
@ -134,69 +246,78 @@ defmodule Pleroma.Emails.UserEmail do
|
|||
"""
|
||||
@spec digest_email(User.t()) :: Swoosh.Email.t() | nil
|
||||
def digest_email(user) do
|
||||
notifications = Pleroma.Notification.for_user_since(user, user.last_digest_emailed_at)
|
||||
Gettext.with_locale_or_default user.language do
|
||||
notifications = Pleroma.Notification.for_user_since(user, user.last_digest_emailed_at)
|
||||
|
||||
mentions =
|
||||
notifications
|
||||
|> Enum.filter(&(&1.activity.data["type"] == "Create"))
|
||||
|> Enum.map(fn notification ->
|
||||
object = Pleroma.Object.normalize(notification.activity, fetch: false)
|
||||
mentions =
|
||||
notifications
|
||||
|> Enum.filter(&(&1.activity.data["type"] == "Create"))
|
||||
|> Enum.map(fn notification ->
|
||||
object = Pleroma.Object.normalize(notification.activity, fetch: false)
|
||||
|
||||
if not is_nil(object) do
|
||||
object = update_in(object.data["content"], &format_links/1)
|
||||
if not is_nil(object) do
|
||||
object = update_in(object.data["content"], &format_links/1)
|
||||
|
||||
%{
|
||||
data: notification,
|
||||
object: object,
|
||||
from: User.get_by_ap_id(notification.activity.actor)
|
||||
}
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
%{
|
||||
data: notification,
|
||||
object: object,
|
||||
from: User.get_by_ap_id(notification.activity.actor)
|
||||
}
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
followers =
|
||||
notifications
|
||||
|> Enum.filter(&(&1.activity.data["type"] == "Follow"))
|
||||
|> Enum.map(fn notification ->
|
||||
from = User.get_by_ap_id(notification.activity.actor)
|
||||
followers =
|
||||
notifications
|
||||
|> Enum.filter(&(&1.activity.data["type"] == "Follow"))
|
||||
|> Enum.map(fn notification ->
|
||||
from = User.get_by_ap_id(notification.activity.actor)
|
||||
|
||||
if not is_nil(from) do
|
||||
%{
|
||||
data: notification,
|
||||
object: Pleroma.Object.normalize(notification.activity, fetch: false),
|
||||
from: User.get_by_ap_id(notification.activity.actor)
|
||||
}
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
if not is_nil(from) do
|
||||
%{
|
||||
data: notification,
|
||||
object: Pleroma.Object.normalize(notification.activity, fetch: false),
|
||||
from: User.get_by_ap_id(notification.activity.actor)
|
||||
}
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
unless Enum.empty?(mentions) do
|
||||
styling = Config.get([__MODULE__, :styling])
|
||||
logo = Config.get([__MODULE__, :logo])
|
||||
unless Enum.empty?(mentions) do
|
||||
styling = Config.get([__MODULE__, :styling])
|
||||
logo = Config.get([__MODULE__, :logo])
|
||||
|
||||
html_data = %{
|
||||
instance: instance_name(),
|
||||
user: user,
|
||||
mentions: mentions,
|
||||
followers: followers,
|
||||
unsubscribe_link: unsubscribe_url(user, "digest"),
|
||||
styling: styling
|
||||
}
|
||||
html_data = %{
|
||||
instance: instance_name(),
|
||||
user: user,
|
||||
mentions: mentions,
|
||||
followers: followers,
|
||||
unsubscribe_link: unsubscribe_url(user, "digest"),
|
||||
styling: styling
|
||||
}
|
||||
|
||||
logo_path =
|
||||
if is_nil(logo) do
|
||||
Path.join(:code.priv_dir(:pleroma), "static/static/logo.svg")
|
||||
else
|
||||
Path.join(Config.get([:instance, :static_dir]), logo)
|
||||
end
|
||||
logo_path =
|
||||
if is_nil(logo) do
|
||||
Path.join(:code.priv_dir(:pleroma), "static/static/logo.svg")
|
||||
else
|
||||
Path.join(Config.get([:instance, :static_dir]), logo)
|
||||
end
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("Your digest from #{instance_name()}")
|
||||
|> put_layout(false)
|
||||
|> render_body("digest.html", html_data)
|
||||
|> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.svg", type: :inline))
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject(
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"digest email subject",
|
||||
"Your digest from %{instance_name}",
|
||||
instance_name: instance_name()
|
||||
)
|
||||
)
|
||||
|> put_layout(false)
|
||||
|> render_body("digest.html", html_data)
|
||||
|> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.svg", type: :inline))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -226,27 +347,47 @@ defmodule Pleroma.Emails.UserEmail do
|
|||
|
||||
def backup_is_ready_email(backup, admin_user_id \\ nil) do
|
||||
%{user: user} = Pleroma.Repo.preload(backup, :user)
|
||||
download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup)
|
||||
|
||||
html_body =
|
||||
if is_nil(admin_user_id) do
|
||||
"""
|
||||
<p>You requested a full backup of your Pleroma account. It's ready for download:</p>
|
||||
<p><a href="#{download_url}">#{download_url}</a></p>
|
||||
"""
|
||||
else
|
||||
admin = Pleroma.Repo.get(User, admin_user_id)
|
||||
Gettext.with_locale_or_default user.language do
|
||||
download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup)
|
||||
|
||||
"""
|
||||
<p>Admin @#{admin.nickname} requested a full backup of your Pleroma account. It's ready for download:</p>
|
||||
<p><a href="#{download_url}">#{download_url}</a></p>
|
||||
"""
|
||||
end
|
||||
html_body =
|
||||
if is_nil(admin_user_id) do
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"account archive email body - self-requested",
|
||||
"""
|
||||
<p>You requested a full backup of your Pleroma account. It's ready for download:</p>
|
||||
<p><a href="%{download_url}">%{download_url}</a></p>
|
||||
""",
|
||||
download_url: download_url
|
||||
)
|
||||
else
|
||||
admin = Pleroma.Repo.get(User, admin_user_id)
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject("Your account archive is ready")
|
||||
|> html_body(html_body)
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"account archive email body - admin requested",
|
||||
"""
|
||||
<p>Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:</p>
|
||||
<p><a href="%{download_url}">%{download_url}</a></p>
|
||||
""",
|
||||
admin_nickname: admin.nickname,
|
||||
download_url: download_url
|
||||
)
|
||||
end
|
||||
|
||||
new()
|
||||
|> to(recipient(user))
|
||||
|> from(sender())
|
||||
|> subject(
|
||||
Gettext.dpgettext(
|
||||
"static_pages",
|
||||
"account archive email subject",
|
||||
"Your account archive is ready"
|
||||
)
|
||||
)
|
||||
|> html_body(html_body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
# emoji-test.txt
|
||||
# Date: 2020-09-12, 22:19:50 GMT
|
||||
# © 2020 Unicode®, Inc.
|
||||
# Date: 2021-08-26, 17:22:23 GMT
|
||||
# © 2021 Unicode®, Inc.
|
||||
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
|
||||
# For terms of use, see http://www.unicode.org/terms_of_use.html
|
||||
#
|
||||
# Emoji Keyboard/Display Test Data for UTS #51
|
||||
# Version: 13.1
|
||||
# Version: 14.0
|
||||
#
|
||||
# For documentation and usage, see http://www.unicode.org/reports/tr51
|
||||
#
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
1F602 ; fully-qualified # 😂 E0.6 face with tears of joy
|
||||
1F642 ; fully-qualified # 🙂 E1.0 slightly smiling face
|
||||
1F643 ; fully-qualified # 🙃 E1.0 upside-down face
|
||||
1FAE0 ; fully-qualified # 🫠 E14.0 melting face
|
||||
1F609 ; fully-qualified # 😉 E0.6 winking face
|
||||
1F60A ; fully-qualified # 😊 E0.6 smiling face with smiling eyes
|
||||
1F607 ; fully-qualified # 😇 E1.0 smiling face with halo
|
||||
|
|
@ -68,10 +69,13 @@
|
|||
1F911 ; fully-qualified # 🤑 E1.0 money-mouth face
|
||||
|
||||
# subgroup: face-hand
|
||||
1F917 ; fully-qualified # 🤗 E1.0 hugging face
|
||||
1F917 ; fully-qualified # 🤗 E1.0 smiling face with open hands
|
||||
1F92D ; fully-qualified # 🤭 E5.0 face with hand over mouth
|
||||
1FAE2 ; fully-qualified # 🫢 E14.0 face with open eyes and hand over mouth
|
||||
1FAE3 ; fully-qualified # 🫣 E14.0 face with peeking eye
|
||||
1F92B ; fully-qualified # 🤫 E5.0 shushing face
|
||||
1F914 ; fully-qualified # 🤔 E1.0 thinking face
|
||||
1FAE1 ; fully-qualified # 🫡 E14.0 saluting face
|
||||
|
||||
# subgroup: face-neutral-skeptical
|
||||
1F910 ; fully-qualified # 🤐 E1.0 zipper-mouth face
|
||||
|
|
@ -79,6 +83,7 @@
|
|||
1F610 ; fully-qualified # 😐 E0.7 neutral face
|
||||
1F611 ; fully-qualified # 😑 E1.0 expressionless face
|
||||
1F636 ; fully-qualified # 😶 E1.0 face without mouth
|
||||
1FAE5 ; fully-qualified # 🫥 E14.0 dotted line face
|
||||
1F636 200D 1F32B FE0F ; fully-qualified # 😶🌫️ E13.1 face in clouds
|
||||
1F636 200D 1F32B ; minimally-qualified # 😶🌫 E13.1 face in clouds
|
||||
1F60F ; fully-qualified # 😏 E0.6 smirking face
|
||||
|
|
@ -105,7 +110,7 @@
|
|||
1F975 ; fully-qualified # 🥵 E11.0 hot face
|
||||
1F976 ; fully-qualified # 🥶 E11.0 cold face
|
||||
1F974 ; fully-qualified # 🥴 E11.0 woozy face
|
||||
1F635 ; fully-qualified # 😵 E0.6 knocked-out face
|
||||
1F635 ; fully-qualified # 😵 E0.6 face with crossed-out eyes
|
||||
1F635 200D 1F4AB ; fully-qualified # 😵💫 E13.1 face with spiral eyes
|
||||
1F92F ; fully-qualified # 🤯 E5.0 exploding head
|
||||
|
||||
|
|
@ -121,6 +126,7 @@
|
|||
|
||||
# subgroup: face-concerned
|
||||
1F615 ; fully-qualified # 😕 E1.0 confused face
|
||||
1FAE4 ; fully-qualified # 🫤 E14.0 face with diagonal mouth
|
||||
1F61F ; fully-qualified # 😟 E1.0 worried face
|
||||
1F641 ; fully-qualified # 🙁 E1.0 slightly frowning face
|
||||
2639 FE0F ; fully-qualified # ☹️ E0.7 frowning face
|
||||
|
|
@ -130,6 +136,7 @@
|
|||
1F632 ; fully-qualified # 😲 E0.6 astonished face
|
||||
1F633 ; fully-qualified # 😳 E0.6 flushed face
|
||||
1F97A ; fully-qualified # 🥺 E11.0 pleading face
|
||||
1F979 ; fully-qualified # 🥹 E14.0 face holding back tears
|
||||
1F626 ; fully-qualified # 😦 E1.0 frowning face with open mouth
|
||||
1F627 ; fully-qualified # 😧 E1.0 anguished face
|
||||
1F628 ; fully-qualified # 😨 E0.6 fearful face
|
||||
|
|
@ -232,8 +239,8 @@
|
|||
1F4AD ; fully-qualified # 💭 E1.0 thought balloon
|
||||
1F4A4 ; fully-qualified # 💤 E0.6 zzz
|
||||
|
||||
# Smileys & Emotion subtotal: 170
|
||||
# Smileys & Emotion subtotal: 170 w/o modifiers
|
||||
# Smileys & Emotion subtotal: 177
|
||||
# Smileys & Emotion subtotal: 177 w/o modifiers
|
||||
|
||||
# group: People & Body
|
||||
|
||||
|
|
@ -269,6 +276,30 @@
|
|||
1F596 1F3FD ; fully-qualified # 🖖🏽 E1.0 vulcan salute: medium skin tone
|
||||
1F596 1F3FE ; fully-qualified # 🖖🏾 E1.0 vulcan salute: medium-dark skin tone
|
||||
1F596 1F3FF ; fully-qualified # 🖖🏿 E1.0 vulcan salute: dark skin tone
|
||||
1FAF1 ; fully-qualified # 🫱 E14.0 rightwards hand
|
||||
1FAF1 1F3FB ; fully-qualified # 🫱🏻 E14.0 rightwards hand: light skin tone
|
||||
1FAF1 1F3FC ; fully-qualified # 🫱🏼 E14.0 rightwards hand: medium-light skin tone
|
||||
1FAF1 1F3FD ; fully-qualified # 🫱🏽 E14.0 rightwards hand: medium skin tone
|
||||
1FAF1 1F3FE ; fully-qualified # 🫱🏾 E14.0 rightwards hand: medium-dark skin tone
|
||||
1FAF1 1F3FF ; fully-qualified # 🫱🏿 E14.0 rightwards hand: dark skin tone
|
||||
1FAF2 ; fully-qualified # 🫲 E14.0 leftwards hand
|
||||
1FAF2 1F3FB ; fully-qualified # 🫲🏻 E14.0 leftwards hand: light skin tone
|
||||
1FAF2 1F3FC ; fully-qualified # 🫲🏼 E14.0 leftwards hand: medium-light skin tone
|
||||
1FAF2 1F3FD ; fully-qualified # 🫲🏽 E14.0 leftwards hand: medium skin tone
|
||||
1FAF2 1F3FE ; fully-qualified # 🫲🏾 E14.0 leftwards hand: medium-dark skin tone
|
||||
1FAF2 1F3FF ; fully-qualified # 🫲🏿 E14.0 leftwards hand: dark skin tone
|
||||
1FAF3 ; fully-qualified # 🫳 E14.0 palm down hand
|
||||
1FAF3 1F3FB ; fully-qualified # 🫳🏻 E14.0 palm down hand: light skin tone
|
||||
1FAF3 1F3FC ; fully-qualified # 🫳🏼 E14.0 palm down hand: medium-light skin tone
|
||||
1FAF3 1F3FD ; fully-qualified # 🫳🏽 E14.0 palm down hand: medium skin tone
|
||||
1FAF3 1F3FE ; fully-qualified # 🫳🏾 E14.0 palm down hand: medium-dark skin tone
|
||||
1FAF3 1F3FF ; fully-qualified # 🫳🏿 E14.0 palm down hand: dark skin tone
|
||||
1FAF4 ; fully-qualified # 🫴 E14.0 palm up hand
|
||||
1FAF4 1F3FB ; fully-qualified # 🫴🏻 E14.0 palm up hand: light skin tone
|
||||
1FAF4 1F3FC ; fully-qualified # 🫴🏼 E14.0 palm up hand: medium-light skin tone
|
||||
1FAF4 1F3FD ; fully-qualified # 🫴🏽 E14.0 palm up hand: medium skin tone
|
||||
1FAF4 1F3FE ; fully-qualified # 🫴🏾 E14.0 palm up hand: medium-dark skin tone
|
||||
1FAF4 1F3FF ; fully-qualified # 🫴🏿 E14.0 palm up hand: dark skin tone
|
||||
|
||||
# subgroup: hand-fingers-partial
|
||||
1F44C ; fully-qualified # 👌 E0.6 OK hand
|
||||
|
|
@ -302,6 +333,12 @@
|
|||
1F91E 1F3FD ; fully-qualified # 🤞🏽 E3.0 crossed fingers: medium skin tone
|
||||
1F91E 1F3FE ; fully-qualified # 🤞🏾 E3.0 crossed fingers: medium-dark skin tone
|
||||
1F91E 1F3FF ; fully-qualified # 🤞🏿 E3.0 crossed fingers: dark skin tone
|
||||
1FAF0 ; fully-qualified # 🫰 E14.0 hand with index finger and thumb crossed
|
||||
1FAF0 1F3FB ; fully-qualified # 🫰🏻 E14.0 hand with index finger and thumb crossed: light skin tone
|
||||
1FAF0 1F3FC ; fully-qualified # 🫰🏼 E14.0 hand with index finger and thumb crossed: medium-light skin tone
|
||||
1FAF0 1F3FD ; fully-qualified # 🫰🏽 E14.0 hand with index finger and thumb crossed: medium skin tone
|
||||
1FAF0 1F3FE ; fully-qualified # 🫰🏾 E14.0 hand with index finger and thumb crossed: medium-dark skin tone
|
||||
1FAF0 1F3FF ; fully-qualified # 🫰🏿 E14.0 hand with index finger and thumb crossed: dark skin tone
|
||||
1F91F ; fully-qualified # 🤟 E5.0 love-you gesture
|
||||
1F91F 1F3FB ; fully-qualified # 🤟🏻 E5.0 love-you gesture: light skin tone
|
||||
1F91F 1F3FC ; fully-qualified # 🤟🏼 E5.0 love-you gesture: medium-light skin tone
|
||||
|
|
@ -359,6 +396,12 @@
|
|||
261D 1F3FD ; fully-qualified # ☝🏽 E1.0 index pointing up: medium skin tone
|
||||
261D 1F3FE ; fully-qualified # ☝🏾 E1.0 index pointing up: medium-dark skin tone
|
||||
261D 1F3FF ; fully-qualified # ☝🏿 E1.0 index pointing up: dark skin tone
|
||||
1FAF5 ; fully-qualified # 🫵 E14.0 index pointing at the viewer
|
||||
1FAF5 1F3FB ; fully-qualified # 🫵🏻 E14.0 index pointing at the viewer: light skin tone
|
||||
1FAF5 1F3FC ; fully-qualified # 🫵🏼 E14.0 index pointing at the viewer: medium-light skin tone
|
||||
1FAF5 1F3FD ; fully-qualified # 🫵🏽 E14.0 index pointing at the viewer: medium skin tone
|
||||
1FAF5 1F3FE ; fully-qualified # 🫵🏾 E14.0 index pointing at the viewer: medium-dark skin tone
|
||||
1FAF5 1F3FF ; fully-qualified # 🫵🏿 E14.0 index pointing at the viewer: dark skin tone
|
||||
|
||||
# subgroup: hand-fingers-closed
|
||||
1F44D ; fully-qualified # 👍 E0.6 thumbs up
|
||||
|
|
@ -411,6 +454,12 @@
|
|||
1F64C 1F3FD ; fully-qualified # 🙌🏽 E1.0 raising hands: medium skin tone
|
||||
1F64C 1F3FE ; fully-qualified # 🙌🏾 E1.0 raising hands: medium-dark skin tone
|
||||
1F64C 1F3FF ; fully-qualified # 🙌🏿 E1.0 raising hands: dark skin tone
|
||||
1FAF6 ; fully-qualified # 🫶 E14.0 heart hands
|
||||
1FAF6 1F3FB ; fully-qualified # 🫶🏻 E14.0 heart hands: light skin tone
|
||||
1FAF6 1F3FC ; fully-qualified # 🫶🏼 E14.0 heart hands: medium-light skin tone
|
||||
1FAF6 1F3FD ; fully-qualified # 🫶🏽 E14.0 heart hands: medium skin tone
|
||||
1FAF6 1F3FE ; fully-qualified # 🫶🏾 E14.0 heart hands: medium-dark skin tone
|
||||
1FAF6 1F3FF ; fully-qualified # 🫶🏿 E14.0 heart hands: dark skin tone
|
||||
1F450 ; fully-qualified # 👐 E0.6 open hands
|
||||
1F450 1F3FB ; fully-qualified # 👐🏻 E1.0 open hands: light skin tone
|
||||
1F450 1F3FC ; fully-qualified # 👐🏼 E1.0 open hands: medium-light skin tone
|
||||
|
|
@ -424,6 +473,31 @@
|
|||
1F932 1F3FE ; fully-qualified # 🤲🏾 E5.0 palms up together: medium-dark skin tone
|
||||
1F932 1F3FF ; fully-qualified # 🤲🏿 E5.0 palms up together: dark skin tone
|
||||
1F91D ; fully-qualified # 🤝 E3.0 handshake
|
||||
1F91D 1F3FB ; fully-qualified # 🤝🏻 E3.0 handshake: light skin tone
|
||||
1F91D 1F3FC ; fully-qualified # 🤝🏼 E3.0 handshake: medium-light skin tone
|
||||
1F91D 1F3FD ; fully-qualified # 🤝🏽 E3.0 handshake: medium skin tone
|
||||
1F91D 1F3FE ; fully-qualified # 🤝🏾 E3.0 handshake: medium-dark skin tone
|
||||
1F91D 1F3FF ; fully-qualified # 🤝🏿 E3.0 handshake: dark skin tone
|
||||
1FAF1 1F3FB 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏻🫲🏼 E14.0 handshake: light skin tone, medium-light skin tone
|
||||
1FAF1 1F3FB 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏻🫲🏽 E14.0 handshake: light skin tone, medium skin tone
|
||||
1FAF1 1F3FB 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏻🫲🏾 E14.0 handshake: light skin tone, medium-dark skin tone
|
||||
1FAF1 1F3FB 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏻🫲🏿 E14.0 handshake: light skin tone, dark skin tone
|
||||
1FAF1 1F3FC 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏼🫲🏻 E14.0 handshake: medium-light skin tone, light skin tone
|
||||
1FAF1 1F3FC 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏼🫲🏽 E14.0 handshake: medium-light skin tone, medium skin tone
|
||||
1FAF1 1F3FC 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏼🫲🏾 E14.0 handshake: medium-light skin tone, medium-dark skin tone
|
||||
1FAF1 1F3FC 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏼🫲🏿 E14.0 handshake: medium-light skin tone, dark skin tone
|
||||
1FAF1 1F3FD 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏽🫲🏻 E14.0 handshake: medium skin tone, light skin tone
|
||||
1FAF1 1F3FD 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏽🫲🏼 E14.0 handshake: medium skin tone, medium-light skin tone
|
||||
1FAF1 1F3FD 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏽🫲🏾 E14.0 handshake: medium skin tone, medium-dark skin tone
|
||||
1FAF1 1F3FD 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏽🫲🏿 E14.0 handshake: medium skin tone, dark skin tone
|
||||
1FAF1 1F3FE 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏾🫲🏻 E14.0 handshake: medium-dark skin tone, light skin tone
|
||||
1FAF1 1F3FE 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏾🫲🏼 E14.0 handshake: medium-dark skin tone, medium-light skin tone
|
||||
1FAF1 1F3FE 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏾🫲🏽 E14.0 handshake: medium-dark skin tone, medium skin tone
|
||||
1FAF1 1F3FE 200D 1FAF2 1F3FF ; fully-qualified # 🫱🏾🫲🏿 E14.0 handshake: medium-dark skin tone, dark skin tone
|
||||
1FAF1 1F3FF 200D 1FAF2 1F3FB ; fully-qualified # 🫱🏿🫲🏻 E14.0 handshake: dark skin tone, light skin tone
|
||||
1FAF1 1F3FF 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏿🫲🏼 E14.0 handshake: dark skin tone, medium-light skin tone
|
||||
1FAF1 1F3FF 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏿🫲🏽 E14.0 handshake: dark skin tone, medium skin tone
|
||||
1FAF1 1F3FF 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏿🫲🏾 E14.0 handshake: dark skin tone, medium-dark skin tone
|
||||
1F64F ; fully-qualified # 🙏 E0.6 folded hands
|
||||
1F64F 1F3FB ; fully-qualified # 🙏🏻 E1.0 folded hands: light skin tone
|
||||
1F64F 1F3FC ; fully-qualified # 🙏🏼 E1.0 folded hands: medium-light skin tone
|
||||
|
|
@ -501,6 +575,7 @@
|
|||
1F441 ; unqualified # 👁 E0.7 eye
|
||||
1F445 ; fully-qualified # 👅 E0.6 tongue
|
||||
1F444 ; fully-qualified # 👄 E0.6 mouth
|
||||
1FAE6 ; fully-qualified # 🫦 E14.0 biting lip
|
||||
|
||||
# subgroup: person
|
||||
1F476 ; fully-qualified # 👶 E0.6 baby
|
||||
|
|
@ -1472,6 +1547,12 @@
|
|||
1F477 1F3FE 200D 2640 ; minimally-qualified # 👷🏾♀ E4.0 woman construction worker: medium-dark skin tone
|
||||
1F477 1F3FF 200D 2640 FE0F ; fully-qualified # 👷🏿♀️ E4.0 woman construction worker: dark skin tone
|
||||
1F477 1F3FF 200D 2640 ; minimally-qualified # 👷🏿♀ E4.0 woman construction worker: dark skin tone
|
||||
1FAC5 ; fully-qualified # 🫅 E14.0 person with crown
|
||||
1FAC5 1F3FB ; fully-qualified # 🫅🏻 E14.0 person with crown: light skin tone
|
||||
1FAC5 1F3FC ; fully-qualified # 🫅🏼 E14.0 person with crown: medium-light skin tone
|
||||
1FAC5 1F3FD ; fully-qualified # 🫅🏽 E14.0 person with crown: medium skin tone
|
||||
1FAC5 1F3FE ; fully-qualified # 🫅🏾 E14.0 person with crown: medium-dark skin tone
|
||||
1FAC5 1F3FF ; fully-qualified # 🫅🏿 E14.0 person with crown: dark skin tone
|
||||
1F934 ; fully-qualified # 🤴 E3.0 prince
|
||||
1F934 1F3FB ; fully-qualified # 🤴🏻 E3.0 prince: light skin tone
|
||||
1F934 1F3FC ; fully-qualified # 🤴🏼 E3.0 prince: medium-light skin tone
|
||||
|
|
@ -1592,6 +1673,18 @@
|
|||
1F930 1F3FD ; fully-qualified # 🤰🏽 E3.0 pregnant woman: medium skin tone
|
||||
1F930 1F3FE ; fully-qualified # 🤰🏾 E3.0 pregnant woman: medium-dark skin tone
|
||||
1F930 1F3FF ; fully-qualified # 🤰🏿 E3.0 pregnant woman: dark skin tone
|
||||
1FAC3 ; fully-qualified # 🫃 E14.0 pregnant man
|
||||
1FAC3 1F3FB ; fully-qualified # 🫃🏻 E14.0 pregnant man: light skin tone
|
||||
1FAC3 1F3FC ; fully-qualified # 🫃🏼 E14.0 pregnant man: medium-light skin tone
|
||||
1FAC3 1F3FD ; fully-qualified # 🫃🏽 E14.0 pregnant man: medium skin tone
|
||||
1FAC3 1F3FE ; fully-qualified # 🫃🏾 E14.0 pregnant man: medium-dark skin tone
|
||||
1FAC3 1F3FF ; fully-qualified # 🫃🏿 E14.0 pregnant man: dark skin tone
|
||||
1FAC4 ; fully-qualified # 🫄 E14.0 pregnant person
|
||||
1FAC4 1F3FB ; fully-qualified # 🫄🏻 E14.0 pregnant person: light skin tone
|
||||
1FAC4 1F3FC ; fully-qualified # 🫄🏼 E14.0 pregnant person: medium-light skin tone
|
||||
1FAC4 1F3FD ; fully-qualified # 🫄🏽 E14.0 pregnant person: medium skin tone
|
||||
1FAC4 1F3FE ; fully-qualified # 🫄🏾 E14.0 pregnant person: medium-dark skin tone
|
||||
1FAC4 1F3FF ; fully-qualified # 🫄🏿 E14.0 pregnant person: dark skin tone
|
||||
1F931 ; fully-qualified # 🤱 E5.0 breast-feeding
|
||||
1F931 1F3FB ; fully-qualified # 🤱🏻 E5.0 breast-feeding: light skin tone
|
||||
1F931 1F3FC ; fully-qualified # 🤱🏼 E5.0 breast-feeding: medium-light skin tone
|
||||
|
|
@ -1862,6 +1955,7 @@
|
|||
1F9DF 200D 2642 ; minimally-qualified # 🧟♂ E5.0 man zombie
|
||||
1F9DF 200D 2640 FE0F ; fully-qualified # 🧟♀️ E5.0 woman zombie
|
||||
1F9DF 200D 2640 ; minimally-qualified # 🧟♀ E5.0 woman zombie
|
||||
1F9CC ; fully-qualified # 🧌 E14.0 troll
|
||||
|
||||
# subgroup: person-activity
|
||||
1F486 ; fully-qualified # 💆 E0.6 person getting massage
|
||||
|
|
@ -3168,8 +3262,8 @@
|
|||
1FAC2 ; fully-qualified # 🫂 E13.0 people hugging
|
||||
1F463 ; fully-qualified # 👣 E0.6 footprints
|
||||
|
||||
# People & Body subtotal: 2899
|
||||
# People & Body subtotal: 494 w/o modifiers
|
||||
# People & Body subtotal: 2986
|
||||
# People & Body subtotal: 506 w/o modifiers
|
||||
|
||||
# group: Component
|
||||
|
||||
|
|
@ -3304,6 +3398,7 @@
|
|||
1F988 ; fully-qualified # 🦈 E3.0 shark
|
||||
1F419 ; fully-qualified # 🐙 E0.6 octopus
|
||||
1F41A ; fully-qualified # 🐚 E0.6 spiral shell
|
||||
1FAB8 ; fully-qualified # 🪸 E14.0 coral
|
||||
|
||||
# subgroup: animal-bug
|
||||
1F40C ; fully-qualified # 🐌 E0.6 snail
|
||||
|
|
@ -3329,6 +3424,7 @@
|
|||
1F490 ; fully-qualified # 💐 E0.6 bouquet
|
||||
1F338 ; fully-qualified # 🌸 E0.6 cherry blossom
|
||||
1F4AE ; fully-qualified # 💮 E0.6 white flower
|
||||
1FAB7 ; fully-qualified # 🪷 E14.0 lotus
|
||||
1F3F5 FE0F ; fully-qualified # 🏵️ E0.7 rosette
|
||||
1F3F5 ; unqualified # 🏵 E0.7 rosette
|
||||
1F339 ; fully-qualified # 🌹 E0.6 rose
|
||||
|
|
@ -3353,9 +3449,11 @@
|
|||
1F341 ; fully-qualified # 🍁 E0.6 maple leaf
|
||||
1F342 ; fully-qualified # 🍂 E0.6 fallen leaf
|
||||
1F343 ; fully-qualified # 🍃 E0.6 leaf fluttering in wind
|
||||
1FAB9 ; fully-qualified # 🪹 E14.0 empty nest
|
||||
1FABA ; fully-qualified # 🪺 E14.0 nest with eggs
|
||||
|
||||
# Animals & Nature subtotal: 147
|
||||
# Animals & Nature subtotal: 147 w/o modifiers
|
||||
# Animals & Nature subtotal: 151
|
||||
# Animals & Nature subtotal: 151 w/o modifiers
|
||||
|
||||
# group: Food & Drink
|
||||
|
||||
|
|
@ -3396,6 +3494,7 @@
|
|||
1F9C5 ; fully-qualified # 🧅 E12.0 onion
|
||||
1F344 ; fully-qualified # 🍄 E0.6 mushroom
|
||||
1F95C ; fully-qualified # 🥜 E3.0 peanuts
|
||||
1FAD8 ; fully-qualified # 🫘 E14.0 beans
|
||||
1F330 ; fully-qualified # 🌰 E0.6 chestnut
|
||||
|
||||
# subgroup: food-prepared
|
||||
|
|
@ -3491,6 +3590,7 @@
|
|||
1F37B ; fully-qualified # 🍻 E0.6 clinking beer mugs
|
||||
1F942 ; fully-qualified # 🥂 E3.0 clinking glasses
|
||||
1F943 ; fully-qualified # 🥃 E3.0 tumbler glass
|
||||
1FAD7 ; fully-qualified # 🫗 E14.0 pouring liquid
|
||||
1F964 ; fully-qualified # 🥤 E5.0 cup with straw
|
||||
1F9CB ; fully-qualified # 🧋 E13.0 bubble tea
|
||||
1F9C3 ; fully-qualified # 🧃 E12.0 beverage box
|
||||
|
|
@ -3504,10 +3604,11 @@
|
|||
1F374 ; fully-qualified # 🍴 E0.6 fork and knife
|
||||
1F944 ; fully-qualified # 🥄 E3.0 spoon
|
||||
1F52A ; fully-qualified # 🔪 E0.6 kitchen knife
|
||||
1FAD9 ; fully-qualified # 🫙 E14.0 jar
|
||||
1F3FA ; fully-qualified # 🏺 E1.0 amphora
|
||||
|
||||
# Food & Drink subtotal: 131
|
||||
# Food & Drink subtotal: 131 w/o modifiers
|
||||
# Food & Drink subtotal: 134
|
||||
# Food & Drink subtotal: 134 w/o modifiers
|
||||
|
||||
# group: Travel & Places
|
||||
|
||||
|
|
@ -3597,6 +3698,7 @@
|
|||
2668 FE0F ; fully-qualified # ♨️ E0.6 hot springs
|
||||
2668 ; unqualified # ♨ E0.6 hot springs
|
||||
1F3A0 ; fully-qualified # 🎠 E0.6 carousel horse
|
||||
1F6DD ; fully-qualified # 🛝 E14.0 playground slide
|
||||
1F3A1 ; fully-qualified # 🎡 E0.6 ferris wheel
|
||||
1F3A2 ; fully-qualified # 🎢 E0.6 roller coaster
|
||||
1F488 ; fully-qualified # 💈 E0.6 barber pole
|
||||
|
|
@ -3652,6 +3754,7 @@
|
|||
1F6E2 FE0F ; fully-qualified # 🛢️ E0.7 oil drum
|
||||
1F6E2 ; unqualified # 🛢 E0.7 oil drum
|
||||
26FD ; fully-qualified # ⛽ E0.6 fuel pump
|
||||
1F6DE ; fully-qualified # 🛞 E14.0 wheel
|
||||
1F6A8 ; fully-qualified # 🚨 E0.6 police car light
|
||||
1F6A5 ; fully-qualified # 🚥 E0.6 horizontal traffic light
|
||||
1F6A6 ; fully-qualified # 🚦 E1.0 vertical traffic light
|
||||
|
|
@ -3660,6 +3763,7 @@
|
|||
|
||||
# subgroup: transport-water
|
||||
2693 ; fully-qualified # ⚓ E0.6 anchor
|
||||
1F6DF ; fully-qualified # 🛟 E14.0 ring buoy
|
||||
26F5 ; fully-qualified # ⛵ E0.6 sailboat
|
||||
1F6F6 ; fully-qualified # 🛶 E3.0 canoe
|
||||
1F6A4 ; fully-qualified # 🚤 E0.6 speedboat
|
||||
|
|
@ -3797,8 +3901,8 @@
|
|||
1F4A7 ; fully-qualified # 💧 E0.6 droplet
|
||||
1F30A ; fully-qualified # 🌊 E0.6 water wave
|
||||
|
||||
# Travel & Places subtotal: 264
|
||||
# Travel & Places subtotal: 264 w/o modifiers
|
||||
# Travel & Places subtotal: 267
|
||||
# Travel & Places subtotal: 267 w/o modifiers
|
||||
|
||||
# group: Activities
|
||||
|
||||
|
|
@ -3874,6 +3978,7 @@
|
|||
1F52E ; fully-qualified # 🔮 E0.6 crystal ball
|
||||
1FA84 ; fully-qualified # 🪄 E13.0 magic wand
|
||||
1F9FF ; fully-qualified # 🧿 E11.0 nazar amulet
|
||||
1FAAC ; fully-qualified # 🪬 E14.0 hamsa
|
||||
1F3AE ; fully-qualified # 🎮 E0.6 video game
|
||||
1F579 FE0F ; fully-qualified # 🕹️ E0.7 joystick
|
||||
1F579 ; unqualified # 🕹 E0.7 joystick
|
||||
|
|
@ -3882,6 +3987,7 @@
|
|||
1F9E9 ; fully-qualified # 🧩 E11.0 puzzle piece
|
||||
1F9F8 ; fully-qualified # 🧸 E11.0 teddy bear
|
||||
1FA85 ; fully-qualified # 🪅 E13.0 piñata
|
||||
1FAA9 ; fully-qualified # 🪩 E14.0 mirror ball
|
||||
1FA86 ; fully-qualified # 🪆 E13.0 nesting dolls
|
||||
2660 FE0F ; fully-qualified # ♠️ E0.6 spade suit
|
||||
2660 ; unqualified # ♠ E0.6 spade suit
|
||||
|
|
@ -3907,8 +4013,8 @@
|
|||
1F9F6 ; fully-qualified # 🧶 E11.0 yarn
|
||||
1FAA2 ; fully-qualified # 🪢 E13.0 knot
|
||||
|
||||
# Activities subtotal: 95
|
||||
# Activities subtotal: 95 w/o modifiers
|
||||
# Activities subtotal: 97
|
||||
# Activities subtotal: 97 w/o modifiers
|
||||
|
||||
# group: Objects
|
||||
|
||||
|
|
@ -4009,6 +4115,7 @@
|
|||
|
||||
# subgroup: computer
|
||||
1F50B ; fully-qualified # 🔋 E0.6 battery
|
||||
1FAAB ; fully-qualified # 🪫 E14.0 low battery
|
||||
1F50C ; fully-qualified # 🔌 E0.6 electric plug
|
||||
1F4BB ; fully-qualified # 💻 E0.6 laptop
|
||||
1F5A5 FE0F ; fully-qualified # 🖥️ E0.7 desktop computer
|
||||
|
|
@ -4207,7 +4314,9 @@
|
|||
1FA78 ; fully-qualified # 🩸 E12.0 drop of blood
|
||||
1F48A ; fully-qualified # 💊 E0.6 pill
|
||||
1FA79 ; fully-qualified # 🩹 E12.0 adhesive bandage
|
||||
1FA7C ; fully-qualified # 🩼 E14.0 crutch
|
||||
1FA7A ; fully-qualified # 🩺 E12.0 stethoscope
|
||||
1FA7B ; fully-qualified # 🩻 E14.0 x-ray
|
||||
|
||||
# subgroup: household
|
||||
1F6AA ; fully-qualified # 🚪 E0.6 door
|
||||
|
|
@ -4232,6 +4341,7 @@
|
|||
1F9FB ; fully-qualified # 🧻 E11.0 roll of paper
|
||||
1FAA3 ; fully-qualified # 🪣 E13.0 bucket
|
||||
1F9FC ; fully-qualified # 🧼 E11.0 soap
|
||||
1FAE7 ; fully-qualified # 🫧 E14.0 bubbles
|
||||
1FAA5 ; fully-qualified # 🪥 E13.0 toothbrush
|
||||
1F9FD ; fully-qualified # 🧽 E11.0 sponge
|
||||
1F9EF ; fully-qualified # 🧯 E11.0 fire extinguisher
|
||||
|
|
@ -4246,9 +4356,10 @@
|
|||
26B1 ; unqualified # ⚱ E1.0 funeral urn
|
||||
1F5FF ; fully-qualified # 🗿 E0.6 moai
|
||||
1FAA7 ; fully-qualified # 🪧 E13.0 placard
|
||||
1FAAA ; fully-qualified # 🪪 E14.0 identification card
|
||||
|
||||
# Objects subtotal: 299
|
||||
# Objects subtotal: 299 w/o modifiers
|
||||
# Objects subtotal: 304
|
||||
# Objects subtotal: 304 w/o modifiers
|
||||
|
||||
# group: Symbols
|
||||
|
||||
|
|
@ -4409,6 +4520,7 @@
|
|||
2795 ; fully-qualified # ➕ E0.6 plus
|
||||
2796 ; fully-qualified # ➖ E0.6 minus
|
||||
2797 ; fully-qualified # ➗ E0.6 divide
|
||||
1F7F0 ; fully-qualified # 🟰 E14.0 heavy equals sign
|
||||
267E FE0F ; fully-qualified # ♾️ E11.0 infinity
|
||||
267E ; unqualified # ♾ E11.0 infinity
|
||||
|
||||
|
|
@ -4581,8 +4693,8 @@
|
|||
1F533 ; fully-qualified # 🔳 E0.6 white square button
|
||||
1F532 ; fully-qualified # 🔲 E0.6 black square button
|
||||
|
||||
# Symbols subtotal: 301
|
||||
# Symbols subtotal: 301 w/o modifiers
|
||||
# Symbols subtotal: 302
|
||||
# Symbols subtotal: 302 w/o modifiers
|
||||
|
||||
# group: Flags
|
||||
|
||||
|
|
@ -4871,7 +4983,7 @@
|
|||
# Flags subtotal: 275 w/o modifiers
|
||||
|
||||
# Status Counts
|
||||
# fully-qualified : 3512
|
||||
# fully-qualified : 3624
|
||||
# minimally-qualified : 817
|
||||
# unqualified : 252
|
||||
# component : 9
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# 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
|
||||
|
|
@ -137,4 +138,17 @@ defmodule Pleroma.Emoji do
|
|||
end
|
||||
|
||||
def is_unicode_emoji?(_), do: false
|
||||
|
||||
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
|
||||
end
|
||||
|
|
|
|||
45
lib/pleroma/emoji/combinations.ex
Normal file
45
lib/pleroma/emoji/combinations.ex
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emoji.Combinations do
|
||||
# FE0F is the emoji variation sequence. It is used for fully-qualifying
|
||||
# emoji, and that includes emoji combinations.
|
||||
# This code generates combinations per emoji: for each FE0F, all possible
|
||||
# combinations of the character being removed or staying will be generated.
|
||||
# This is made as an attempt to find all partially-qualified and unqualified
|
||||
# versions of a fully-qualified emoji.
|
||||
# I have found *no cases* for which this would be a problem, after browsing
|
||||
# the entire emoji list in emoji-test.txt. This is safe, and, sadly, most
|
||||
# likely sane too.
|
||||
|
||||
defp qualification_combinations(codepoints) do
|
||||
qualification_combinations([[]], codepoints)
|
||||
end
|
||||
|
||||
defp qualification_combinations(acc, []), do: acc
|
||||
|
||||
defp qualification_combinations(acc, ["\uFE0F" | tail]) do
|
||||
acc
|
||||
|> Enum.flat_map(fn x -> [x, x ++ ["\uFE0F"]] end)
|
||||
|> qualification_combinations(tail)
|
||||
end
|
||||
|
||||
defp qualification_combinations(acc, [codepoint | tail]) do
|
||||
acc
|
||||
|> Enum.map(&Kernel.++(&1, [codepoint]))
|
||||
|> qualification_combinations(tail)
|
||||
end
|
||||
|
||||
def variate_emoji_qualification(emoji) when is_binary(emoji) do
|
||||
emoji
|
||||
|> String.codepoints()
|
||||
|> qualification_combinations()
|
||||
|> Enum.map(&List.to_string/1)
|
||||
end
|
||||
|
||||
def variate_emoji_qualification(emoji) when is_list(emoji) do
|
||||
emoji
|
||||
|> Enum.map(fn emoji -> {emoji, variate_emoji_qualification(emoji)} end)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emoji.Formatter do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emoji.Loader do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emoji.Pack do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Filter do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.FollowingRelationship do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Formatter do
|
||||
|
|
@ -34,32 +34,34 @@ defmodule Pleroma.Formatter do
|
|||
|
||||
def mention_handler("@" <> nickname, buffer, opts, acc) do
|
||||
case User.get_cached_by_nickname(nickname) do
|
||||
%User{id: id} = user ->
|
||||
user_url = user.uri || user.ap_id
|
||||
nickname_text = get_nickname_text(nickname, opts)
|
||||
|
||||
link =
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:span,
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:a,
|
||||
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
||||
"data-user": id,
|
||||
class: "u-url mention",
|
||||
href: user_url,
|
||||
rel: "ugc"
|
||||
),
|
||||
class: "h-card"
|
||||
)
|
||||
|> Phoenix.HTML.safe_to_string()
|
||||
|
||||
{link, %{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
|
||||
%User{} = user ->
|
||||
{mention_from_user(user, opts),
|
||||
%{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
|
||||
|
||||
_ ->
|
||||
{buffer, acc}
|
||||
end
|
||||
end
|
||||
|
||||
def mention_from_user(%User{id: id} = user, opts \\ %{mentions_format: :full}) do
|
||||
user_url = user.uri || user.ap_id
|
||||
nickname_text = get_nickname_text(user.nickname, opts)
|
||||
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:span,
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:a,
|
||||
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
||||
"data-user": id,
|
||||
class: "u-url mention",
|
||||
href: user_url,
|
||||
rel: "ugc"
|
||||
),
|
||||
class: "h-card"
|
||||
)
|
||||
|> Phoenix.HTML.safe_to_string()
|
||||
end
|
||||
|
||||
def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do
|
||||
tag = String.downcase(tag)
|
||||
url = "#{Pleroma.Web.Endpoint.url()}/tag/#{tag}"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Frontend do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gopher.Server do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun.API do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun.Conn do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun.ConnectionPool do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun.ConnectionPool.Reclaimer do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun.ConnectionPool.Worker do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun.ConnectionPool.WorkerSupervisor do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Hashtag do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Healthcheck do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Helpers.AuthHelper do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Helpers.InetHelper do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Helpers.MediaHelper do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Helpers.QtFastStart do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Helpers.UriHelper do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTML do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelper do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelper.Default do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelper.Gun do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelper.Hackney do
|
||||
|
|
@ -24,10 +24,6 @@ defmodule Pleroma.HTTP.AdapterHelper.Hackney do
|
|||
|> Pleroma.HTTP.AdapterHelper.maybe_add_proxy(proxy)
|
||||
end
|
||||
|
||||
defp add_scheme_opts(opts, %URI{scheme: "https"}) do
|
||||
Keyword.put(opts, :ssl_options, versions: [:"tlsv1.2", :"tlsv1.1", :tlsv1])
|
||||
end
|
||||
|
||||
defp add_scheme_opts(opts, _), do: opts
|
||||
|
||||
defp maybe_add_with_body(opts) do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.ExAws do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.Request do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.RequestBuilder do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.Tzdata do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.WebPush do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Instances do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Instances.Instance do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.JobQueueMonitor do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.JWT do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Keys do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.List do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Logging do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Maintenance do
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue