2020-05-12 19:59:26 +00:00
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.StatusOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.AccountOperation
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus
alias Pleroma.Web.ApiSpec.Schemas.Status
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
import Pleroma.Web.ApiSpec.Helpers
def open_api_operation ( action ) do
operation = String . to_existing_atom ( " #{ action } _operation " )
apply ( __MODULE__ , operation , [ ] )
end
def index_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Get multiple statuses by IDs " ,
security : [ %{ " oAuth " = > [ " read:statuses " ] } ] ,
parameters : [
Operation . parameter (
:ids ,
:query ,
% Schema { type : :array , items : FlakeID } ,
2020-05-12 21:09:26 +00:00
" Array of status IDs "
2020-05-12 19:59:26 +00:00
)
] ,
operationId : " StatusController.index " ,
responses : %{
200 = > Operation . response ( " Array of Status " , " application/json " , array_of_statuses ( ) )
}
}
end
def create_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Publish new status " ,
security : [ %{ " oAuth " = > [ " write:statuses " ] } ] ,
description : " Post a new status " ,
operationId : " StatusController.create " ,
requestBody : request_body ( " Parameters " , create_request ( ) , required : true ) ,
responses : %{
200 = >
Operation . response (
" Status. When `scheduled_at` is present, ScheduledStatus is returned instead " ,
" application/json " ,
% Schema { oneOf : [ Status , ScheduledStatus ] }
) ,
422 = > Operation . response ( " Bad Request " , " application/json " , ApiError )
}
}
end
def show_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " View specific status " ,
description : " View information about a status " ,
operationId : " StatusController.show " ,
security : [ %{ " oAuth " = > [ " read:statuses " ] } ] ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def delete_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Delete status " ,
security : [ %{ " oAuth " = > [ " write:statuses " ] } ] ,
description : " Delete one of your own statuses " ,
operationId : " StatusController.delete " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > empty_object_response ( ) ,
403 = > Operation . response ( " Forbidden " , " application/json " , ApiError ) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def reblog_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Boost " ,
security : [ %{ " oAuth " = > [ " write:statuses " ] } ] ,
2020-05-12 21:12:22 +00:00
description : " Share a status " ,
2020-05-12 19:59:26 +00:00
operationId : " StatusController.reblog " ,
parameters : [ id_param ( ) ] ,
requestBody :
request_body ( " Parameters " , % Schema {
type : :object ,
properties : %{
visibility : % Schema { allOf : [ VisibilityScope ] , default : " public " }
}
} ) ,
responses : %{
200 = > status_response ( ) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def unreblog_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Undo boost " ,
security : [ %{ " oAuth " = > [ " write:statuses " ] } ] ,
description : " Undo a reshare of a status " ,
operationId : " StatusController.unreblog " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def favourite_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Favourite " ,
security : [ %{ " oAuth " = > [ " write:favourites " ] } ] ,
description : " Add a status to your favourites list " ,
operationId : " StatusController.favourite " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def unfavourite_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Undo favourite " ,
security : [ %{ " oAuth " = > [ " write:favourites " ] } ] ,
description : " Remove a status from your favourites list " ,
operationId : " StatusController.unfavourite " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def pin_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Pin to profile " ,
security : [ %{ " oAuth " = > [ " write:accounts " ] } ] ,
description : " Feature one of your own public statuses at the top of your profile " ,
operationId : " StatusController.pin " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
400 = > Operation . response ( " Error " , " application/json " , ApiError )
}
}
end
def unpin_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Unpin to profile " ,
security : [ %{ " oAuth " = > [ " write:accounts " ] } ] ,
description : " Unfeature a status from the top of your profile " ,
operationId : " StatusController.unpin " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
400 = > Operation . response ( " Error " , " application/json " , ApiError )
}
}
end
def bookmark_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Bookmark " ,
security : [ %{ " oAuth " = > [ " write:bookmarks " ] } ] ,
description : " Privately bookmark a status " ,
operationId : " StatusController.bookmark " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( )
}
}
end
def unbookmark_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Undo bookmark " ,
security : [ %{ " oAuth " = > [ " write:bookmarks " ] } ] ,
description : " Remove a status from your private bookmarks " ,
operationId : " StatusController.unbookmark " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( )
}
}
end
def mute_conversation_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Mute conversation " ,
security : [ %{ " oAuth " = > [ " write:mutes " ] } ] ,
description :
" Do not receive notifications for the thread that this status is part of. Must be a thread in which you are a participant. " ,
operationId : " StatusController.mute_conversation " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
400 = > Operation . response ( " Error " , " application/json " , ApiError )
}
}
end
def unmute_conversation_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Unmute conversation " ,
security : [ %{ " oAuth " = > [ " write:mutes " ] } ] ,
description :
" Start receiving notifications again for the thread that this status is part of " ,
operationId : " StatusController.unmute_conversation " ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > status_response ( ) ,
400 = > Operation . response ( " Error " , " application/json " , ApiError )
}
}
end
def card_operation do
% Operation {
tags : [ " Statuses " ] ,
deprecated : true ,
summary : " Preview card " ,
description : " Deprecated in favor of card property inlined on Status entity " ,
operationId : " StatusController.card " ,
parameters : [ id_param ( ) ] ,
security : [ %{ " oAuth " = > [ " read:statuses " ] } ] ,
responses : %{
200 = >
Operation . response ( " Card " , " application/json " , % Schema {
type : :object ,
nullable : true ,
properties : %{
type : % Schema { type : :string , enum : [ " link " , " photo " , " video " , " rich " ] } ,
provider_name : % Schema { type : :string , nullable : true } ,
provider_url : % Schema { type : :string , format : :uri } ,
url : % Schema { type : :string , format : :uri } ,
image : % Schema { type : :string , nullable : true , format : :uri } ,
title : % Schema { type : :string } ,
description : % Schema { type : :string }
}
} )
}
}
end
def favourited_by_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Favourited by " ,
description : " View who favourited a given status " ,
operationId : " StatusController.favourited_by " ,
security : [ %{ " oAuth " = > [ " read:accounts " ] } ] ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = >
Operation . response (
" Array of Accounts " ,
" application/json " ,
AccountOperation . array_of_accounts ( )
) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def reblogged_by_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Boosted by " ,
description : " View who boosted a given status " ,
operationId : " StatusController.reblogged_by " ,
security : [ %{ " oAuth " = > [ " read:accounts " ] } ] ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = >
Operation . response (
" Array of Accounts " ,
" application/json " ,
AccountOperation . array_of_accounts ( )
) ,
404 = > Operation . response ( " Not Found " , " application/json " , ApiError )
}
}
end
def context_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Parent and child statuses " ,
description : " View statuses above and below this status in the thread " ,
operationId : " StatusController.context " ,
security : [ %{ " oAuth " = > [ " read:statuses " ] } ] ,
parameters : [ id_param ( ) ] ,
responses : %{
200 = > Operation . response ( " Context " , " application/json " , context ( ) )
}
}
end
def favourites_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Favourited statuses " ,
description : " Statuses the user has favourited " ,
operationId : " StatusController.favourites " ,
parameters : pagination_params ( ) ,
security : [ %{ " oAuth " = > [ " read:favourites " ] } ] ,
responses : %{
200 = > Operation . response ( " Array of Statuses " , " application/json " , array_of_statuses ( ) )
}
}
end
def bookmarks_operation do
% Operation {
tags : [ " Statuses " ] ,
summary : " Bookmarked statuses " ,
description : " Statuses the user has bookmarked " ,
operationId : " StatusController.bookmarks " ,
parameters : [
Operation . parameter ( :with_relationships , :query , BooleanLike , " Include relationships " )
| pagination_params ( )
] ,
security : [ %{ " oAuth " = > [ " read:bookmarks " ] } ] ,
responses : %{
200 = > Operation . response ( " Array of Statuses " , " application/json " , array_of_statuses ( ) )
}
}
end
defp array_of_statuses do
% Schema { type : :array , items : Status , example : [ Status . schema ( ) . example ] }
end
defp create_request do
% Schema {
title : " StatusCreateRequest " ,
type : :object ,
properties : %{
status : % Schema {
type : :string ,
description :
" Text content of the status. If `media_ids` is provided, this becomes optional. Attaching a `poll` is optional while `status` is provided. "
} ,
media_ids : % Schema {
type : :array ,
items : % Schema { type : :string } ,
description :
" Array of Attachment ids to be attached as media. If provided, `status` becomes optional, and `poll` cannot be used. "
} ,
poll : % Schema {
type : :object ,
required : [ :options ] ,
properties : %{
options : % Schema {
type : :array ,
items : % Schema { type : :string } ,
description :
" Array of possible answers. If provided, `media_ids` cannot be used, and `poll[expires_in]` must be provided. "
} ,
expires_in : % Schema {
type : :integer ,
description :
" Duration the poll should be open, in seconds. If provided, `media_ids` cannot be used, and `poll[options]` must be provided. "
} ,
multiple : % Schema { type : :boolean , description : " Allow multiple choices? " } ,
hide_totals : % Schema {
type : :boolean ,
description : " Hide vote counts until the poll ends? "
}
}
} ,
in_reply_to_id : % Schema {
allOf : [ FlakeID ] ,
description : " ID of the status being replied to, if status is a reply "
} ,
sensitive : % Schema {
type : :boolean ,
description : " Mark status and attached media as sensitive? "
} ,
spoiler_text : % Schema {
type : :string ,
description :
" Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field. "
} ,
scheduled_at : % Schema {
type : :string ,
format : :" date-time " ,
nullable : true ,
description :
" ISO 8601 Datetime at which to schedule a status. Providing this paramter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future. "
} ,
language : % Schema { type : :string , description : " ISO 639 language code for this status. " } ,
# Pleroma-specific properties:
preview : % Schema {
type : :boolean ,
description :
" If set to `true` the post won't be actually posted, but the status entitiy would still be rendered back. This could be useful for previewing rich text/custom emoji, for example "
} ,
content_type : % Schema {
type : :string ,
description :
" The MIME type of the status, it is transformed into HTML by the backend. You can get the list of the supported MIME types with the nodeinfo endpoint. "
} ,
to : % Schema {
type : :array ,
items : % Schema { type : :string } ,
description :
" A list of nicknames (like `lain@soykaf.club` or `lain` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for for post visibility are not affected by this and will still apply "
} ,
visibility : % Schema {
anyOf : [
VisibilityScope ,
% Schema { type : :string , description : " `list:LIST_ID` " , example : " LIST:123 " }
] ,
description :
" Visibility of the posted status. Besides standard MastoAPI values (`direct`, `private`, `unlisted` or `public`) it can be used to address a List by setting it to `list:LIST_ID` "
} ,
expires_in : % Schema {
type : :integer ,
description :
" The number of seconds the posted activity should expire in. When a posted activity expires it will be deleted from the server, and a delete request for it will be federated. This needs to be longer than an hour. "
} ,
in_reply_to_conversation_id : % Schema {
type : :string ,
description :
" Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`. "
}
} ,
example : %{
" status " = > " What time is it? " ,
" sensitive " = > " false " ,
" poll " = > %{
" options " = > [ " Cofe " , " Adventure " ] ,
" expires_in " = > 420
}
}
}
end
defp id_param do
Operation . parameter ( :id , :path , FlakeID , " Status ID " ,
example : " 9umDrYheeY451cQnEe " ,
required : true
)
end
defp status_response do
Operation . response ( " Status " , " application/json " , Status )
end
defp context do
% Schema {
title : " StatusContext " ,
description :
" Represents the tree around a given status. Used for reconstructing threads of statuses. " ,
type : :object ,
required : [ :ancestors , :descendants ] ,
properties : %{
ancestors : array_of_statuses ( ) ,
descendants : array_of_statuses ( )
} ,
example : %{
" ancestors " = > [ Status . schema ( ) . example ] ,
" descendants " = > [ Status . schema ( ) . example ]
}
}
end
end