99 lines
2.9 KiB
Elixir
99 lines
2.9 KiB
Elixir
|
defmodule Mobilizon.Service.ActivityPub.Audience do
|
||
|
@moduledoc """
|
||
|
Tools for calculating content audience
|
||
|
"""
|
||
|
alias Mobilizon.Actors.Actor
|
||
|
|
||
|
@ap_public "https://www.w3.org/ns/activitystreams#Public"
|
||
|
|
||
|
@doc """
|
||
|
Determines the full audience based on mentions for a public audience
|
||
|
|
||
|
Audience is:
|
||
|
* `to` : the mentioned actors, the eventual actor we're replying to and the public
|
||
|
* `cc` : the actor's followers
|
||
|
"""
|
||
|
@spec get_to_and_cc(Actor.t(), list(), map(), String.t()) :: {list(), list()}
|
||
|
def get_to_and_cc(%Actor{} = actor, mentions, in_reply_to, :public) do
|
||
|
to = [@ap_public | mentions]
|
||
|
cc = [actor.followers_url]
|
||
|
|
||
|
if in_reply_to do
|
||
|
{Enum.uniq([in_reply_to.actor | to]), cc}
|
||
|
else
|
||
|
{to, cc}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
@doc """
|
||
|
Determines the full audience based on mentions based on a unlisted audience
|
||
|
|
||
|
Audience is:
|
||
|
* `to` : the mentionned actors, actor's followers and the eventual actor we're replying to
|
||
|
* `cc` : public
|
||
|
"""
|
||
|
@spec get_to_and_cc(Actor.t(), list(), map(), String.t()) :: {list(), list()}
|
||
|
def get_to_and_cc(%Actor{} = actor, mentions, in_reply_to, :unlisted) do
|
||
|
to = [actor.followers_url | mentions]
|
||
|
cc = [@ap_public]
|
||
|
|
||
|
if in_reply_to do
|
||
|
{Enum.uniq([in_reply_to.actor | to]), cc}
|
||
|
else
|
||
|
{to, cc}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
@doc """
|
||
|
Determines the full audience based on mentions based on a private audience
|
||
|
|
||
|
Audience is:
|
||
|
* `to` : the mentioned actors, actor's followers and the eventual actor we're replying to
|
||
|
* `cc` : none
|
||
|
"""
|
||
|
@spec get_to_and_cc(Actor.t(), list(), map(), String.t()) :: {list(), list()}
|
||
|
def get_to_and_cc(%Actor{} = actor, mentions, in_reply_to, :private) do
|
||
|
{to, cc} = get_to_and_cc(actor, mentions, in_reply_to, :direct)
|
||
|
{[actor.followers_url | to], cc}
|
||
|
end
|
||
|
|
||
|
@doc """
|
||
|
Determines the full audience based on mentions based on a direct audience
|
||
|
|
||
|
Audience is:
|
||
|
* `to` : the mentioned actors and the eventual actor we're replying to
|
||
|
* `cc` : none
|
||
|
"""
|
||
|
@spec get_to_and_cc(Actor.t(), list(), map(), String.t()) :: {list(), list()}
|
||
|
def get_to_and_cc(_actor, mentions, in_reply_to, :direct) do
|
||
|
if in_reply_to do
|
||
|
{Enum.uniq([in_reply_to.actor | mentions]), []}
|
||
|
else
|
||
|
{mentions, []}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def get_to_and_cc(_actor, mentions, _in_reply_to, {:list, _}) do
|
||
|
{mentions, []}
|
||
|
end
|
||
|
|
||
|
# def get_addressed_actors(_, to) when is_list(to) do
|
||
|
# Actors.get(to)
|
||
|
# end
|
||
|
|
||
|
def get_addressed_actors(mentioned_users, _), do: mentioned_users
|
||
|
|
||
|
def calculate_to_and_cc_from_mentions(
|
||
|
actor,
|
||
|
mentions \\ [],
|
||
|
in_reply_to \\ nil,
|
||
|
visibility \\ :public
|
||
|
) do
|
||
|
with mentioned_actors <- for({_, mentioned_actor} <- mentions, do: mentioned_actor.url),
|
||
|
addressed_actors <- get_addressed_actors(mentioned_actors, nil),
|
||
|
{to, cc} <- get_to_and_cc(actor, addressed_actors, in_reply_to, visibility) do
|
||
|
%{"to" => to, "cc" => cc}
|
||
|
end
|
||
|
end
|
||
|
end
|