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
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)
Object.increase_replies_count(reply_ap_id)
end
end
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)
Object.decrease_replies_count(reply_ap_id)
end
end
{:ok, map} <- MRF.filter(map),
{recipients, _, _} = get_recipients(map),
{:fake, false, map, recipients} <- {:fake, fake, map, recipients},
- {:ok, object} <- insert_full_object(map) do
+ {:ok, map, object} <- insert_full_object(map) do
{:ok, activity} =
Repo.insert(%Activity{
data: map,
end
if activity.data["type"] in ["Create"] do
- activity.data["object"]
+ object = Object.normalize(activity)
+
+ 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
if !Enum.member?(activity.data["cc"] || [], public) &&
!Enum.member?(
activity.data["to"],
- User.get_by_ap_id(activity.data["actor"]).follower_address
+ User.get_cached_by_ap_id(activity.data["actor"]).follower_address
),
do: Pleroma.Web.Streamer.stream("direct", activity)
end
:ok <- maybe_federate(activity) do
Enum.each(User.all_superusers(), fn superuser ->
superuser
- |> Pleroma.AdminEmail.report(actor, account, statuses, content)
+ |> Pleroma.Emails.AdminEmail.report(actor, account, statuses, content)
|> Pleroma.Emails.Mailer.deliver_async()
end)
q
|> restrict_unlisted()
- |> Repo.all()
+ |> Pagination.fetch_paginated(opts)
|> Enum.reverse()
end
defp restrict_since(query, _), do: query
+ defp restrict_tag_reject(_query, %{"tag_reject" => _tag_reject, "skip_preload" => true}) do
+ raise "Can't use the child object without preloading!"
+ end
+
defp restrict_tag_reject(query, %{"tag_reject" => tag_reject})
when is_list(tag_reject) and tag_reject != [] do
from(
- activity in query,
- where: fragment(~s(\(not \(? #> '{"object","tag"}'\) \\?| ?\)), activity.data, ^tag_reject)
+ [_activity, object] in query,
+ where: fragment("not (?)->'tag' \\?| (?)", object.data, ^tag_reject)
)
end
defp restrict_tag_reject(query, _), do: query
+ defp restrict_tag_all(_query, %{"tag_all" => _tag_all, "skip_preload" => true}) do
+ raise "Can't use the child object without preloading!"
+ end
+
defp restrict_tag_all(query, %{"tag_all" => tag_all})
when is_list(tag_all) and tag_all != [] do
from(
- activity in query,
- where: fragment(~s(\(? #> '{"object","tag"}'\) \\?& ?), activity.data, ^tag_all)
+ [_activity, object] in query,
+ where: fragment("(?)->'tag' \\?& (?)", object.data, ^tag_all)
)
end
defp restrict_tag_all(query, _), do: query
+ defp restrict_tag(_query, %{"tag" => _tag, "skip_preload" => true}) do
+ raise "Can't use the child object without preloading!"
+ end
+
defp restrict_tag(query, %{"tag" => tag}) when is_list(tag) do
from(
- activity in query,
- where: fragment(~s(\(? #> '{"object","tag"}'\) \\?| ?), activity.data, ^tag)
+ [_activity, object] in query,
+ where: fragment("(?)->'tag' \\?| (?)", object.data, ^tag)
)
end
defp restrict_tag(query, %{"tag" => tag}) when is_binary(tag) do
from(
- activity in query,
- where: fragment(~s(? <@ (? #> '{"object","tag"}'\)), ^tag, activity.data)
+ [_activity, object] in query,
+ where: fragment("(?)->'tag' \\? (?)", object.data, ^tag)
)
end
)
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
defp restrict_favorited_by(query, _), do: query
+ defp restrict_media(_query, %{"only_media" => _val, "skip_preload" => true}) do
+ raise "Can't use the child object without preloading!"
+ end
+
defp restrict_media(query, %{"only_media" => val}) when val == "true" or val == "1" do
from(
- activity in query,
- where: fragment(~s(not (? #> '{"object","attachment"}' = ?\)), activity.data, ^[])
+ [_activity, object] in query,
+ where: fragment("not (?)->'attachment' = (?)", object.data, ^[])
)
end
from(
activity in query,
where: fragment("not (? = ANY(?))", activity.actor, ^blocks),
- where: fragment("not (?->'to' \\?| ?)", activity.data, ^blocks),
+ where: fragment("not (? && ?)", activity.recipients, ^blocks),
+ where:
+ fragment(
+ "not (?->>'type' = 'Announce' and ?->'to' \\?| ?)",
+ activity.data,
+ activity.data,
+ ^blocks
+ ),
where: fragment("not (split_part(?, '/', 3) = ANY(?))", activity.actor, ^domain_blocks)
)
end
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)
|> 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)
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
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)}")
end
def make_user_from_ap_id(ap_id) do
- if _user = User.get_by_ap_id(ap_id) do
+ if _user = User.get_cached_by_ap_id(ap_id) do
Transmogrifier.upgrade_user_from_ap_id(ap_id)
else
with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id) 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)