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)
activity.id in actor.pinned_activities
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

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)
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
|> cast(params, [:pinned_activities])
|> validate_length(:pinned_activities,
@ -2327,9 +2332,19 @@ def add_pinnned_activity(user, %Pleroma.Activity{id: id}) do
|> update_and_set_cache()
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)}
# 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
|> cast(params, [:pinned_activities])
|> update_and_set_cache()

View file

@ -31,18 +31,8 @@ def enqueue(args) do
@impl true
def perform(%Oban.Job{args: %{"activity_id" => id}}) do
with %Activity{} = activity <- find_activity(id),
%Pleroma.User{} = user <- find_user(activity.object.data["actor"]),
false <- pinned_by_actor?(activity, user) do
%Pleroma.User{} = user <- find_user(activity.object.data["actor"]) do
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
@ -74,12 +64,6 @@ defp find_user(ap_id) do
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
from(j in Oban.Job,
where: j.state == "scheduled",

View file

@ -115,8 +115,7 @@ test "posting a status", %{conn: conn} do
"expires_in" => expires_in
})
assert fourth_response =
%{"id" => fourth_id} = json_response_and_validate_schema(conn_four, 200)
assert %{"id" => fourth_id} = json_response_and_validate_schema(conn_four, 200)
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")
|> json_response_and_validate_schema(400)
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
describe "cards" do

View file

@ -44,25 +44,4 @@ test "enqueue job" do
assert %Oban.Job{} = Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
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