X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Futils.ex;h=2ca805c091ab25c9340e05782750844b1ff6d711;hb=6fbafb1cdcba3dc2a7e8b9718e295c9811a726d9;hp=91cfa21943fd876b503c5b7d7af0bcfd0718cf31;hpb=3c0abfca53751624ebd6ea7174ee880d9e7b29e7;p=akkoma diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 91cfa2194..2ca805c09 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do 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 @@ -706,26 +707,37 @@ defmodule Pleroma.Web.ActivityPub.Utils do def make_flag_data(_, _), do: %{} defp build_flag_object(%{account: account, statuses: statuses} = _) do - [account.ap_id] ++ - Enum.map(statuses || [], fn act -> - id = - case act do - %Activity{} = act -> act.data["id"] - act when is_map(act) -> act["id"] - act when is_binary(act) -> act - end + [account.ap_id] ++ build_flag_object(%{statuses: statuses}) + end - activity = Activity.get_by_ap_id_with_object(id) - actor = User.get_by_ap_id(activity.object.data["actor"]) + defp build_flag_object(%{statuses: statuses}) do + Enum.map(statuses || [], &build_flag_object/1) + end + defp build_flag_object(act) when is_map(act) or is_binary(act) do + id = + case act do + %Activity{} = act -> act.data["id"] + act when is_map(act) -> act["id"] + act when is_binary(act) -> act + end + + case Activity.get_by_ap_id_with_object(id) do + %Activity{} = activity -> %{ "type" => "Note", "id" => activity.data["id"], "content" => activity.object.data["content"], "published" => activity.object.data["published"], - "actor" => AccountView.render("show.json", %{user: actor}) + "actor" => + AccountView.render("show.json", %{ + user: User.get_by_ap_id(activity.object.data["actor"]) + }) } - end) + + _ -> + %{"id" => id, "deleted" => true} + end end defp build_flag_object(_), do: [] @@ -770,6 +782,113 @@ defmodule Pleroma.Web.ActivityPub.Utils do 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 + + def parse_report_group(activity) do + reports = get_reports_by_status_id(activity["id"]) + max_date = Enum.max_by(reports, &NaiveDateTime.from_iso8601!(&1.data["published"])) + actors = Enum.map(reports, & &1.user_actor) + [%{data: %{"object" => [account_id | _]}} | _] = reports + + account = + AccountView.render("show.json", %{ + user: User.get_by_ap_id(account_id) + }) + + status = get_status_data(activity) + + %{ + date: max_date.data["published"], + account: account, + status: status, + actors: Enum.uniq(actors), + reports: reports + } + end + + defp get_status_data(status) do + case status["deleted"] do + true -> + %{ + "id" => status["id"], + "deleted" => true + } + + _ -> + Activity.get_by_ap_id(status["id"]) + end + end + + def get_reports_by_status_id(ap_id) do + from(a in Activity, + where: fragment("(?)->>'type' = 'Flag'", a.data), + where: fragment("(?)->'object' @> ?", a.data, ^[%{id: ap_id}]), + or_where: fragment("(?)->'object' @> ?", a.data, ^[ap_id]) + ) + |> Activity.with_preloaded_user_actor() + |> Repo.all() + end + + @spec get_reports_grouped_by_status([String.t()]) :: %{ + required(:groups) => [ + %{ + required(:date) => String.t(), + required(:account) => %{}, + required(:status) => %{}, + required(:actors) => [%User{}], + required(:reports) => [%Activity{}] + } + ] + } + def get_reports_grouped_by_status(activity_ids) do + parsed_groups = + activity_ids + |> Enum.map(fn id -> + id + |> build_flag_object() + |> parse_report_group() + end) + + %{ + groups: parsed_groups + } + end + + @spec get_reported_activities() :: [ + %{ + required(:activity) => String.t(), + required(:date) => String.t() + } + ] + def get_reported_activities do + reported_activities_query = + from(a in Activity, + where: fragment("(?)->>'type' = 'Flag'", a.data), + select: %{ + activity: fragment("jsonb_array_elements((? #- '{object,0}')->'object')", a.data) + }, + group_by: fragment("activity") + ) + + from(a in subquery(reported_activities_query), + distinct: true, + select: %{ + id: fragment("COALESCE(?->>'id'::text, ? #>> '{}')", a.activity, a.activity) + } + ) + |> Repo.all() + |> Enum.map(& &1.id) + end def update_report_state(%Activity{} = activity, state) when state in @strip_status_report_states do @@ -793,11 +912,29 @@ defmodule Pleroma.Web.ActivityPub.Utils 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 [actor | reported_activities] = activity.data["object"] - stripped_activities = Enum.map(reported_activities, & &1["id"]) + + stripped_activities = + Enum.map(reported_activities, fn + act when is_map(act) -> act["id"] + act when is_binary(act) -> act + end) + new_data = put_in(activity.data, ["object"], [actor | stripped_activities]) {:ok, %{activity | data: new_data}}