X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fobject.ex;h=e678fd415465850fb452bcd4075ae612bff95f9f;hb=5102468d0f8067548ef233b5947da4bc517f5774;hp=eb37b95a6ed88da494ee69adc64bb2e4b7112e23;hpb=8cb852523a13530ae77b76e4d3253ccd5883e9dc;p=akkoma diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index eb37b95a6..e678fd415 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -1,10 +1,13 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors +# Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Object do use Ecto.Schema + import Ecto.Query + import Ecto.Changeset + alias Pleroma.Activity alias Pleroma.Object alias Pleroma.Object.Fetcher @@ -12,11 +15,12 @@ defmodule Pleroma.Object do alias Pleroma.Repo alias Pleroma.User - import Ecto.Query - import Ecto.Changeset - require Logger + @type t() :: %__MODULE__{} + + @derive {Jason.Encoder, only: [:data]} + schema "objects" do field(:data, :map) @@ -79,6 +83,20 @@ defmodule Pleroma.Object do Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id))) end + @doc """ + Get a single attachment by it's name and href + """ + @spec get_attachment_by_name_and_href(String.t(), String.t()) :: Object.t() | nil + def get_attachment_by_name_and_href(name, href) do + query = + from(o in Object, + where: fragment("(?)->>'name' = ?", o.data, ^name), + where: fragment("(?)->>'href' = ?", o.data, ^href) + ) + + Repo.one(query) + end + defp warn_on_no_object_preloaded(ap_id) do "Object.normalize() called without preloaded object (#{inspect(ap_id)}). Consider preloading the object" |> Logger.debug() @@ -127,18 +145,18 @@ defmodule Pleroma.Object do # Legacy objects can be mutated by anybody def authorize_mutation(%Object{}, %User{}), do: true + @spec get_cached_by_ap_id(String.t()) :: Object.t() | nil def get_cached_by_ap_id(ap_id) do key = "object:#{ap_id}" - Cachex.fetch!(:object_cache, key, fn _ -> - object = get_by_ap_id(ap_id) - - if object do - {:commit, object} - else - {:ignore, object} - end - end) + with {:ok, nil} <- Cachex.get(:object_cache, key), + object when not is_nil(object) <- get_by_ap_id(ap_id), + {:ok, true} <- Cachex.put(:object_cache, key, object) do + object + else + {:ok, object} -> object + nil -> nil + end end def context_mapping(context) do @@ -167,6 +185,13 @@ defmodule Pleroma.Object do deleted_activity = Activity.delete_all_by_object_ap_id(id), {:ok, true} <- Cachex.del(:object_cache, "object:#{id}"), {:ok, _} <- Cachex.del(:web_resp_cache, URI.parse(id).path) do + with true <- Pleroma.Config.get([:instance, :cleanup_attachments]) do + {:ok, _} = + Pleroma.Workers.AttachmentsCleanupWorker.enqueue("cleanup_attachments", %{ + "object" => object + }) + end + {:ok, object, deleted_activity} end end @@ -236,7 +261,7 @@ defmodule Pleroma.Object do end end - def increase_vote_count(ap_id, name) do + def increase_vote_count(ap_id, name, actor) do with %Object{} = object <- Object.normalize(ap_id), "Question" <- object.data["type"] do multiple = Map.has_key?(object.data, "anyOf") @@ -251,12 +276,15 @@ defmodule Pleroma.Object do option end) + voters = [actor | object.data["voters"] || []] |> Enum.uniq() + data = if multiple do Map.put(object.data, "anyOf", options) else Map.put(object.data, "oneOf", options) end + |> Map.put("voters", voters) object |> Object.change(%{data: data}) @@ -276,4 +304,26 @@ defmodule Pleroma.Object do def local?(%Object{data: %{"id" => id}}) do String.starts_with?(id, Pleroma.Web.base_url() <> "/") end + + def replies(object, opts \\ []) do + object = Object.normalize(object) + + query = + Object + |> where( + [o], + fragment("(?)->>'inReplyTo' = ?", o.data, ^object.data["id"]) + ) + |> order_by([o], asc: o.id) + + if opts[:self_only] do + actor = object.data["actor"] + where(query, [o], fragment("(?)->>'actor' = ?", o.data, ^actor)) + else + query + end + end + + def self_replies(object, opts \\ []), + do: replies(object, Keyword.put(opts, :self_only, true)) end