pin/unpin for activities with expires_at option

This commit is contained in:
Alexander Strizhakov 2020-09-04 11:40:32 +03:00 committed by rinpatch
parent b3485a6dbf
commit eb5ff715f7
5 changed files with 64 additions and 46 deletions

View File

@ -343,9 +343,4 @@ def pinned_by_actor?(%Activity{} = activity) do
actor = user_actor(activity) actor = user_actor(activity)
activity.id in actor.pinned_activities activity.id in actor.pinned_activities
end end
@spec pinned_by_actor?(Activity.t(), User.t()) :: boolean()
def pinned_by_actor?(%Activity{id: id}, %User{} = user) do
id in user.pinned_activities
end
end end

View File

@ -2315,6 +2315,11 @@ def add_pinnned_activity(user, %Pleroma.Activity{id: id}) do
max_pinned_statuses = Config.get([:instance, :max_pinned_statuses], 0) max_pinned_statuses = Config.get([:instance, :max_pinned_statuses], 0)
params = %{pinned_activities: user.pinned_activities ++ [id]} params = %{pinned_activities: user.pinned_activities ++ [id]}
# if pinned activity was scheduled for deletion, we remove job
if expiration = Pleroma.Workers.PurgeExpiredActivity.get_expiration(id) do
Oban.cancel_job(expiration.id)
end
user user
|> cast(params, [:pinned_activities]) |> cast(params, [:pinned_activities])
|> validate_length(:pinned_activities, |> validate_length(:pinned_activities,
@ -2327,9 +2332,19 @@ def add_pinnned_activity(user, %Pleroma.Activity{id: id}) do
|> update_and_set_cache() |> update_and_set_cache()
end end
def remove_pinnned_activity(user, %Pleroma.Activity{id: id}) do def remove_pinnned_activity(user, %Pleroma.Activity{id: id, data: data}) do
params = %{pinned_activities: List.delete(user.pinned_activities, id)} params = %{pinned_activities: List.delete(user.pinned_activities, id)}
# if pinned activity was scheduled for deletion, we reschedule it for deletion
if data["expires_at"] do
{:ok, expires_at, _} = DateTime.from_iso8601(data["expires_at"])
Pleroma.Workers.PurgeExpiredActivity.enqueue(%{
activity_id: id,
expires_at: expires_at
})
end
user user
|> cast(params, [:pinned_activities]) |> cast(params, [:pinned_activities])
|> update_and_set_cache() |> update_and_set_cache()

View File

@ -31,18 +31,8 @@ def enqueue(args) do
@impl true @impl true
def perform(%Oban.Job{args: %{"activity_id" => id}}) do def perform(%Oban.Job{args: %{"activity_id" => id}}) do
with %Activity{} = activity <- find_activity(id), with %Activity{} = activity <- find_activity(id),
%Pleroma.User{} = user <- find_user(activity.object.data["actor"]), %Pleroma.User{} = user <- find_user(activity.object.data["actor"]) do
false <- pinned_by_actor?(activity, user) do
Pleroma.Web.CommonAPI.delete(activity.id, user) Pleroma.Web.CommonAPI.delete(activity.id, user)
else
:pinned_by_actor ->
# if activity is pinned, schedule deletion on next day
enqueue(%{activity_id: id, expires_at: DateTime.add(DateTime.utc_now(), 24 * 3600)})
:ok
error ->
error
end end
end end
@ -74,12 +64,6 @@ defp find_user(ap_id) do
end end
end end
defp pinned_by_actor?(activity, user) do
with true <- Activity.pinned_by_actor?(activity, user) do
:pinned_by_actor
end
end
def get_expiration(id) do def get_expiration(id) do
from(j in Oban.Job, from(j in Oban.Job,
where: j.state == "scheduled", where: j.state == "scheduled",

View File

@ -115,8 +115,7 @@ test "posting a status", %{conn: conn} do
"expires_in" => expires_in "expires_in" => expires_in
}) })
assert fourth_response = assert %{"id" => fourth_id} = json_response_and_validate_schema(conn_four, 200)
%{"id" => fourth_id} = json_response_and_validate_schema(conn_four, 200)
assert Activity.get_by_id(fourth_id) assert Activity.get_by_id(fourth_id)
@ -1142,6 +1141,52 @@ test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do
|> post("/api/v1/statuses/#{activity_two.id}/pin") |> post("/api/v1/statuses/#{activity_two.id}/pin")
|> json_response_and_validate_schema(400) |> json_response_and_validate_schema(400)
end end
test "on pin removes deletion job, on unpin reschedule deletion" do
%{conn: conn} = oauth_access(["write:accounts", "write:statuses"])
expires_in = 2 * 60 * 60
expires_at = DateTime.add(DateTime.utc_now(), expires_in)
assert %{"id" => id} =
conn
|> put_req_header("content-type", "application/json")
|> post("api/v1/statuses", %{
"status" => "oolong",
"expires_in" => expires_in
})
|> json_response_and_validate_schema(200)
assert_enqueued(
worker: Pleroma.Workers.PurgeExpiredActivity,
args: %{activity_id: id},
scheduled_at: expires_at
)
assert %{"id" => ^id, "pinned" => true} =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/statuses/#{id}/pin")
|> json_response_and_validate_schema(200)
refute_enqueued(
worker: Pleroma.Workers.PurgeExpiredActivity,
args: %{activity_id: id},
scheduled_at: expires_at
)
assert %{"id" => ^id, "pinned" => false} =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/statuses/#{id}/unpin")
|> json_response_and_validate_schema(200)
assert_enqueued(
worker: Pleroma.Workers.PurgeExpiredActivity,
args: %{activity_id: id},
scheduled_at: expires_at
)
end
end end
describe "cards" do describe "cards" do

View File

@ -44,25 +44,4 @@ test "enqueue job" do
assert %Oban.Job{} = Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id) assert %Oban.Job{} = Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
end end
test "don't delete pinned posts, schedule deletion on next day" do
activity = insert(:note_activity)
assert {:ok, _} =
PurgeExpiredActivity.enqueue(%{
activity_id: activity.id,
expires_at: DateTime.utc_now(),
validate: false
})
user = Pleroma.User.get_by_ap_id(activity.actor)
{:ok, activity} = Pleroma.Web.CommonAPI.pin(activity.id, user)
assert %{success: 1, failure: 0} ==
Oban.drain_queue(queue: :activity_expiration, with_scheduled: true)
job = Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
assert DateTime.diff(job.scheduled_at, DateTime.add(DateTime.utc_now(), 24 * 3600)) in [0, 1]
end
end end