event editing?
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
daccdc179c
commit
f7d9f42243
7 changed files with 170 additions and 18 deletions
|
@ -34,6 +34,23 @@ def create_operation do
|
|||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Event actions"],
|
||||
summary: "Update event",
|
||||
description: "Change the content of an event",
|
||||
operationId: "PleromaAPI.EventController.update",
|
||||
security: [%{"oAuth" => ["write"]}],
|
||||
parameters: [id_param()],
|
||||
requestBody: request_body("Parameters", update_request(), required: true),
|
||||
responses: %{
|
||||
200 => event_response(),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def participations_operation do
|
||||
%Operation{
|
||||
tags: ["Event actions"],
|
||||
|
@ -217,6 +234,50 @@ defp create_request do
|
|||
}
|
||||
end
|
||||
|
||||
defp update_request do
|
||||
%Schema{
|
||||
title: "EventUpdateRequest",
|
||||
type: :object,
|
||||
properties: %{
|
||||
name: %Schema{
|
||||
type: :string,
|
||||
description: "Name of the event."
|
||||
},
|
||||
status: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Text description of the event."
|
||||
},
|
||||
banner_id: %Schema{
|
||||
nullable: true,
|
||||
type: :string,
|
||||
description: "Attachment id to be attached as banner."
|
||||
},
|
||||
start_time: %Schema{
|
||||
type: :string,
|
||||
format: :"date-time",
|
||||
description: "Start time."
|
||||
},
|
||||
end_time: %Schema{
|
||||
type: :string,
|
||||
format: :"date-time",
|
||||
description: "End time."
|
||||
},
|
||||
location_id: %Schema{
|
||||
type: :string,
|
||||
description: "Location ID from geospatial provider",
|
||||
nullable: true
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"name" => "Updated event",
|
||||
"status" => "We had to reschedule the event.",
|
||||
"start_time" => "2022-02-22T22:00:00.000Z",
|
||||
"end_time" => "2022-02-22T23:00:00.000Z"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp event_response do
|
||||
Operation.response(
|
||||
"Status",
|
||||
|
|
|
@ -743,4 +743,39 @@ def event(user, data, location \\ nil) do
|
|||
ActivityPub.create(draft.changes)
|
||||
end
|
||||
end
|
||||
|
||||
def update_event(user, orig_activity, changes) do
|
||||
with orig_object <- Object.normalize(orig_activity),
|
||||
{:ok, new_object} <- make_update_event_data(user, orig_object, changes),
|
||||
{:ok, update_data, _} <- Builder.update(user, new_object),
|
||||
{:ok, update, _} <- Pipeline.common_pipeline(update_data, local: true) do
|
||||
{:ok, update}
|
||||
else
|
||||
_ -> {:error, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp make_update_event_data(user, orig_object, changes) do
|
||||
kept_params = %{
|
||||
visibility: Visibility.get_visibility(orig_object),
|
||||
in_reply_to_id:
|
||||
with replied_id when is_binary(replied_id) <- orig_object.data["inReplyTo"],
|
||||
%Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(replied_id) do
|
||||
activity_id
|
||||
else
|
||||
_ -> nil
|
||||
end
|
||||
}
|
||||
|
||||
params = Map.merge(changes, kept_params)
|
||||
|
||||
with {:ok, draft} <- ActivityDraft.event(user, params) do
|
||||
change =
|
||||
Object.Updater.make_update_object_data(orig_object.data, draft.object, Utils.make_date())
|
||||
|
||||
{:ok, change}
|
||||
else
|
||||
_ -> {:error, nil}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -135,7 +135,13 @@ defp event_object(draft) do
|
|||
"location_id" => draft.location_id,
|
||||
"location_provider" => draft.location_provider,
|
||||
"startTime" => draft.start_time,
|
||||
"endTime" => draft.end_time
|
||||
"endTime" => draft.end_time,
|
||||
"source" => %{
|
||||
"content" => draft.status,
|
||||
"mediaType" => Utils.get_content_type(draft.params[:content_type])
|
||||
},
|
||||
"generator" => draft.params[:generator],
|
||||
"content_type" => draft.params[:content_type],
|
||||
}
|
||||
|
||||
%__MODULE__{draft | object: object}
|
||||
|
|
|
@ -21,7 +21,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
|||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Web.Plugs.RateLimiter
|
||||
|
||||
|
@ -101,6 +100,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
|||
|
||||
plug(RateLimiter, [name: :statuses_actions] when action in @rate_limited_status_actions)
|
||||
|
||||
plug(Pleroma.Web.Plugs.SetApplicationPlug, [] when action in [:create, :update])
|
||||
|
||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.StatusOperation
|
||||
|
@ -140,8 +141,9 @@ def create(
|
|||
)
|
||||
when not is_nil(scheduled_at) do
|
||||
params =
|
||||
Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
|
||||
|> put_application(conn)
|
||||
params
|
||||
|> Map.put(:in_reply_to_status_id, params[:in_reply_to_id])
|
||||
|> Map.put(:application, conn.assigns.application)
|
||||
|
||||
attrs = %{
|
||||
params: Map.new(params, fn {key, value} -> {to_string(key), value} end),
|
||||
|
@ -166,8 +168,9 @@ def create(
|
|||
# Creates a regular status
|
||||
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])
|
||||
|> put_application(conn)
|
||||
params
|
||||
|> Map.put(:in_reply_to_status_id, params[:in_reply_to_id])
|
||||
|> Map.put(:application, conn.assigns.application)
|
||||
|
||||
with {:ok, activity} <- CommonAPI.post(user, params) do
|
||||
try_render(conn, "show.json",
|
||||
|
@ -231,7 +234,7 @@ def update(%{assigns: %{user: user}, body_params: body_params} = conn, %{id: id}
|
|||
{_, true} <- {:is_create, activity.data["type"] == "Create"},
|
||||
actor <- Activity.user_actor(activity),
|
||||
{_, true} <- {:own_status, actor.id == user.id},
|
||||
changes <- body_params |> put_application(conn),
|
||||
changes <- body_params |> Map.put(:application, conn.assigns.application),
|
||||
{_, {:ok, _update_activity}} <- {:pipeline, CommonAPI.update(user, activity, changes)},
|
||||
{_, %Activity{}} = {_, activity} <- {:refetched, Activity.get_by_id_with_object(id)} do
|
||||
try_render(conn, "show.json",
|
||||
|
@ -484,15 +487,4 @@ def bookmarks(%{assigns: %{user: user}} = conn, params) do
|
|||
as: :activity
|
||||
)
|
||||
end
|
||||
|
||||
defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do
|
||||
if user.disclose_client do
|
||||
%{client_name: client_name, website: website} = Repo.preload(token, :app).app
|
||||
Map.put(params, :generator, %{type: "Application", name: client_name, url: website})
|
||||
else
|
||||
Map.put(params, :generator, nil)
|
||||
end
|
||||
end
|
||||
|
||||
defp put_application(params, _), do: Map.put(params, :generator, nil)
|
||||
end
|
||||
|
|
|
@ -48,6 +48,7 @@ defmodule Pleroma.Web.PleromaAPI.EventController do
|
|||
%{scopes: ["write"]}
|
||||
when action in [
|
||||
:create,
|
||||
:update,
|
||||
:authorize_participation_request,
|
||||
:reject_participation_request,
|
||||
:join,
|
||||
|
@ -67,6 +68,8 @@ defmodule Pleroma.Web.PleromaAPI.EventController do
|
|||
when action in [:export_ics]
|
||||
)
|
||||
|
||||
plug(Pleroma.Web.Plugs.SetApplicationPlug, [] when action in [:create, :update])
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaEventOperation
|
||||
|
||||
def create(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
||||
|
@ -96,6 +99,32 @@ def create(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
|||
end
|
||||
end
|
||||
|
||||
@doc "PUT /api/v1/statuses/:id"
|
||||
def update(%{assigns: %{user: user}, body_params: body_params} = conn, %{id: id} = params) do
|
||||
with {_, %Activity{}} = {_, activity} <- {:activity, Activity.get_by_id_with_object(id)},
|
||||
{_, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
|
||||
{_, true} <- {:is_create, activity.data["type"] == "Create"},
|
||||
actor <- Activity.user_actor(activity),
|
||||
{_, true} <- {:own_status, actor.id == user.id},
|
||||
changes <- body_params |> Map.put(:application, conn.assigns.application),
|
||||
{_, {:ok, _update_activity}} <-
|
||||
{:pipeline, CommonAPI.update_event(user, activity, changes)},
|
||||
{_, %Activity{}} = {_, activity} <- {:refetched, Activity.get_by_id_with_object(id)} do
|
||||
conn
|
||||
|> put_view(StatusView)
|
||||
|> try_render("show.json",
|
||||
activity: activity,
|
||||
for: user,
|
||||
with_direct_conversation_id: true,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
else
|
||||
{:own_status, _} -> {:error, :forbidden}
|
||||
{:pipeline, e} -> {:error, :internal_server_error}
|
||||
_ -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_location(%{location_id: location_id}) when is_binary(location_id) do
|
||||
result = Geospatial.Service.service().get_by_id(location_id)
|
||||
|
||||
|
|
28
lib/pleroma/web/plugs/set_application_plug.ex
Normal file
28
lib/pleroma/web/plugs/set_application_plug.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.SetApplicationPlug do
|
||||
import Plug.Conn, only: [assign: 3]
|
||||
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
|
||||
def init(_), do: nil
|
||||
|
||||
def call(conn, _) do
|
||||
assign(conn, :application, get_application(conn))
|
||||
end
|
||||
|
||||
defp get_application(%{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do
|
||||
if user.disclose_client do
|
||||
%{client_name: client_name, website: website} = Repo.preload(token, :app).app
|
||||
%{type: "Application", name: client_name, url: website}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
defp get_application(_), do: nil
|
||||
end
|
|
@ -488,6 +488,7 @@ defmodule Pleroma.Web.Router do
|
|||
post("/backups", BackupController, :create)
|
||||
|
||||
post("/events", EventController, :create)
|
||||
put("/events/:id", EventController, :update)
|
||||
get("/events/:id/participations", EventController, :participations)
|
||||
get("/events/:id/participation_requests", EventController, :participation_requests)
|
||||
|
||||
|
|
Loading…
Reference in a new issue