Added limits and media attachments for scheduled activities.
This commit is contained in:
parent
b3870df51f
commit
fc92a0fd8d
11 changed files with 327 additions and 30 deletions
|
|
@ -184,4 +184,12 @@ defmodule Pleroma.Object do
|
|||
_ -> {:error, "Not found"}
|
||||
end
|
||||
end
|
||||
|
||||
def enforce_user_objects(user, object_ids) do
|
||||
Object
|
||||
|> where([o], fragment("?->>'actor' = ?", o.data, ^user.ap_id))
|
||||
|> where([o], o.id in ^object_ids)
|
||||
|> select([o], o.id)
|
||||
|> Repo.all()
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@
|
|||
defmodule Pleroma.ScheduledActivity do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
|
||||
import Ecto.Query
|
||||
import Ecto.Changeset
|
||||
|
|
@ -25,11 +28,69 @@ defmodule Pleroma.ScheduledActivity do
|
|||
def changeset(%ScheduledActivity{} = scheduled_activity, attrs) do
|
||||
scheduled_activity
|
||||
|> cast(attrs, [:scheduled_at, :params])
|
||||
|> validate_required([:scheduled_at, :params])
|
||||
|> validate_scheduled_at()
|
||||
|> with_media_attachments()
|
||||
end
|
||||
|
||||
defp with_media_attachments(
|
||||
%{changes: %{params: %{"media_ids" => media_ids} = params}} = changeset
|
||||
)
|
||||
when is_list(media_ids) do
|
||||
user = User.get_cached_by_id(changeset.data.user_id)
|
||||
media_ids = Object.enforce_user_objects(user, media_ids) |> Enum.map(&to_string(&1))
|
||||
media_attachments = Utils.attachments_from_ids(%{"media_ids" => media_ids})
|
||||
|
||||
params =
|
||||
params
|
||||
|> Map.put("media_attachments", media_attachments)
|
||||
|> Map.put("media_ids", media_ids)
|
||||
|
||||
put_change(changeset, :params, params)
|
||||
end
|
||||
|
||||
defp with_media_attachments(changeset), do: changeset
|
||||
|
||||
def update_changeset(%ScheduledActivity{} = scheduled_activity, attrs) do
|
||||
scheduled_activity
|
||||
|> cast(attrs, [:scheduled_at])
|
||||
|> validate_required([:scheduled_at])
|
||||
|> validate_scheduled_at()
|
||||
end
|
||||
|
||||
def validate_scheduled_at(changeset) do
|
||||
validate_change(changeset, :scheduled_at, fn _, scheduled_at ->
|
||||
cond do
|
||||
not far_enough?(scheduled_at) ->
|
||||
[scheduled_at: "must be at least 5 minutes from now"]
|
||||
|
||||
exceeds_daily_user_limit?(changeset.data.user_id, scheduled_at) ->
|
||||
[scheduled_at: "daily limit exceeded"]
|
||||
|
||||
exceeds_total_user_limit?(changeset.data.user_id) ->
|
||||
[scheduled_at: "total limit exceeded"]
|
||||
|
||||
true ->
|
||||
[]
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def exceeds_daily_user_limit?(user_id, scheduled_at) do
|
||||
ScheduledActivity
|
||||
|> where(user_id: ^user_id)
|
||||
|> where([s], type(s.scheduled_at, :date) == type(^scheduled_at, :date))
|
||||
|> select([u], count(u.id))
|
||||
|> Repo.one()
|
||||
|> Kernel.>=(Config.get([ScheduledActivity, :daily_user_limit]))
|
||||
end
|
||||
|
||||
def exceeds_total_user_limit?(user_id) do
|
||||
ScheduledActivity
|
||||
|> where(user_id: ^user_id)
|
||||
|> select([u], count(u.id))
|
||||
|> Repo.one()
|
||||
|> Kernel.>=(Config.get([ScheduledActivity, :total_user_limit]))
|
||||
end
|
||||
|
||||
def far_enough?(scheduled_at) when is_binary(scheduled_at) do
|
||||
|
|
@ -64,23 +125,15 @@ defmodule Pleroma.ScheduledActivity do
|
|||
|> Repo.one()
|
||||
end
|
||||
|
||||
def update(%User{} = user, scheduled_activity_id, attrs) do
|
||||
with %ScheduledActivity{} = scheduled_activity <- get(user, scheduled_activity_id) do
|
||||
scheduled_activity
|
||||
|> update_changeset(attrs)
|
||||
|> Repo.update()
|
||||
else
|
||||
nil -> {:error, :not_found}
|
||||
end
|
||||
def update(scheduled_activity, attrs) do
|
||||
scheduled_activity
|
||||
|> update_changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
def delete(%User{} = user, scheduled_activity_id) do
|
||||
with %ScheduledActivity{} = scheduled_activity <- get(user, scheduled_activity_id) do
|
||||
scheduled_activity
|
||||
|> Repo.delete()
|
||||
else
|
||||
nil -> {:error, :not_found}
|
||||
end
|
||||
def delete(scheduled_activity) do
|
||||
scheduled_activity
|
||||
|> Repo.delete()
|
||||
end
|
||||
|
||||
def for_user_query(%User{} = user) do
|
||||
|
|
|
|||
|
|
@ -390,18 +390,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
%{assigns: %{user: user}} = conn,
|
||||
%{"id" => scheduled_activity_id} = params
|
||||
) do
|
||||
with {:ok, scheduled_activity} <-
|
||||
ScheduledActivity.update(user, scheduled_activity_id, params) do
|
||||
with %ScheduledActivity{} = scheduled_activity <-
|
||||
ScheduledActivity.get(user, scheduled_activity_id),
|
||||
{:ok, scheduled_activity} <- ScheduledActivity.update(scheduled_activity, params) do
|
||||
conn
|
||||
|> put_view(ScheduledActivityView)
|
||||
|> render("show.json", %{scheduled_activity: scheduled_activity})
|
||||
else
|
||||
nil -> {:error, :not_found}
|
||||
error -> error
|
||||
end
|
||||
end
|
||||
|
||||
def delete_scheduled_status(%{assigns: %{user: user}} = conn, %{"id" => scheduled_activity_id}) do
|
||||
with {:ok, %ScheduledActivity{}} <- ScheduledActivity.delete(user, scheduled_activity_id) do
|
||||
with %ScheduledActivity{} = scheduled_activity <-
|
||||
ScheduledActivity.get(user, scheduled_activity_id),
|
||||
{:ok, scheduled_activity} <- ScheduledActivity.delete(scheduled_activity) do
|
||||
conn
|
||||
|> json(%{})
|
||||
|> put_view(ScheduledActivityView)
|
||||
|> render("show.json", %{scheduled_activity: scheduled_activity})
|
||||
else
|
||||
nil -> {:error, :not_found}
|
||||
error -> error
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do
|
|||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
def render("index.json", %{scheduled_activities: scheduled_activities}) do
|
||||
render_many(scheduled_activities, ScheduledActivityView, "show.json")
|
||||
|
|
@ -17,7 +18,36 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do
|
|||
%{
|
||||
id: scheduled_activity.id |> to_string,
|
||||
scheduled_at: scheduled_activity.scheduled_at |> CommonAPI.Utils.to_masto_date(),
|
||||
params: scheduled_activity.params
|
||||
params: status_params(scheduled_activity.params)
|
||||
}
|
||||
|> with_media_attachments(scheduled_activity)
|
||||
end
|
||||
|
||||
defp with_media_attachments(data, %{params: %{"media_attachments" => media_attachments}}) do
|
||||
attachments = render_many(media_attachments, StatusView, "attachment.json", as: :attachment)
|
||||
Map.put(data, :media_attachments, attachments)
|
||||
end
|
||||
|
||||
defp with_media_attachments(data, _), do: data
|
||||
|
||||
defp status_params(params) do
|
||||
data = %{
|
||||
text: params["status"],
|
||||
sensitive: params["sensitive"],
|
||||
spoiler_text: params["spoiler_text"],
|
||||
visibility: params["visibility"],
|
||||
scheduled_at: params["scheduled_at"],
|
||||
poll: params["poll"],
|
||||
in_reply_to_id: params["in_reply_to_id"]
|
||||
}
|
||||
|
||||
data =
|
||||
if media_ids = params["media_ids"] do
|
||||
Map.put(data, :media_ids, media_ids)
|
||||
else
|
||||
data
|
||||
end
|
||||
|
||||
data
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue