X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Factivity.ex;h=46552c7be67a25465dbdaab02a1f46013ce3b166;hb=bbd9ed02576f1599e90f8575573fe6e935d32eae;hp=99cc9c077cb131472711e3e26a98ad880e0709ee;hpb=627e5a0a4992cc19fc65a7e93a09c470c8e2bf33;p=akkoma diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 99cc9c077..46552c7be 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -6,14 +6,19 @@ defmodule Pleroma.Activity do use Ecto.Schema alias Pleroma.Activity + alias Pleroma.Bookmark alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo + alias Pleroma.ThreadMute + alias Pleroma.User import Ecto.Changeset import Ecto.Query @type t :: %__MODULE__{} + @type actor :: String.t() + @primary_key {:id, Pleroma.FlakeId, autogenerate: true} # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 @@ -33,6 +38,9 @@ defmodule Pleroma.Activity do field(:local, :boolean, default: true) field(:actor, :string) field(:recipients, {:array, :string}, default: []) + field(:thread_muted?, :boolean, virtual: true) + # This is a fake relation, do not use outside of with_preloaded_bookmark/get_bookmark + has_one(:bookmark, Bookmark) has_many(:notifications, Notification, on_delete: :delete_all) # Attention: this is a fake relation, don't try to preload it blindly and expect it to work! @@ -54,23 +62,46 @@ defmodule Pleroma.Activity do timestamps() end - def with_preloaded_object(query) do - query - |> join( - :inner, - [activity], - o in Object, + def with_joined_object(query) do + join(query, :inner, [activity], o in Object, on: fragment( "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')", o.data, activity.data, activity.data - ) + ), + as: :object + ) + end + + def with_preloaded_object(query) do + query + |> has_named_binding?(:object) + |> if(do: query, else: with_joined_object(query)) + |> preload([activity, object: object], object: object) + end + + def with_preloaded_bookmark(query, %User{} = user) do + from([a] in query, + left_join: b in Bookmark, + on: b.user_id == ^user.id and b.activity_id == a.id, + preload: [bookmark: b] + ) + end + + def with_preloaded_bookmark(query, _), do: query + + def with_set_thread_muted_field(query, %User{} = user) do + from([a] in query, + left_join: tm in ThreadMute, + on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data), + select: %Activity{a | thread_muted?: not is_nil(tm.id)} ) - |> preload([activity, object], object: object) end + def with_set_thread_muted_field(query, _), do: query + def get_by_ap_id(ap_id) do Repo.one( from( @@ -80,9 +111,19 @@ defmodule Pleroma.Activity do ) end + def get_bookmark(%Activity{} = activity, %User{} = user) do + if Ecto.assoc_loaded?(activity.bookmark) do + activity.bookmark + else + Bookmark.get(user.id, activity.id) + end + end + + def get_bookmark(_, _), do: nil + def change(struct, params \\ %{}) do struct - |> cast(params, [:data]) + |> cast(params, [:data, :recipients]) |> validate_required([:data]) |> unique_constraint(:ap_id, name: :activities_unique_apid_index) end @@ -106,7 +147,10 @@ defmodule Pleroma.Activity do end def get_by_id(id) do - Repo.get(Activity, id) + Activity + |> where([a], a.id == ^id) + |> restrict_deactivated_users() + |> Repo.one() end def get_by_id_with_object(id) do @@ -174,6 +218,7 @@ defmodule Pleroma.Activity do def get_create_by_object_ap_id(ap_id) when is_binary(ap_id) do create_by_object_ap_id(ap_id) + |> restrict_deactivated_users() |> Repo.one() end @@ -204,12 +249,14 @@ defmodule Pleroma.Activity do def create_by_object_ap_id_with_object(_), do: nil - def get_create_by_object_ap_id_with_object(ap_id) do + def get_create_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do ap_id |> create_by_object_ap_id_with_object() |> Repo.one() end + def get_create_by_object_ap_id_with_object(_), do: nil + defp get_in_reply_to_activity_from_object(%Object{data: %{"inReplyTo" => ap_id}}) do get_create_by_object_ap_id_with_object(ap_id) end @@ -230,6 +277,7 @@ defmodule Pleroma.Activity do |> Repo.delete_all() |> elem(1) |> Enum.find(fn + %{data: %{"type" => "Create", "object" => ap_id}} when is_binary(ap_id) -> ap_id == id %{data: %{"type" => "Create", "object" => %{"id" => ap_id}}} -> ap_id == id _ -> nil end) @@ -258,53 +306,43 @@ defmodule Pleroma.Activity do |> Repo.all() end - def increase_replies_count(nil), do: nil - - def increase_replies_count(object_ap_id) do - from(a in create_by_object_ap_id(object_ap_id), - update: [ - set: [ - data: - fragment( - """ - jsonb_set(?, '{object, repliesCount}', - (coalesce((?->'object'->>'repliesCount')::int, 0) + 1)::varchar::jsonb, true) - """, - a.data, - a.data - ) - ] - ] + def follow_requests_for_actor(%Pleroma.User{ap_id: ap_id}) do + from( + a in Activity, + where: + fragment( + "? ->> 'type' = 'Follow'", + a.data + ), + where: + fragment( + "? ->> 'state' = 'pending'", + a.data + ), + where: + fragment( + "coalesce((?)->'object'->>'id', (?)->>'object') = ?", + a.data, + a.data, + ^ap_id + ) ) - |> Repo.update_all([]) - |> case do - {1, [activity]} -> activity - _ -> {:error, "Not found"} - end end - def decrease_replies_count(nil), do: nil - - def decrease_replies_count(object_ap_id) do - from(a in create_by_object_ap_id(object_ap_id), - update: [ - set: [ - data: - fragment( - """ - jsonb_set(?, '{object, repliesCount}', - (greatest(0, (?->'object'->>'repliesCount')::int - 1))::varchar::jsonb, true) - """, - a.data, - a.data - ) - ] - ] + @spec query_by_actor(actor()) :: Ecto.Query.t() + def query_by_actor(actor) do + from(a in Activity, where: a.actor == ^actor) + end + + def restrict_deactivated_users(query) do + from(activity in query, + where: + fragment( + "? not in (SELECT ap_id FROM users WHERE info->'deactivated' @> 'true')", + activity.actor + ) ) - |> Repo.update_all([]) - |> case do - {1, [activity]} -> activity - _ -> {:error, "Not found"} - end end + + defdelegate search(user, query, options \\ []), to: Pleroma.Activity.Search end