use Ecto.Schema
alias Pleroma.EctoType.ActivityPub.ObjectValidators
- alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
+ alias Pleroma.Object.Fetcher
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
- alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
alias Pleroma.Web.ActivityPub.Transmogrifier
import Ecto.Changeset
+ require Logger
+
@primary_key false
@derive Jason.Encoder
embedded_schema do
- field(:id, ObjectValidators.ObjectID, primary_key: true)
- field(:to, ObjectValidators.Recipients, default: [])
- field(:cc, ObjectValidators.Recipients, default: [])
- field(:bto, ObjectValidators.Recipients, default: [])
- field(:bcc, ObjectValidators.Recipients, default: [])
- embeds_many(:tag, TagValidator)
- field(:type, :string)
-
- field(:name, :string)
- field(:summary, :string)
- field(:content, :string)
-
- field(:context, :string)
- # short identifier for PleromaFE to group statuses by context
- field(:context_id, :integer)
-
- # TODO: Remove actor on objects
- field(:actor, ObjectValidators.ObjectID)
-
- field(:attributedTo, ObjectValidators.ObjectID)
- field(:published, ObjectValidators.DateTime)
- field(:emoji, ObjectValidators.Emoji, default: %{})
- field(:sensitive, :boolean, default: false)
- embeds_many(:attachment, AttachmentValidator)
- field(:replies_count, :integer, default: 0)
- field(:like_count, :integer, default: 0)
- field(:announcement_count, :integer, default: 0)
- field(:inReplyTo, ObjectValidators.ObjectID)
- field(:url, ObjectValidators.Uri)
-
- field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
- field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
+ quote do
+ unquote do
+ import Elixir.Pleroma.Web.ActivityPub.ObjectValidators.CommonFields
+ message_fields()
+ object_fields()
+ status_object_fields()
+ end
+ end
field(:replies, {:array, ObjectValidators.ObjectID}, default: [])
+ field(:source, :map)
end
def cast_and_apply(data) do
defp fix_replies(%{"replies" => replies} = data) when is_bitstring(replies),
do: Map.drop(data, ["replies"])
+ defp fix_replies(%{"replies" => %{"first" => first}} = data) do
+ with {:ok, %{"orderedItems" => replies}} <-
+ Fetcher.fetch_and_contain_remote_object_from_id(first) do
+ Map.put(data, "replies", replies)
+ else
+ {:error, _} ->
+ Logger.error("Could not fetch replies for #{first}")
+ Map.put(data, "replies", [])
+ end
+ end
+
defp fix_replies(data), do: data
+ # https://github.com/misskey-dev/misskey/pull/8787
+ defp fix_misskey_content(%{"source" => %{"mediaType" => "text/x.misskeymarkdown"}} = object),
+ do: object
+
+ defp fix_misskey_content(%{"_misskey_content" => content} = object) do
+ object
+ |> Map.put("source", %{"content" => content, "mediaType" => "text/x.misskeymarkdown"})
+ |> Map.delete("_misskey_content")
+ end
+
+ defp fix_misskey_content(data), do: data
+
+ defp fix_source(%{"source" => source} = object) when is_binary(source) do
+ object
+ |> Map.put("source", %{"content" => source})
+ end
+
+ defp fix_source(object), do: object
+
defp fix(data) do
data
|> CommonFixes.fix_actor()
|> fix_url()
|> fix_tag()
|> fix_replies()
+ |> fix_source()
+ |> fix_misskey_content()
|> Transmogrifier.fix_emoji()
|> Transmogrifier.fix_content_map()
end