Object: remove context_id field
30 to 70% of the objects in the object table are simple JSON objects containing a single field, 'id', being the context's ID. The reason for the creation of an object per context seems to be an old relic from the StatusNet era, and has only been used nowadays as an helper for threads in Pleroma-FE via the `pleroma.conversation_id` field in status views. An object per context was created, and its numerical ID (table column) was used and stored as 'context_id' in the object and activity along with the full 'context' URI/string. This commit removes this field and stops creation of objects for each context, which will also allow incoming activities to use activity IDs as contexts, something which was not possible before, or would have been very broken under most circumstances. The `pleroma.conversation_id` field has been reimplemented in a way to maintain backwards-compatibility by calculating a CRC32 of the full context URI/string in the object, instead of relying on the row ID for the created context object.
This commit is contained in:
parent
7de21ec991
commit
f3e061c964
14 changed files with 9 additions and 102 deletions
|
|
@ -208,10 +208,6 @@ defmodule Pleroma.Object do
|
|||
end
|
||||
end
|
||||
|
||||
def context_mapping(context) do
|
||||
Object.change(%Object{}, %{data: %{"id" => context}})
|
||||
end
|
||||
|
||||
def make_tombstone(%Object{data: %{"id" => id, "type" => type}}, deleted \\ DateTime.utc_now()) do
|
||||
%ObjectTombstone{
|
||||
id: id,
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
|||
defp validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["Article", "Note", "Page"])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|
|
|
|||
|
|
@ -22,14 +22,12 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
|
|||
end
|
||||
|
||||
def fix_object_defaults(data) do
|
||||
%{data: %{"id" => context}, id: context_id} =
|
||||
Utils.create_context(data["context"] || data["conversation"])
|
||||
context = Utils.maybe_create_context(data["context"] || data["conversation"])
|
||||
|
||||
%User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["attributedTo"])
|
||||
|
||||
data
|
||||
|> Map.put("context", context)
|
||||
|> Map.put("context_id", context_id)
|
||||
|> cast_and_filter_recipients("to", follower_collection)
|
||||
|> cast_and_filter_recipients("cc", follower_collection)
|
||||
|> cast_and_filter_recipients("bto", follower_collection)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
|
|||
defp validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["Event"])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
defp validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["Question"])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|
|
|
|||
|
|
@ -154,22 +154,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
Notification.get_notified_from_activity(%Activity{data: object}, false)
|
||||
end
|
||||
|
||||
def create_context(context) do
|
||||
context = context || generate_id("contexts")
|
||||
|
||||
# Ecto has problems accessing the constraint inside the jsonb,
|
||||
# so we explicitly check for the existed object before insert
|
||||
object = Object.get_cached_by_ap_id(context)
|
||||
|
||||
with true <- is_nil(object),
|
||||
changeset <- Object.context_mapping(context),
|
||||
{:ok, inserted_object} <- Repo.insert(changeset) do
|
||||
inserted_object
|
||||
else
|
||||
_ ->
|
||||
object
|
||||
end
|
||||
end
|
||||
def maybe_create_context(context), do: context || generate_id("contexts")
|
||||
|
||||
@doc """
|
||||
Enqueues an activity for federation if it's local
|
||||
|
|
@ -201,18 +186,16 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
|> Map.put_new("id", "pleroma:fakeid")
|
||||
|> Map.put_new_lazy("published", &make_date/0)
|
||||
|> Map.put_new("context", "pleroma:fakecontext")
|
||||
|> Map.put_new("context_id", -1)
|
||||
|> lazy_put_object_defaults(true)
|
||||
end
|
||||
|
||||
def lazy_put_activity_defaults(map, _fake?) do
|
||||
%{data: %{"id" => context}, id: context_id} = create_context(map["context"])
|
||||
context = maybe_create_context(map["context"])
|
||||
|
||||
map
|
||||
|> Map.put_new_lazy("id", &generate_activity_id/0)
|
||||
|> Map.put_new_lazy("published", &make_date/0)
|
||||
|> Map.put_new("context", context)
|
||||
|> Map.put_new("context_id", context_id)
|
||||
|> lazy_put_object_defaults(false)
|
||||
end
|
||||
|
||||
|
|
@ -226,7 +209,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
|> Map.put_new("id", "pleroma:fake_object_id")
|
||||
|> Map.put_new_lazy("published", &make_date/0)
|
||||
|> Map.put_new("context", activity["context"])
|
||||
|> Map.put_new("context_id", activity["context_id"])
|
||||
|> Map.put_new("fake", true)
|
||||
|
||||
%{activity | "object" => object}
|
||||
|
|
@ -239,7 +221,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
|> Map.put_new_lazy("id", &generate_object_id/0)
|
||||
|> Map.put_new_lazy("published", &make_date/0)
|
||||
|> Map.put_new("context", activity["context"])
|
||||
|> Map.put_new("context_id", activity["context_id"])
|
||||
|
||||
%{activity | "object" => object}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -449,35 +449,6 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
|||
|
||||
def get_report_statuses(_, _), do: {:ok, nil}
|
||||
|
||||
# DEPRECATED mostly, context objects are now created at insertion time.
|
||||
def context_to_conversation_id(context) do
|
||||
with %Object{id: id} <- Object.get_cached_by_ap_id(context) do
|
||||
id
|
||||
else
|
||||
_e ->
|
||||
changeset = Object.context_mapping(context)
|
||||
|
||||
case Repo.insert(changeset) do
|
||||
{:ok, %{id: id}} ->
|
||||
id
|
||||
|
||||
# This should be solved by an upsert, but it seems ecto
|
||||
# has problems accessing the constraint inside the jsonb.
|
||||
{:error, _} ->
|
||||
Object.get_cached_by_ap_id(context).id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def conversation_id_to_context(id) do
|
||||
with %Object{data: %{"id" => context}} <- Repo.get(Object, id) do
|
||||
context
|
||||
else
|
||||
_e ->
|
||||
{:error, dgettext("errors", "No such conversation")}
|
||||
end
|
||||
end
|
||||
|
||||
def validate_character_limit("" = _full_payload, [] = _attachments) do
|
||||
{:error, dgettext("errors", "Cannot post an empty status without attachments")}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
do: context_id
|
||||
|
||||
defp get_context_id(%{data: %{"context" => context}}) when is_binary(context),
|
||||
do: Utils.context_to_conversation_id(context)
|
||||
do: :erlang.crc32(context)
|
||||
|
||||
defp get_context_id(_), do: nil
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue