defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Activity
+ alias Pleroma.Activity.Ir.Topics
alias Pleroma.Config
alias Pleroma.Conversation
alias Pleroma.Notification
alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF
alias Pleroma.Web.ActivityPub.Transmogrifier
+ alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.Streamer
alias Pleroma.Web.WebFinger
import Ecto.Query
{recipients, to, cc}
end
- defp check_actor_is_active(true, _), do: :ok
-
- defp check_actor_is_active(false, actor) do
+ defp check_actor_is_active(actor) do
if not is_nil(actor) do
with user <- User.get_cached_by_ap_id(actor),
false <- user.info.deactivated do
- :ok
+ true
else
- _e -> :reject
+ _e -> false
end
else
- :ok
+ true
end
end
def insert(map, local \\ true, fake \\ false, bypass_actor_check \\ false) when is_map(map) do
with nil <- Activity.normalize(map),
map <- lazy_put_activity_defaults(map, fake),
- :ok <- check_actor_is_active(bypass_actor_check, map["actor"]),
+ true <- bypass_actor_check || check_actor_is_active(map["actor"]),
{_, true} <- {:remote_limit_error, check_remote_limit(map)},
{:ok, map} <- MRF.filter(map),
{recipients, _, _} = get_recipients(map),
# Splice in the child object if we have one.
activity =
- if !is_nil(object) do
+ if not is_nil(object) do
Map.put(activity, :object, object)
else
activity
participations
|> Repo.preload(:user)
- Enum.each(participations, fn participation ->
- Pleroma.Web.Streamer.stream("participation", participation)
- end)
+ Streamer.stream("participation", participations)
end
def stream_out_participations(%Object{data: %{"context" => context}}, user) do
def stream_out_participations(_, _), do: :noop
- def stream_out(activity) do
- if activity.data["type"] in ["Create", "Announce", "Delete"] do
- object = Object.normalize(activity)
- # Do not stream out poll replies
- unless object.data["type"] == "Answer" do
- Pleroma.Web.Streamer.stream("user", activity)
- Pleroma.Web.Streamer.stream("list", activity)
-
- if get_visibility(activity) == "public" do
- Pleroma.Web.Streamer.stream("public", activity)
-
- if activity.local do
- Pleroma.Web.Streamer.stream("public:local", activity)
- end
-
- if activity.data["type"] in ["Create"] do
- object.data
- |> Map.get("tag", [])
- |> Enum.filter(fn tag -> is_bitstring(tag) end)
- |> Enum.each(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end)
-
- if object.data["attachment"] != [] do
- Pleroma.Web.Streamer.stream("public:media", activity)
-
- if activity.local do
- Pleroma.Web.Streamer.stream("public:local:media", activity)
- end
- end
- end
- else
- if get_visibility(activity) == "direct",
- do: Pleroma.Web.Streamer.stream("direct", activity)
- end
- end
- end
+ def stream_out(%Activity{data: %{"type" => data_type}} = activity)
+ when data_type in ["Create", "Announce", "Delete"] do
+ activity
+ |> Topics.get_activity_topics()
+ |> Streamer.stream(activity)
+ end
+
+ def stream_out(_activity) do
+ :noop
end
def create(%{to: to, actor: actor, context: context, object: object} = params, fake \\ false) do
end
def update(%{to: to, cc: cc, actor: actor, object: object} = params) do
- # only accept false as false value
local = !(params[:local] == false)
+ activity_id = params[:activity_id]
with data <- %{
"to" => to,
"actor" => actor,
"object" => object
},
+ data <- Utils.maybe_put(data, "id", activity_id),
{:ok, activity} <- insert(data, local),
:ok <- maybe_federate(activity) do
{:ok, activity}
end
end
- def unlike(
- %User{} = actor,
- %Object{} = object,
- activity_id \\ nil,
- local \\ true
- ) do
+ def unlike(%User{} = actor, %Object{} = object, activity_id \\ nil, local \\ true) do
with %Activity{} = like_activity <- get_existing_like(actor.ap_id, object),
unlike_data <- make_unlike_data(actor, like_activity, activity_id),
{:ok, unlike_activity} <- insert(unlike_data, local),
def follow(follower, followed, activity_id \\ nil, local \\ true) do
with data <- make_follow_data(follower, followed, activity_id),
{:ok, activity} <- insert(data, local),
- :ok <- maybe_federate(activity) do
+ :ok <- maybe_federate(activity),
+ _ <- User.set_follow_state_cache(follower.ap_id, followed.ap_id, activity.data["state"]) do
{:ok, activity}
end
end
from(activity in Activity)
|> maybe_preload_objects(opts)
+ |> maybe_preload_bookmarks(opts)
+ |> maybe_set_thread_muted_field(opts)
|> restrict_blocked(opts)
|> restrict_recipients(recipients, opts["user"])
|> where(
)
)
|> exclude_poll_votes(opts)
+ |> exclude_id(opts)
|> order_by([activity], desc: activity.id)
end
end
@spec fetch_latest_activity_id_for_context(String.t(), keyword() | map()) ::
- Pleroma.FlakeId.t() | nil
+ FlakeId.Ecto.CompatType.t() | nil
def fetch_latest_activity_id_for_context(context, opts \\ %{}) do
context
|> fetch_activities_for_context_query(Map.merge(%{"skip_preload" => true}, opts))
params =
params
|> Map.put("type", ["Create", "Announce"])
+ |> Map.put("user", reading_user)
|> Map.put("actor_id", user.ap_id)
|> Map.put("whole_db", true)
|> Map.put("pinned_activity_ids", user.info.pinned_activities)
defp restrict_muted(query, %{"with_muted" => val}) when val in [true, "true", "1"], do: query
- defp restrict_muted(query, %{"muting_user" => %User{info: info}}) do
+ defp restrict_muted(query, %{"muting_user" => %User{info: info}} = opts) do
mutes = info.mutes
- from(
- activity in query,
- where: fragment("not (? = ANY(?))", activity.actor, ^mutes),
- where: fragment("not (?->'to' \\?| ?)", activity.data, ^mutes)
- )
+ query =
+ from([activity] in query,
+ where: fragment("not (? = ANY(?))", activity.actor, ^mutes),
+ where: fragment("not (?->'to' \\?| ?)", activity.data, ^mutes)
+ )
+
+ unless opts["skip_preload"] do
+ from([thread_mute: tm] in query, where: is_nil(tm.user_id))
+ else
+ query
+ end
end
defp restrict_muted(query, _), do: query
defp restrict_muted_reblogs(query, _), do: query
- defp exclude_poll_votes(query, %{"include_poll_votes" => "true"}), do: query
+ defp exclude_poll_votes(query, %{"include_poll_votes" => true}), do: query
defp exclude_poll_votes(query, _) do
if has_named_binding?(query, :object) do
end
end
+ defp exclude_id(query, %{"exclude_id" => id}) when is_binary(id) do
+ from(activity in query, where: activity.id != ^id)
+ end
+
+ defp exclude_id(query, _), do: query
+
defp maybe_preload_objects(query, %{"skip_preload" => true}), do: query
defp maybe_preload_objects(query, _) do
defp maybe_set_thread_muted_field(query, opts) do
query
- |> Activity.with_set_thread_muted_field(opts["user"])
+ |> Activity.with_set_thread_muted_field(opts["muting_user"] || opts["user"])
end
defp maybe_order(query, %{order: :desc}) do
"url" => [%{"href" => data["image"]["url"]}]
}
+ fields =
+ data
+ |> Map.get("attachment", [])
+ |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
+ |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
+
locked = data["manuallyApprovesFollowers"] || false
data = Transmogrifier.maybe_fix_user_object(data)
ap_enabled: true,
source_data: data,
banner: banner,
+ fields: fields,
locked: locked
},
avatar: avatar,