X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Factivity_pub.ex;h=1a3b47cb34fe401d707e6c5e4abbb41785f781bc;hb=627e5a0a4992cc19fc65a7e93a09c470c8e2bf33;hp=0d9a89d0b2dc3bee4557416a25669e94244da7b5;hpb=21ff78cd40820b6b5e56b78a08afddd04417937b;p=akkoma diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 0d9a89d0b..1a3b47cb3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -7,13 +7,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do alias Pleroma.Instances alias Pleroma.Notification alias Pleroma.Object + alias Pleroma.Object.Fetcher + alias Pleroma.Pagination alias Pleroma.Repo alias Pleroma.Upload alias Pleroma.User alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.Federator - alias Pleroma.Web.OStatus alias Pleroma.Web.WebFinger import Ecto.Query @@ -90,12 +91,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end def increase_replies_count_if_reply(%{ - "object" => - %{"inReplyTo" => reply_ap_id, "inReplyToStatusId" => reply_status_id} = object, + "object" => %{"inReplyTo" => reply_ap_id} = object, "type" => "Create" }) do if is_public?(object) do - Activity.increase_replies_count(reply_status_id) + Activity.increase_replies_count(reply_ap_id) Object.increase_replies_count(reply_ap_id) end end @@ -103,25 +103,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def increase_replies_count_if_reply(_create_data), do: :noop def decrease_replies_count_if_reply(%Object{ - data: %{"inReplyTo" => reply_ap_id, "inReplyToStatusId" => reply_status_id} = object + data: %{"inReplyTo" => reply_ap_id} = object }) do if is_public?(object) do - Activity.decrease_replies_count(reply_status_id) + Activity.decrease_replies_count(reply_ap_id) Object.decrease_replies_count(reply_ap_id) end end def decrease_replies_count_if_reply(_object), do: :noop - def insert(map, local \\ true) when is_map(map) do + def insert(map, local \\ true, fake \\ false) when is_map(map) do with nil <- Activity.normalize(map), - map <- lazy_put_activity_defaults(map), + map <- lazy_put_activity_defaults(map, fake), :ok <- check_actor_is_active(map["actor"]), {_, true} <- {:remote_limit_error, check_remote_limit(map)}, {:ok, map} <- MRF.filter(map), - {:ok, object} <- insert_full_object(map) do - {recipients, _, _} = get_recipients(map) - + {recipients, _, _} = get_recipients(map), + {:fake, false, map, recipients} <- {:fake, fake, map, recipients}, + {:ok, map, object} <- insert_full_object(map) do {:ok, activity} = Repo.insert(%Activity{ data: map, @@ -146,15 +146,31 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do stream_out(activity) {:ok, activity} else - %Activity{} = activity -> {:ok, activity} - error -> {:error, error} + %Activity{} = activity -> + {:ok, activity} + + {:fake, true, map, recipients} -> + activity = %Activity{ + data: map, + local: local, + actor: map["actor"], + recipients: recipients, + id: "pleroma:fakeid" + } + + Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + {:ok, activity} + + error -> + {:error, error} end end def stream_out(activity) do public = "https://www.w3.org/ns/activitystreams#Public" - if activity.data["type"] in ["Create", "Announce", "Delete"] do + if activity.data["type"] in ["Create", "Announce"] do + object = Object.normalize(activity.data["object"]) Pleroma.Web.Streamer.stream("user", activity) Pleroma.Web.Streamer.stream("list", activity) @@ -166,12 +182,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end if activity.data["type"] in ["Create"] do - activity.data["object"] + object.data |> Map.get("tag", []) |> Enum.filter(fn tag -> is_bitstring(tag) end) |> Enum.each(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) - if activity.data["object"]["attachment"] != [] do + if object.data["attachment"] != [] do Pleroma.Web.Streamer.stream("public:media", activity) if activity.local do @@ -190,7 +206,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - def create(%{to: to, actor: actor, context: context, object: object} = params) do + def create(%{to: to, actor: actor, context: context, object: object} = params, fake \\ false) do additional = params[:additional] || %{} # only accept false as false value local = !(params[:local] == false) @@ -201,13 +217,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do %{to: to, actor: actor, published: published, context: context, object: object}, additional ), - {:ok, activity} <- insert(create_data, local), + {:ok, activity} <- insert(create_data, local, fake), + {:fake, false, activity} <- {:fake, fake, activity}, _ <- increase_replies_count_if_reply(create_data), # Changing note count prior to enqueuing federation task in order to avoid # race conditions on updating user.info {:ok, _actor} <- increase_note_count_if_public(actor, activity), :ok <- maybe_federate(activity) do {:ok, activity} + else + {:fake, true, activity} -> + {:ok, activity} end end @@ -430,8 +450,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do :ok <- maybe_federate(activity) do Enum.each(User.all_superusers(), fn superuser -> superuser - |> Pleroma.AdminEmail.report(actor, account, statuses, content) - |> Pleroma.Mailer.deliver_async() + |> Pleroma.Emails.AdminEmail.report(actor, account, statuses, content) + |> Pleroma.Emails.Mailer.deliver_async() end) {:ok, activity} @@ -474,7 +494,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do q |> restrict_unlisted() - |> Repo.all() + |> Pagination.fetch_paginated(opts) |> Enum.reverse() end @@ -617,26 +637,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do ) end - defp restrict_limit(query, %{"limit" => limit}) do - from(activity in query, limit: ^limit) - end - - defp restrict_limit(query, _), do: query - defp restrict_local(query, %{"local_only" => true}) do from(activity in query, where: activity.local == true) end defp restrict_local(query, _), do: query - defp restrict_max(query, %{"max_id" => ""}), do: query - - defp restrict_max(query, %{"max_id" => max_id}) do - from(activity in query, where: activity.id < ^max_id) - end - - defp restrict_max(query, _), do: query - defp restrict_actor(query, %{"actor_id" => actor_id}) do from(activity in query, where: activity.actor == ^actor_id) end @@ -737,8 +743,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do from( activity in query, - where: fragment("not ?->>'type' = 'Announce'", activity.data), - where: fragment("not ? = ANY(?)", activity.actor, ^muted_reblogs) + where: + fragment( + "not ( ?->>'type' = 'Announce' and ? = ANY(?))", + activity.data, + activity.actor, + ^muted_reblogs + ) ) end @@ -752,12 +763,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end def fetch_activities_query(recipients, opts \\ %{}) do - base_query = - from( - activity in Activity, - limit: 20, - order_by: [fragment("? desc nulls last", activity.id)] - ) + base_query = from(activity in Activity) base_query |> maybe_preload_objects(opts) @@ -767,8 +773,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_tag_all(opts) |> restrict_since(opts) |> restrict_local(opts) - |> restrict_limit(opts) - |> restrict_max(opts) |> restrict_actor(opts) |> restrict_type(opts) |> restrict_favorited_by(opts) @@ -784,14 +788,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def fetch_activities(recipients, opts \\ %{}) do fetch_activities_query(recipients, opts) - |> Repo.all() + |> Pagination.fetch_paginated(opts) |> Enum.reverse() end def fetch_activities_bounded(recipients_to, recipients_cc, opts \\ %{}) do fetch_activities_query([], opts) |> restrict_to_cc(recipients_to, recipients_cc) - |> Repo.all() + |> Pagination.fetch_paginated(opts) |> Enum.reverse() end @@ -856,7 +860,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end def fetch_and_prepare_user_from_ap_id(ap_id) do - with {:ok, data} <- fetch_and_contain_remote_object_from_id(ap_id) do + with {:ok, data} <- Fetcher.fetch_and_contain_remote_object_from_id(ap_id) do user_data_from_user_object(data) else e -> Logger.error("Could not decode user at fetch #{ap_id}, #{inspect(e)}") @@ -966,60 +970,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - # TODO: - # This will create a Create activity, which we need internally at the moment. - def fetch_object_from_id(id) do - if object = Object.get_cached_by_ap_id(id) do - {:ok, object} - else - with {:ok, data} <- fetch_and_contain_remote_object_from_id(id), - nil <- Object.normalize(data), - params <- %{ - "type" => "Create", - "to" => data["to"], - "cc" => data["cc"], - "actor" => data["actor"] || data["attributedTo"], - "object" => data - }, - :ok <- Transmogrifier.contain_origin(id, params), - {:ok, activity} <- Transmogrifier.handle_incoming(params) do - {:ok, Object.normalize(activity)} - else - {:error, {:reject, nil}} -> - {:reject, nil} - - object = %Object{} -> - {:ok, object} - - _e -> - Logger.info("Couldn't get object via AP, trying out OStatus fetching...") - - case OStatus.fetch_activity_from_url(id) do - {:ok, [activity | _]} -> {:ok, Object.normalize(activity)} - e -> e - end - end - end - end - - def fetch_and_contain_remote_object_from_id(id) do - Logger.info("Fetching object #{id} via AP") - - with true <- String.starts_with?(id, "http"), - {:ok, %{body: body, status: code}} when code in 200..299 <- - @httpoison.get( - id, - [{:Accept, "application/activity+json"}] - ), - {:ok, data} <- Jason.decode(body), - :ok <- Transmogrifier.contain_origin_from_id(id, data) do - {:ok, data} - else - e -> - {:error, e} - end - end - # filter out broken threads def contain_broken_threads(%Activity{} = activity, %User{} = user) do entire_thread_visible_for_user?(activity, user)