Compare commits
1 Commits
feature/sa
...
issue/2315
Author | SHA1 | Date | |
---|---|---|---|
|
572e03c0cc |
@ -553,7 +553,8 @@ config :pleroma, Oban,
|
||||
remote_fetcher: 2,
|
||||
attachments_cleanup: 5,
|
||||
new_users_digest: 1,
|
||||
mute_expire: 5
|
||||
mute_expire: 5,
|
||||
poll_expiration_notify: 1
|
||||
],
|
||||
plugins: [Oban.Plugins.Pruner],
|
||||
crontab: [
|
||||
|
@ -368,7 +368,7 @@ defmodule Pleroma.Notification do
|
||||
end
|
||||
|
||||
def create_notifications(%Activity{data: %{"type" => type}} = activity, options)
|
||||
when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag"] do
|
||||
when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag", "ClosePoll"] do
|
||||
do_create_notifications(activity, options)
|
||||
end
|
||||
|
||||
@ -418,9 +418,11 @@ defmodule Pleroma.Notification do
|
||||
"EmojiReaction" ->
|
||||
"pleroma:emoji_reaction"
|
||||
|
||||
"ClosePoll" ->
|
||||
"poll"
|
||||
|
||||
"Create" ->
|
||||
activity
|
||||
|> type_from_activity_object()
|
||||
type_from_activity_object(activity)
|
||||
|
||||
t ->
|
||||
raise "No notification type for activity type #{t}"
|
||||
@ -471,7 +473,16 @@ defmodule Pleroma.Notification do
|
||||
def get_notified_from_activity(activity, local_only \\ true)
|
||||
|
||||
def get_notified_from_activity(%Activity{data: %{"type" => type}} = activity, local_only)
|
||||
when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact", "Flag"] do
|
||||
when type in [
|
||||
"Create",
|
||||
"Like",
|
||||
"Announce",
|
||||
"Follow",
|
||||
"Move",
|
||||
"EmojiReact",
|
||||
"Flag",
|
||||
"ClosePoll"
|
||||
] do
|
||||
potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity)
|
||||
|
||||
potential_receivers =
|
||||
@ -511,6 +522,10 @@ defmodule Pleroma.Notification do
|
||||
User.all_superusers() |> Enum.map(fn user -> user.ap_id end)
|
||||
end
|
||||
|
||||
def get_potential_receiver_ap_ids(%{data: %{"type" => "ClosePoll"}}) do
|
||||
[]
|
||||
end
|
||||
|
||||
def get_potential_receiver_ap_ids(activity) do
|
||||
[]
|
||||
|> Utils.maybe_notify_to_recipients(activity)
|
||||
|
@ -65,6 +65,15 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
||||
end
|
||||
end
|
||||
|
||||
def close_poll(_activity, object) do
|
||||
{:ok,
|
||||
%{
|
||||
"id" => Utils.generate_activity_id(),
|
||||
"type" => "ClosePoll",
|
||||
"object" => object.data["id"]
|
||||
}, []}
|
||||
end
|
||||
|
||||
@spec undo(User.t(), Activity.t()) :: {:ok, map(), keyword()}
|
||||
def undo(actor, object) do
|
||||
{:ok,
|
||||
|
@ -21,6 +21,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ClosePollValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator
|
||||
@ -151,6 +152,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
||||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => "ClosePoll"} = object, meta) do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|> ClosePollValidator.cast_and_validate()
|
||||
|> Ecto.Changeset.apply_action(:insert) do
|
||||
object = stringify_keys(object)
|
||||
{:ok, object, meta}
|
||||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => type} = object, meta) when type in ~w[Audio Video] do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|
@ -0,0 +1,41 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.ClosePollValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
data
|
||||
|> cast_data()
|
||||
|> validate_data()
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
%__MODULE__{}
|
||||
|> changeset(data)
|
||||
end
|
||||
|
||||
def changeset(struct, data) do
|
||||
struct
|
||||
|> cast(data, __schema__(:fields))
|
||||
end
|
||||
|
||||
def validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["ClosePoll"])
|
||||
|> validate_required([:id, :type, :object])
|
||||
end
|
||||
end
|
@ -245,6 +245,14 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
||||
end
|
||||
|
||||
# Tasks this handles:
|
||||
# - Set up notification on close poll
|
||||
def handle(%{data: %{"type" => "ClosePoll"}} = object, meta) do
|
||||
Notification.create_notifications(object)
|
||||
|
||||
{:ok, object, meta}
|
||||
end
|
||||
|
||||
# Tasks this handles:
|
||||
# - Delete and unpins the create activity
|
||||
# - Replace object with Tombstone
|
||||
# - Set up notification
|
||||
|
@ -264,6 +264,18 @@ defmodule Pleroma.Web.CommonAPI do
|
||||
end
|
||||
end
|
||||
|
||||
# postprocess the close poll
|
||||
#
|
||||
def close_poll(activity_id) do
|
||||
with %Activity{} = activity <- Activity.get_by_id(activity_id),
|
||||
%Object{} = object <- Object.normalize(activity),
|
||||
{:ok, poll, _} <- Builder.close_poll(activity, object),
|
||||
meta <- [local: true, do_not_federate: true],
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(poll, meta) do
|
||||
{:ok, activity}
|
||||
end
|
||||
end
|
||||
|
||||
def react_with_emoji(id, user, emoji) do
|
||||
with %Activity{} = activity <- Activity.get_by_id(id),
|
||||
object <- Object.normalize(activity),
|
||||
@ -411,6 +423,25 @@ defmodule Pleroma.Web.CommonAPI do
|
||||
end
|
||||
end
|
||||
|
||||
def postprocess(%Activity{} = activity) do
|
||||
case Object.normalize(activity) do
|
||||
%Object{data: %{"type" => "Question", "closed" => closed_at}} ->
|
||||
Pleroma.Workers.PollExpirationNotify.enqueue(%{
|
||||
activity_id: activity.id,
|
||||
closed_at:
|
||||
Timex.shift(
|
||||
Timex.parse!(closed_at, "{ISO:Extended:Z}"),
|
||||
minutes: 1
|
||||
)
|
||||
})
|
||||
|
||||
_ ->
|
||||
activity
|
||||
end
|
||||
|
||||
activity
|
||||
end
|
||||
|
||||
def pin(id, %{ap_id: user_ap_id} = user) do
|
||||
with %Activity{
|
||||
actor: ^user_ap_id,
|
||||
|
@ -164,7 +164,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||
def create(%{assigns: %{user: user}, body_params: %{status: _} = params} = conn, _) do
|
||||
params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
|
||||
|
||||
with {:ok, activity} <- CommonAPI.post(user, params) do
|
||||
with {:ok, activity} <- CommonAPI.post(user, params),
|
||||
_ <- CommonAPI.postprocess(activity) do
|
||||
try_render(conn, "show.json",
|
||||
activity: activity,
|
||||
for: user,
|
||||
|
25
lib/pleroma/workers/poll_expiration_notify.ex
Normal file
25
lib/pleroma/workers/poll_expiration_notify.ex
Normal file
@ -0,0 +1,25 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Workers.PollExpirationNotify do
|
||||
@moduledoc false
|
||||
|
||||
use Oban.Worker, queue: :poll_expiration_notify, max_attempts: 1
|
||||
|
||||
def enqueue(args) do
|
||||
{scheduled_at, args} = Map.pop(args, :closed_at)
|
||||
|
||||
args
|
||||
|> __MODULE__.new(scheduled_at: scheduled_at)
|
||||
|> Oban.insert()
|
||||
end
|
||||
|
||||
@impl true
|
||||
def perform(%Oban.Job{args: %{"activity_id" => activity_id}}) do
|
||||
Pleroma.Web.CommonAPI.close_poll(activity_id)
|
||||
:ok
|
||||
end
|
||||
|
||||
def perform(_), do: :ok
|
||||
end
|
Loading…
Reference in New Issue
Block a user