Commit 4c5125de authored by rinpatch's avatar rinpatch Committed by kaniini

Remove `bookmarks` assoc and add a fake `bookmark` assoc instead

parent be067ec2
...@@ -10,6 +10,7 @@ defmodule Pleroma.Activity do ...@@ -10,6 +10,7 @@ defmodule Pleroma.Activity do
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query import Ecto.Query
...@@ -36,8 +37,9 @@ defmodule Pleroma.Activity do ...@@ -36,8 +37,9 @@ defmodule Pleroma.Activity do
field(:local, :boolean, default: true) field(:local, :boolean, default: true)
field(:actor, :string) field(:actor, :string)
field(:recipients, {:array, :string}, default: []) field(:recipients, {:array, :string}, default: [])
# 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) has_many(:notifications, Notification, on_delete: :delete_all)
has_many(:bookmarks, Bookmark, on_delete: :delete_all)
# Attention: this is a fake relation, don't try to preload it blindly and expect it to work! # Attention: this is a fake relation, don't try to preload it blindly and expect it to work!
# The foreign key is embedded in a jsonb field. # The foreign key is embedded in a jsonb field.
...@@ -73,14 +75,18 @@ defmodule Pleroma.Activity do ...@@ -73,14 +75,18 @@ defmodule Pleroma.Activity do
) )
) )
|> preload([activity, object], object: object) |> preload([activity, object], object: object)
|> with_preloaded_bookmarks()
end end
def with_preloaded_bookmarks(query) do def with_preloaded_bookmark(query, %User{} = user) do
query from([a] in query,
|> preload(:bookmarks) left_join: b in Bookmark,
on: b.user_id == ^user.id and b.activity_id == a.id,
preload: [bookmark: b]
)
end end
def with_preloaded_bookmark(query, _), do: query
def get_by_ap_id(ap_id) do def get_by_ap_id(ap_id) do
Repo.one( Repo.one(
from( from(
...@@ -90,6 +96,16 @@ defmodule Pleroma.Activity do ...@@ -90,6 +96,16 @@ defmodule Pleroma.Activity do
) )
end 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 def change(struct, params \\ %{}) do
struct struct
|> cast(params, [:data]) |> cast(params, [:data])
...@@ -112,7 +128,6 @@ defmodule Pleroma.Activity do ...@@ -112,7 +128,6 @@ defmodule Pleroma.Activity do
), ),
preload: [object: o] preload: [object: o]
) )
|> with_preloaded_bookmarks()
) )
end end
...@@ -133,7 +148,6 @@ defmodule Pleroma.Activity do ...@@ -133,7 +148,6 @@ defmodule Pleroma.Activity do
), ),
preload: [object: o] preload: [object: o]
) )
|> with_preloaded_bookmarks()
|> Repo.one() |> Repo.one()
end end
...@@ -212,7 +226,6 @@ defmodule Pleroma.Activity do ...@@ -212,7 +226,6 @@ defmodule Pleroma.Activity do
), ),
preload: [object: o] preload: [object: o]
) )
|> with_preloaded_bookmarks()
end end
def create_by_object_ap_id_with_object(_), do: nil def create_by_object_ap_id_with_object(_), do: nil
......
...@@ -38,8 +38,7 @@ defmodule Pleroma.Bookmark do ...@@ -38,8 +38,7 @@ defmodule Pleroma.Bookmark do
Bookmark Bookmark
|> where(user_id: ^user_id) |> where(user_id: ^user_id)
|> join(:inner, [b], activity in assoc(b, :activity)) |> join(:inner, [b], activity in assoc(b, :activity))
|> join(:inner, [_b, a], bookmarks in assoc(a, :bookmarks)) |> preload([b, a], activity: a)
|> preload([b, a, b2], activity: {a, bookmarks: b2})
end end
def get(user_id, activity_id) do def get(user_id, activity_id) do
......
...@@ -137,13 +137,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do ...@@ -137,13 +137,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
activity activity
end end
activity =
if activity.data["type"] in ["Create", "Announce"] do
Repo.preload(activity, :bookmarks)
else
activity
end
Task.start(fn -> Task.start(fn ->
Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
end) end)
...@@ -822,11 +815,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do ...@@ -822,11 +815,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> Activity.with_preloaded_object() |> Activity.with_preloaded_object()
end end
defp maybe_preload_bookmarks(query, %{"skip_preload" => true}), do: query
defp maybe_preload_bookmarks(query, opts) do
query
|> Activity.with_preloaded_bookmark(opts["user"])
end
def fetch_activities_query(recipients, opts \\ %{}) do def fetch_activities_query(recipients, opts \\ %{}) do
base_query = from(activity in Activity) base_query = from(activity in Activity)
base_query base_query
|> maybe_preload_objects(opts) |> maybe_preload_objects(opts)
|> maybe_preload_bookmarks(opts)
|> restrict_recipients(recipients, opts["user"]) |> restrict_recipients(recipients, opts["user"])
|> restrict_tag(opts) |> restrict_tag(opts)
|> restrict_tag_reject(opts) |> restrict_tag_reject(opts)
......
...@@ -563,9 +563,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do ...@@ -563,9 +563,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
with %Activity{} = activity <- Activity.get_by_id_with_object(id), with %Activity{} = activity <- Activity.get_by_id_with_object(id),
%User{} = user <- User.get_cached_by_nickname(user.nickname), %User{} = user <- User.get_cached_by_nickname(user.nickname),
true <- Visibility.visible_for_user?(activity, user), true <- Visibility.visible_for_user?(activity, user),
{:ok, bookmark} <- Bookmark.create(user.id, activity.id) do {:ok, _bookmark} <- Bookmark.create(user.id, activity.id) do
activity = %{activity | bookmarks: [bookmark | activity.bookmarks]}
conn conn
|> put_view(StatusView) |> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity}) |> try_render("status.json", %{activity: activity, for: user, as: :activity})
...@@ -577,11 +575,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do ...@@ -577,11 +575,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
%User{} = user <- User.get_cached_by_nickname(user.nickname), %User{} = user <- User.get_cached_by_nickname(user.nickname),
true <- Visibility.visible_for_user?(activity, user), true <- Visibility.visible_for_user?(activity, user),
{:ok, _bookmark} <- Bookmark.destroy(user.id, activity.id) do {:ok, _bookmark} <- Bookmark.destroy(user.id, activity.id) do
bookmarks =
Enum.filter(activity.bookmarks, fn %{user_id: user_id} -> user_id != user.id end)
activity = %{activity | bookmarks: bookmarks}
conn conn
|> put_view(StatusView) |> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity}) |> try_render("status.json", %{activity: activity, for: user, as: :activity})
...@@ -1154,7 +1147,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do ...@@ -1154,7 +1147,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
activities = activities =
bookmarks bookmarks
|> Enum.map(fn b -> b.activity end) |> Enum.map(fn b -> Map.put(b.activity, :bookmark, Map.delete(b, :activity)) end)
conn conn
|> add_link_headers(:bookmarks, bookmarks) |> add_link_headers(:bookmarks, bookmarks)
......
...@@ -75,26 +75,22 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do ...@@ -75,26 +75,22 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
def render( def render(
"status.json", "status.json",
%{activity: %{data: %{"type" => "Announce", "object" => object}} = activity} = opts %{activity: %{data: %{"type" => "Announce", "object" => _object}} = activity} = opts
) do ) do
user = get_user(activity.data["actor"]) user = get_user(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"]) created_at = Utils.to_masto_date(activity.data["published"])
activity_object = Object.normalize(activity)
reblogged_activity = reblogged_activity =
Activity.create_by_object_ap_id(object) Activity.create_by_object_ap_id(activity_object.data["id"])
|> Activity.with_preloaded_bookmarks() |> Activity.with_preloaded_bookmark(opts[:for])
|> Repo.one() |> Repo.one()
reblogged = render("status.json", Map.put(opts, :activity, reblogged_activity)) reblogged = render("status.json", Map.put(opts, :activity, reblogged_activity))
activity_object = Object.normalize(activity)
favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || []) favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || [])
bookmarked = bookmarked = Activity.get_bookmark(reblogged_activity, opts[:for]) != nil
opts[:for] && Ecto.assoc_loaded?(reblogged_activity.bookmarks) &&
Enum.any?(reblogged_activity.bookmarks, fn %{user_id: user_id} ->
user_id == opts[:for].id
end)
mentions = mentions =
activity.recipients activity.recipients
...@@ -104,8 +100,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do ...@@ -104,8 +100,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
%{ %{
id: to_string(activity.id), id: to_string(activity.id),
uri: object, uri: activity_object.data["id"],
url: object, url: activity_object.data["id"],
account: AccountView.render("account.json", %{user: user}), account: AccountView.render("account.json", %{user: user}),
in_reply_to_id: nil, in_reply_to_id: nil,
in_reply_to_account_id: nil, in_reply_to_account_id: nil,
...@@ -157,11 +153,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do ...@@ -157,11 +153,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
favorited = opts[:for] && opts[:for].ap_id in (object.data["likes"] || []) favorited = opts[:for] && opts[:for].ap_id in (object.data["likes"] || [])
bookmarked = bookmarked = Activity.get_bookmark(activity, opts[:for]) != nil
opts[:for] && Ecto.assoc_loaded?(activity.bookmarks) &&
Enum.any?(activity.bookmarks, fn %{user_id: user_id} ->
user_id == opts[:for].id
end)
attachment_data = object.data["attachment"] || [] attachment_data = object.data["attachment"] || []
attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment) attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment)
......
...@@ -6,7 +6,6 @@ defmodule Pleroma.ActivityTest do ...@@ -6,7 +6,6 @@ defmodule Pleroma.ActivityTest do
use Pleroma.DataCase use Pleroma.DataCase
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Bookmark alias Pleroma.Bookmark
alias Pleroma.Object
import Pleroma.Factory import Pleroma.Factory
test "returns an activity by it's AP id" do test "returns an activity by it's AP id" do
...@@ -31,52 +30,47 @@ defmodule Pleroma.ActivityTest do ...@@ -31,52 +30,47 @@ defmodule Pleroma.ActivityTest do
assert activity == found_activity assert activity == found_activity
end end
describe "preloading bookmarks" do test "preloading a bookmark" do
setup do user = insert(:user)
user1 = insert(:user) user2 = insert(:user)
user2 = insert(:user) user3 = insert(:user)
activity = insert(:note_activity) activity = insert(:note_activity)
{:ok, bookmark1} = Bookmark.create(user1.id, activity.id) {:ok, _bookmark} = Bookmark.create(user.id, activity.id)
{:ok, bookmark2} = Bookmark.create(user2.id, activity.id) {:ok, _bookmark2} = Bookmark.create(user2.id, activity.id)
[activity: activity, bookmarks: Enum.sort([bookmark1, bookmark2])] {:ok, bookmark3} = Bookmark.create(user3.id, activity.id)
end
test "using with_preloaded_bookmarks", %{activity: activity, bookmarks: bookmarks} do queried_activity =
queried_activity = Ecto.Query.from(Pleroma.Activity)
Ecto.Query.from(a in Activity, where: a.id == ^activity.id) |> Activity.with_preloaded_bookmark(user3)
|> Activity.with_preloaded_bookmarks() |> Repo.one()
|> Repo.one()
assert Enum.sort(queried_activity.bookmarks) == bookmarks assert queried_activity.bookmark == bookmark3
end end
describe "getting a bookmark" do
test "when association is loaded" do
user = insert(:user)
activity = insert(:note_activity)
{:ok, bookmark} = Bookmark.create(user.id, activity.id)
test "using with_preloaded_object", %{activity: activity, bookmarks: bookmarks} do
queried_activity = queried_activity =
Ecto.Query.from(a in Activity, where: a.id == ^activity.id) Ecto.Query.from(Pleroma.Activity)
|> Activity.with_preloaded_object() |> Activity.with_preloaded_bookmark(user)
|> Repo.one() |> Repo.one()
assert Enum.sort(queried_activity.bookmarks) == bookmarks assert Activity.get_bookmark(queried_activity, user) == bookmark
end
test "using get_by_ap_id_with_object", %{activity: activity, bookmarks: bookmarks} do
queried_activity = Activity.get_by_ap_id_with_object(activity.data["id"])
assert Enum.sort(queried_activity.bookmarks) == bookmarks
end end
test "using get_by_id_with_object", %{activity: activity, bookmarks: bookmarks} do test "when association is not loaded" do
queried_activity = Activity.get_by_id_with_object(activity.id) user = insert(:user)
assert Enum.sort(queried_activity.bookmarks) == bookmarks activity = insert(:note_activity)
end {:ok, bookmark} = Bookmark.create(user.id, activity.id)
test "using get_create_by_object_ap_id_with_object", %{
activity: activity,
bookmarks: bookmarks
} do
queried_activity = queried_activity =
Activity.get_create_by_object_ap_id_with_object(Object.normalize(activity).data["id"]) Ecto.Query.from(Pleroma.Activity)
|> Repo.one()
assert Enum.sort(queried_activity.bookmarks) == bookmarks assert Activity.get_bookmark(queried_activity, user) == bookmark
end end
end end
end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment