Compare commits
1 Commits
feature/sa
...
issue/2315
Author | SHA1 | Date | |
---|---|---|---|
|
572e03c0cc |
@ -553,7 +553,8 @@ config :pleroma, Oban,
|
|||||||
remote_fetcher: 2,
|
remote_fetcher: 2,
|
||||||
attachments_cleanup: 5,
|
attachments_cleanup: 5,
|
||||||
new_users_digest: 1,
|
new_users_digest: 1,
|
||||||
mute_expire: 5
|
mute_expire: 5,
|
||||||
|
poll_expiration_notify: 1
|
||||||
],
|
],
|
||||||
plugins: [Oban.Plugins.Pruner],
|
plugins: [Oban.Plugins.Pruner],
|
||||||
crontab: [
|
crontab: [
|
||||||
|
@ -368,7 +368,7 @@ defmodule Pleroma.Notification do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_notifications(%Activity{data: %{"type" => type}} = activity, options)
|
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)
|
do_create_notifications(activity, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -418,9 +418,11 @@ defmodule Pleroma.Notification do
|
|||||||
"EmojiReaction" ->
|
"EmojiReaction" ->
|
||||||
"pleroma:emoji_reaction"
|
"pleroma:emoji_reaction"
|
||||||
|
|
||||||
|
"ClosePoll" ->
|
||||||
|
"poll"
|
||||||
|
|
||||||
"Create" ->
|
"Create" ->
|
||||||
activity
|
type_from_activity_object(activity)
|
||||||
|> type_from_activity_object()
|
|
||||||
|
|
||||||
t ->
|
t ->
|
||||||
raise "No notification type for activity type #{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, local_only \\ true)
|
||||||
|
|
||||||
def get_notified_from_activity(%Activity{data: %{"type" => type}} = activity, local_only)
|
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_receiver_ap_ids = get_potential_receiver_ap_ids(activity)
|
||||||
|
|
||||||
potential_receivers =
|
potential_receivers =
|
||||||
@ -511,6 +522,10 @@ defmodule Pleroma.Notification do
|
|||||||
User.all_superusers() |> Enum.map(fn user -> user.ap_id end)
|
User.all_superusers() |> Enum.map(fn user -> user.ap_id end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_potential_receiver_ap_ids(%{data: %{"type" => "ClosePoll"}}) do
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
def get_potential_receiver_ap_ids(activity) do
|
def get_potential_receiver_ap_ids(activity) do
|
||||||
[]
|
[]
|
||||||
|> Utils.maybe_notify_to_recipients(activity)
|
|> Utils.maybe_notify_to_recipients(activity)
|
||||||
|
@ -65,6 +65,15 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||||||
end
|
end
|
||||||
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()}
|
@spec undo(User.t(), Activity.t()) :: {:ok, map(), keyword()}
|
||||||
def undo(actor, object) do
|
def undo(actor, object) do
|
||||||
{:ok,
|
{:ok,
|
||||||
|
@ -21,6 +21,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectValidators.ClosePollValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator
|
||||||
@ -151,6 +152,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||||||
end
|
end
|
||||||
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
|
def validate(%{"type" => type} = object, meta) when type in ~w[Audio Video] do
|
||||||
with {:ok, object} <-
|
with {:ok, object} <-
|
||||||
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
|
end
|
||||||
|
|
||||||
# Tasks this handles:
|
# 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
|
# - Delete and unpins the create activity
|
||||||
# - Replace object with Tombstone
|
# - Replace object with Tombstone
|
||||||
# - Set up notification
|
# - Set up notification
|
||||||
|
@ -264,6 +264,18 @@ defmodule Pleroma.Web.CommonAPI do
|
|||||||
end
|
end
|
||||||
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
|
def react_with_emoji(id, user, emoji) do
|
||||||
with %Activity{} = activity <- Activity.get_by_id(id),
|
with %Activity{} = activity <- Activity.get_by_id(id),
|
||||||
object <- Object.normalize(activity),
|
object <- Object.normalize(activity),
|
||||||
@ -411,6 +423,25 @@ defmodule Pleroma.Web.CommonAPI do
|
|||||||
end
|
end
|
||||||
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
|
def pin(id, %{ap_id: user_ap_id} = user) do
|
||||||
with %Activity{
|
with %Activity{
|
||||||
actor: ^user_ap_id,
|
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
|
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])
|
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",
|
try_render(conn, "show.json",
|
||||||
activity: activity,
|
activity: activity,
|
||||||
for: user,
|
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