alias Ecto.Changeset
alias Ecto.UUID
alias Pleroma.Activity
+ alias Pleroma.Activity.Queries
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web
+ alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.Endpoint
def determine_explicit_mentions(_), do: []
- @spec recipient_in_collection(any(), any()) :: boolean()
- defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll
- defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll
- defp recipient_in_collection(_, _), do: false
+ @spec label_in_collection?(any(), any()) :: boolean()
+ defp label_in_collection?(ap_id, coll) when is_binary(coll), do: ap_id == coll
+ defp label_in_collection?(ap_id, coll) when is_list(coll), do: ap_id in coll
+ defp label_in_collection?(_, _), do: false
+
+ @spec label_in_message?(String.t(), map()) :: boolean()
+ def label_in_message?(label, params),
+ do:
+ [params["to"], params["cc"], params["bto"], params["bcc"]]
+ |> Enum.any?(&label_in_collection?(label, &1))
+
+ @spec unaddressed_message?(map()) :: boolean()
+ def unaddressed_message?(params),
+ do:
+ [params["to"], params["cc"], params["bto"], params["bcc"]]
+ |> Enum.all?(&is_nil(&1))
@spec recipient_in_message(User.t(), User.t(), map()) :: boolean()
- def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params) do
- addresses = [params["to"], params["cc"], params["bto"], params["bcc"]]
-
- cond do
- Enum.any?(addresses, &recipient_in_collection(ap_id, &1)) -> true
- # if the message is unaddressed at all, then assume it is directly addressed
- # to the recipient
- Enum.all?(addresses, &is_nil(&1)) -> true
- # if the message is sent from somebody the user is following, then assume it
- # is addressed to the recipient
- User.following?(recipient, actor) -> true
- true -> false
- end
- end
+ def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params),
+ do:
+ label_in_message?(ap_id, params) || unaddressed_message?(params) ||
+ User.following?(recipient, actor)
defp extract_list(target) when is_binary(target), do: [target]
defp extract_list(lst) when is_list(lst), do: lst
def maybe_splice_recipient(ap_id, params) do
need_splice? =
- !recipient_in_collection(ap_id, params["to"]) &&
- !recipient_in_collection(ap_id, params["cc"])
+ !label_in_collection?(ap_id, params["to"]) &&
+ !label_in_collection?(ap_id, params["cc"])
if need_splice? do
cc_list = extract_list(params["cc"])
%Activity{data: %{"actor" => actor}},
object
) do
- announcements = take_announcements(object)
+ unless actor |> User.get_cached_by_ap_id() |> User.invisible?() do
+ announcements = take_announcements(object)
- with announcements <- Enum.uniq([actor | announcements]) do
- update_element_in_object("announcement", announcements, object)
+ with announcements <- Enum.uniq([actor | announcements]) do
+ update_element_in_object("announcement", announcements, object)
+ end
+ else
+ {:ok, object}
end
end
end
#### Report-related helpers
+ def get_reports(params, page, page_size) do
+ params =
+ params
+ |> Map.put("type", "Flag")
+ |> Map.put("skip_preload", true)
+ |> Map.put("total", true)
+ |> Map.put("limit", page_size)
+ |> Map.put("offset", (page - 1) * page_size)
+
+ ActivityPub.fetch_activities([], params, :offset)
+ end
+
+ @spec get_reports_grouped_by_status() :: %{
+ required(:groups) => [
+ %{
+ required(:date) => String.t(),
+ required(:account) => %User{},
+ required(:status) => %Activity{},
+ required(:actors) => [%User{}],
+ required(:reports) => [%Activity{}]
+ }
+ ],
+ required(:total) => integer
+ }
+ def get_reports_grouped_by_status do
+ paginated_activities = get_reported_status_ids()
+
+ groups =
+ paginated_activities
+ |> Enum.map(fn entry ->
+ status =
+ Activity
+ |> Queries.by_ap_id(entry[:activity_id])
+ |> Activity.with_preloaded_object(:left)
+ |> Activity.with_preloaded_user_actor()
+ |> Repo.one()
+
+ reports = get_reports_by_status_id(status.data["id"])
+
+ max_date =
+ Enum.max_by(reports, &Pleroma.Web.CommonAPI.Utils.to_masto_date(&1.data["published"])).data[
+ "published"
+ ]
+
+ actors = Enum.map(reports, & &1.user_actor)
+
+ %{
+ date: max_date,
+ account: status.user_actor,
+ status: status,
+ actors: actors,
+ reports: reports
+ }
+ end)
+
+ %{
+ groups: groups
+ }
+ end
+
+ def get_reports_by_status_id(status_id) do
+ from(a in Activity,
+ where: fragment("(?)->>'type' = 'Flag'", a.data),
+ where: fragment("(?)->'object' \\? (?)", a.data, ^status_id)
+ )
+ |> Activity.with_preloaded_user_actor()
+ |> Repo.all()
+ end
+
+ @spec get_reported_status_ids() :: %{
+ required(:items) => [%Activity{}],
+ required(:total) => integer
+ }
+ def get_reported_status_ids do
+ from(a in Activity,
+ where: fragment("(?)->>'type' = 'Flag'", a.data),
+ select: %{
+ date: fragment("max(?->>'published') date", a.data),
+ activity_id:
+ fragment("jsonb_array_elements_text((? #- '{object,0}')->'object') activity_id", a.data)
+ },
+ group_by: fragment("activity_id"),
+ order_by: fragment("date DESC")
+ )
+ |> Repo.all()
+ end
def update_report_state(%Activity{} = activity, state)
when state in @strip_status_report_states do
|> Repo.update()
end
+ def update_report_state(activity_ids, state) when state in @supported_report_states do
+ activities_num = length(activity_ids)
+
+ from(a in Activity, where: a.id in ^activity_ids)
+ |> update(set: [data: fragment("jsonb_set(data, '{state}', ?)", ^state)])
+ |> Repo.update_all([])
+ |> case do
+ {^activities_num, _} -> :ok
+ _ -> {:error, activity_ids}
+ end
+ end
+
def update_report_state(_, _), do: {:error, "Unsupported state"}
def strip_report_status_data(activity) do