X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fobject.ex;h=1d756bcd1743af73eb413999cddcfd120f15f62e;hb=4134abef63e1165f5701741c1012e64cb908654c;hp=4dd929cfd61c6a78a3578073098fa519194e36f6;hpb=19c108170edb2d72d52c56d82475b565e6fd6b36;p=akkoma diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 4dd929cfd..1d756bcd1 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -10,6 +10,7 @@ defmodule Pleroma.Object do alias Pleroma.Activity alias Pleroma.Config + alias Pleroma.Hashtag alias Pleroma.Object alias Pleroma.Object.Fetcher alias Pleroma.ObjectTombstone @@ -23,9 +24,13 @@ defmodule Pleroma.Object do @derive {Jason.Encoder, only: [:data]} + @cachex Pleroma.Config.get([:cachex, :provider], Cachex) + schema "objects" do field(:data, :map) + many_to_many(:hashtags, Hashtag, join_through: "hashtags_objects", on_replace: :delete) + timestamps() end @@ -47,7 +52,8 @@ defmodule Pleroma.Object do end def create(data) do - Object.change(%Object{}, %{data: data}) + %Object{} + |> Object.change(%{data: data}) |> Repo.insert() end @@ -56,8 +62,37 @@ defmodule Pleroma.Object do |> cast(params, [:data]) |> validate_required([:data]) |> unique_constraint(:ap_id, name: :objects_unique_apid_index) + |> maybe_handle_hashtags_change(struct) + end + + defp maybe_handle_hashtags_change(changeset, struct) do + with data_hashtags_change = get_change(changeset, :data), + true <- hashtags_changed?(struct, data_hashtags_change), + {:ok, hashtag_records} <- + data_hashtags_change + |> object_data_hashtags() + |> Hashtag.get_or_create_by_names() do + put_assoc(changeset, :hashtags, hashtag_records) + else + false -> + changeset + + {:error, hashtag_changeset} -> + failed_hashtag = get_field(hashtag_changeset, :name) + + validate_change(changeset, :data, fn _, _ -> + [data: "error referencing hashtag: #{failed_hashtag}"] + end) + end + end + + defp hashtags_changed?(%Object{} = struct, %{"tag" => _} = data) do + Enum.sort(embedded_hashtags(struct)) != + Enum.sort(object_data_hashtags(data)) end + defp hashtags_changed?(_, _), do: false + def get_by_id(nil), do: nil def get_by_id(id), do: Repo.get(Object, id) @@ -156,9 +191,9 @@ defmodule Pleroma.Object do def get_cached_by_ap_id(ap_id) do key = "object:#{ap_id}" - with {:ok, nil} <- Cachex.get(:object_cache, key), + 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 + {:ok, true} <- @cachex.put(:object_cache, key, object) do object else {:ok, object} -> object @@ -216,13 +251,13 @@ defmodule Pleroma.Object do end def invalid_object_cache(%Object{data: %{"id" => id}}) do - with {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do - Cachex.del(:web_resp_cache, URI.parse(id).path) + with {:ok, true} <- @cachex.del(:object_cache, "object:#{id}") do + @cachex.del(:web_resp_cache, URI.parse(id).path) end end def set_cache(%Object{data: %{"id" => ap_id}} = object) do - Cachex.put(:object_cache, "object:#{ap_id}", object) + @cachex.put(:object_cache, "object:#{ap_id}", object) {:ok, object} end @@ -255,9 +290,7 @@ defmodule Pleroma.Object do end end - defp poll_is_multiple?(%Object{data: %{"anyOf" => anyOf}}) do - !Enum.empty?(anyOf) - end + defp poll_is_multiple?(%Object{data: %{"anyOf" => [_ | _]}}), do: true defp poll_is_multiple?(_), do: false @@ -346,4 +379,23 @@ defmodule Pleroma.Object do def self_replies(object, opts \\ []), do: replies(object, Keyword.put(opts, :self_only, true)) + + def tags(%Object{data: %{"tag" => tags}}) when is_list(tags), do: tags + + def tags(_), do: [] + + def hashtags(object), do: embedded_hashtags(object) + + defp embedded_hashtags(%Object{data: data}) do + object_data_hashtags(data) + end + + defp embedded_hashtags(_), do: [] + + defp object_data_hashtags(%{"tag" => tags}) when is_list(tags) do + # Note: AS2 map-type elements are ignored + Enum.filter(tags, &is_bitstring(&1)) + end + + defp object_data_hashtags(_), do: [] end