Compare commits
5 commits
4472808f20
...
a31bbe369c
Author | SHA1 | Date | |
---|---|---|---|
a31bbe369c | |||
0065e35399 | |||
8505d1f7ae | |||
795e344198 | |||
f3a5887cb9 |
7 changed files with 384 additions and 49 deletions
|
@ -1,8 +1,14 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
||||
)
|
||||
|
@ -31,12 +37,123 @@ func (g *Client) GetMediaAttachment(mediaAttachmentID string) (model.Attachment,
|
|||
return attachment, nil
|
||||
}
|
||||
|
||||
//type CreateMediaAttachmentForm struct {
|
||||
// Description string
|
||||
// Focus string
|
||||
// Filepath string
|
||||
//}
|
||||
//
|
||||
//func (g *Client) CreateMediaAttachment(form CreateMediaAttachmentForm) (model.Attachment, error) {
|
||||
// return model.Attachment{}, nil
|
||||
//}
|
||||
func (g *Client) CreateMediaAttachment(path, description, focus string) (model.Attachment, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return model.Attachment{}, fmt.Errorf("unable to open the file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// create the request body using a writer from the multipart package
|
||||
requestBody := bytes.Buffer{}
|
||||
requestBodyWriter := multipart.NewWriter(&requestBody)
|
||||
|
||||
filename := filepath.Base(path)
|
||||
|
||||
part, err := requestBodyWriter.CreateFormFile("file", filename)
|
||||
if err != nil {
|
||||
return model.Attachment{}, fmt.Errorf("unable to create the new part: %w", err)
|
||||
}
|
||||
|
||||
if _, err := io.Copy(part, file); err != nil {
|
||||
return model.Attachment{}, fmt.Errorf("unable to copy the file contents to the form: %w", err)
|
||||
}
|
||||
|
||||
// add the description
|
||||
if description != "" {
|
||||
descriptionFormFieldWriter, err := requestBodyWriter.CreateFormField("description")
|
||||
if err != nil {
|
||||
return model.Attachment{}, fmt.Errorf(
|
||||
"unable to create the writer for the 'description' form field: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
if _, err := io.WriteString(descriptionFormFieldWriter, description); err != nil {
|
||||
return model.Attachment{}, fmt.Errorf(
|
||||
"unable to write the description to the form: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// add the focus values
|
||||
if focus != "" {
|
||||
focusFormFieldWriter, err := requestBodyWriter.CreateFormField("focus")
|
||||
if err != nil {
|
||||
return model.Attachment{}, fmt.Errorf(
|
||||
"unable to create the writer for the 'focus' form field: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
if _, err := io.WriteString(focusFormFieldWriter, focus); err != nil {
|
||||
return model.Attachment{}, fmt.Errorf(
|
||||
"unable to write the focus values to the form: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if err := requestBodyWriter.Close(); err != nil {
|
||||
return model.Attachment{}, fmt.Errorf("unable to close the writer: %w", err)
|
||||
}
|
||||
|
||||
url := g.Authentication.Instance + baseMediaPath
|
||||
|
||||
var attachment model.Attachment
|
||||
|
||||
params := requestParameters{
|
||||
httpMethod: http.MethodPost,
|
||||
url: url,
|
||||
requestBody: &requestBody,
|
||||
contentType: requestBodyWriter.FormDataContentType(),
|
||||
output: &attachment,
|
||||
}
|
||||
|
||||
if err := g.sendRequest(params); err != nil {
|
||||
return model.Attachment{}, fmt.Errorf(
|
||||
"received an error after sending the request to create the media attachment: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
return attachment, nil
|
||||
}
|
||||
|
||||
func (g *Client) UpdateMediaAttachment(mediaAttachmentID, description, focus string) (model.Attachment, error) {
|
||||
form := struct {
|
||||
Description string `json:"description"`
|
||||
Focus string `json:"focus"`
|
||||
}{
|
||||
Description: description,
|
||||
Focus: focus,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(form)
|
||||
if err != nil {
|
||||
return model.Attachment{}, fmt.Errorf("unable to marshal the form: %w", err)
|
||||
}
|
||||
|
||||
requestBody := bytes.NewBuffer(data)
|
||||
url := g.Authentication.Instance + baseMediaPath + "/" + mediaAttachmentID
|
||||
|
||||
var updatedMediaAttachment model.Attachment
|
||||
|
||||
params := requestParameters{
|
||||
httpMethod: http.MethodPut,
|
||||
url: url,
|
||||
requestBody: requestBody,
|
||||
contentType: applicationJSON,
|
||||
output: &updatedMediaAttachment,
|
||||
}
|
||||
|
||||
if err := g.sendRequest(params); err != nil {
|
||||
return model.Attachment{}, fmt.Errorf(
|
||||
"received an error after sending the request to update the media attachment: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
return updatedMediaAttachment, nil
|
||||
}
|
||||
|
|
|
@ -38,18 +38,19 @@ func (g *Client) GetStatus(statusID string) (model.Status, error) {
|
|||
}
|
||||
|
||||
type CreateStatusForm struct {
|
||||
Content string `json:"status"`
|
||||
InReplyTo string `json:"in_reply_to_id"`
|
||||
Language string `json:"language"`
|
||||
SpoilerText string `json:"spoiler_text"`
|
||||
Boostable bool `json:"boostable"`
|
||||
Federated bool `json:"federated"`
|
||||
Likeable bool `json:"likeable"`
|
||||
Replyable bool `json:"replyable"`
|
||||
Sensitive bool `json:"sensitive"`
|
||||
Poll *CreateStatusPollForm `json:"poll,omitempty"`
|
||||
ContentType model.StatusContentType `json:"content_type"`
|
||||
Visibility model.StatusVisibility `json:"visibility"`
|
||||
Content string `json:"status"`
|
||||
InReplyTo string `json:"in_reply_to_id"`
|
||||
Language string `json:"language"`
|
||||
SpoilerText string `json:"spoiler_text"`
|
||||
Boostable bool `json:"boostable"`
|
||||
Federated bool `json:"federated"`
|
||||
Likeable bool `json:"likeable"`
|
||||
Replyable bool `json:"replyable"`
|
||||
Sensitive bool `json:"sensitive"`
|
||||
Poll *CreateStatusPollForm `json:"poll,omitempty"`
|
||||
ContentType model.StatusContentType `json:"content_type"`
|
||||
Visibility model.StatusVisibility `json:"visibility"`
|
||||
AttachmentIDs []string `json:"media_ids,omitempty"`
|
||||
}
|
||||
|
||||
type CreateStatusPollForm struct {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package executor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||
|
@ -19,8 +20,9 @@ func (c *CreateExecutor) Execute() error {
|
|||
}
|
||||
|
||||
funcMap := map[string]func(*client.Client) error{
|
||||
resourceList: c.createList,
|
||||
resourceStatus: c.createStatus,
|
||||
resourceList: c.createList,
|
||||
resourceStatus: c.createStatus,
|
||||
resourceMediaAttachment: c.createMediaAttachment,
|
||||
}
|
||||
|
||||
doFunc, ok := funcMap[c.resourceType]
|
||||
|
@ -66,6 +68,71 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
sensitive bool
|
||||
)
|
||||
|
||||
attachmentIDs := []string(c.attachmentIDs)
|
||||
|
||||
if !c.mediaFiles.Empty() {
|
||||
descriptionsExists := false
|
||||
focusValuesExists := false
|
||||
expectedLength := len(c.mediaFiles)
|
||||
mediaDescriptions := make([]string, expectedLength)
|
||||
|
||||
if !c.mediaDescriptions.Empty() {
|
||||
descriptionsExists = true
|
||||
|
||||
if !c.mediaDescriptions.ExpectedLength(expectedLength) {
|
||||
return errors.New("the number of media descriptions does not match the number of media files")
|
||||
}
|
||||
}
|
||||
|
||||
if !c.mediaFocusValues.Empty() {
|
||||
focusValuesExists = true
|
||||
|
||||
if !c.mediaFocusValues.ExpectedLength(expectedLength) {
|
||||
return errors.New("the number of media focus values does not match the number of media files")
|
||||
}
|
||||
}
|
||||
|
||||
if descriptionsExists {
|
||||
for ind := 0; ind < expectedLength; ind++ {
|
||||
content, err := utilities.ReadContents(c.mediaDescriptions[ind])
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read the contents from %s: %w", c.mediaDescriptions[ind], err)
|
||||
}
|
||||
|
||||
mediaDescriptions[ind] = content
|
||||
}
|
||||
}
|
||||
|
||||
for ind := 0; ind < expectedLength; ind++ {
|
||||
var (
|
||||
mediaFile string
|
||||
description string
|
||||
focus string
|
||||
)
|
||||
|
||||
mediaFile = c.mediaFiles[ind]
|
||||
|
||||
if descriptionsExists {
|
||||
description = mediaDescriptions[ind]
|
||||
}
|
||||
|
||||
if focusValuesExists {
|
||||
focus = c.mediaFocusValues[ind]
|
||||
}
|
||||
|
||||
attachment, err := gtsClient.CreateMediaAttachment(
|
||||
mediaFile,
|
||||
description,
|
||||
focus,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create the media attachment for %s: %w", mediaFile, err)
|
||||
}
|
||||
|
||||
attachmentIDs = append(attachmentIDs, attachment.ID)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case c.content != "":
|
||||
content = c.content
|
||||
|
@ -75,12 +142,21 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
return fmt.Errorf("unable to get the status contents from %q: %w", c.fromFile, err)
|
||||
}
|
||||
default:
|
||||
return EmptyContentError{
|
||||
ResourceType: resourceStatus,
|
||||
Hint: "please use --" + flagContent + " or --" + flagFromFile,
|
||||
if len(attachmentIDs) == 0 {
|
||||
// TODO: revisit this error type
|
||||
return EmptyContentError{
|
||||
ResourceType: resourceStatus,
|
||||
Hint: "please use --" + flagContent + " or --" + flagFromFile,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numAttachmentIDs := len(attachmentIDs)
|
||||
|
||||
if c.addPoll && numAttachmentIDs > 0 {
|
||||
return fmt.Errorf("attaching media to a poll is not allowed")
|
||||
}
|
||||
|
||||
preferences, err := gtsClient.GetUserPreferences()
|
||||
if err != nil {
|
||||
fmt.Println("WARNING: Unable to get your posting preferences: %w", err)
|
||||
|
@ -115,18 +191,23 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
form := client.CreateStatusForm{
|
||||
Content: content,
|
||||
ContentType: parsedContentType,
|
||||
Language: language,
|
||||
SpoilerText: c.spoilerText,
|
||||
Boostable: c.boostable,
|
||||
Federated: c.federated,
|
||||
InReplyTo: c.inReplyTo,
|
||||
Likeable: c.likeable,
|
||||
Replyable: c.replyable,
|
||||
Sensitive: sensitive,
|
||||
Visibility: parsedVisibility,
|
||||
Poll: nil,
|
||||
Content: content,
|
||||
ContentType: parsedContentType,
|
||||
Language: language,
|
||||
SpoilerText: c.spoilerText,
|
||||
Boostable: c.boostable,
|
||||
Federated: c.federated,
|
||||
InReplyTo: c.inReplyTo,
|
||||
Likeable: c.likeable,
|
||||
Replyable: c.replyable,
|
||||
Sensitive: sensitive,
|
||||
Visibility: parsedVisibility,
|
||||
Poll: nil,
|
||||
AttachmentIDs: nil,
|
||||
}
|
||||
|
||||
if numAttachmentIDs > 0 {
|
||||
form.AttachmentIDs = attachmentIDs
|
||||
}
|
||||
|
||||
if c.addPoll {
|
||||
|
@ -153,3 +234,40 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CreateExecutor) createMediaAttachment(gtsClient *client.Client) error {
|
||||
expectedNumValues := 1
|
||||
if !c.mediaFiles.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media files: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
}
|
||||
|
||||
if !c.mediaDescriptions.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media descriptions: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
}
|
||||
|
||||
if !c.mediaFocusValues.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media focus values: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
}
|
||||
|
||||
attachment, err := gtsClient.CreateMediaAttachment(
|
||||
c.mediaFiles[0],
|
||||
c.mediaDescriptions[0],
|
||||
c.mediaFocusValues[0],
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create the media attachment: %w", err)
|
||||
}
|
||||
|
||||
c.printer.PrintSuccess("Successfully created the media attachment with ID: " + attachment.ID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ func (e *EditExecutor) Execute() error {
|
|||
}
|
||||
|
||||
funcMap := map[string]func(*client.Client) error{
|
||||
resourceList: e.editList,
|
||||
resourceList: e.editList,
|
||||
resourceMediaAttachment: e.editMediaAttachment,
|
||||
}
|
||||
|
||||
doFunc, ok := funcMap[e.resourceType]
|
||||
|
@ -57,8 +58,55 @@ func (e *EditExecutor) editList(gtsClient *client.Client) error {
|
|||
return fmt.Errorf("unable to update the list: %w", err)
|
||||
}
|
||||
|
||||
e.printer.PrintSuccess("Successfully updated the list.")
|
||||
e.printer.PrintSuccess("Successfully edited the list.")
|
||||
e.printer.PrintList(updatedList)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EditExecutor) editMediaAttachment(gtsClient *client.Client) error {
|
||||
expectedNumValues := 1
|
||||
if !e.attachmentIDs.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media attachment IDs: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
}
|
||||
|
||||
if !e.mediaDescriptions.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media descriptions: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
}
|
||||
|
||||
if !e.mediaFocusValues.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media focus values: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
}
|
||||
|
||||
attachment, err := gtsClient.GetMediaAttachment(e.attachmentIDs[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get the media attachment: %w", err)
|
||||
}
|
||||
|
||||
description := e.mediaDescriptions[0]
|
||||
if description == "" {
|
||||
description = attachment.Description
|
||||
}
|
||||
|
||||
focus := e.mediaFocusValues[0]
|
||||
if focus == "" {
|
||||
focus = fmt.Sprintf("%f,%f", attachment.Meta.Focus.X, attachment.Meta.Focus.Y)
|
||||
}
|
||||
|
||||
if _, err = gtsClient.UpdateMediaAttachment(e.attachmentIDs[0], description, focus); err != nil {
|
||||
return fmt.Errorf("unable to update the media attachment: %w", err)
|
||||
}
|
||||
|
||||
e.printer.PrintSuccess("Successfully edited the media attachment.")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ type CreateExecutor struct {
|
|||
printer *printer.Printer
|
||||
config *config.Config
|
||||
addPoll bool
|
||||
attachmentIDs internalFlag.StringSliceValue
|
||||
content string
|
||||
contentType string
|
||||
federated bool
|
||||
|
@ -132,6 +133,9 @@ type CreateExecutor struct {
|
|||
language string
|
||||
listRepliesPolicy string
|
||||
listTitle string
|
||||
mediaDescriptions internalFlag.StringSliceValue
|
||||
mediaFocusValues internalFlag.StringSliceValue
|
||||
mediaFiles internalFlag.StringSliceValue
|
||||
pollAllowsMultipleChoices bool
|
||||
pollExpiresIn internalFlag.TimeDurationValue
|
||||
pollHidesVoteCounts bool
|
||||
|
@ -147,17 +151,22 @@ func NewCreateExecutor(
|
|||
config *config.Config,
|
||||
) *CreateExecutor {
|
||||
exe := CreateExecutor{
|
||||
FlagSet: flag.NewFlagSet("create", flag.ExitOnError),
|
||||
printer: printer,
|
||||
config: config,
|
||||
pollExpiresIn: internalFlag.NewTimeDurationValue(),
|
||||
pollOptions: internalFlag.NewStringSliceValue(),
|
||||
sensitive: internalFlag.NewBoolPtrValue(),
|
||||
FlagSet: flag.NewFlagSet("create", flag.ExitOnError),
|
||||
printer: printer,
|
||||
config: config,
|
||||
attachmentIDs: internalFlag.NewStringSliceValue(),
|
||||
mediaDescriptions: internalFlag.NewStringSliceValue(),
|
||||
mediaFocusValues: internalFlag.NewStringSliceValue(),
|
||||
mediaFiles: internalFlag.NewStringSliceValue(),
|
||||
pollExpiresIn: internalFlag.NewTimeDurationValue(),
|
||||
pollOptions: internalFlag.NewStringSliceValue(),
|
||||
sensitive: internalFlag.NewBoolPtrValue(),
|
||||
}
|
||||
|
||||
exe.Usage = usage.ExecutorUsageFunc("create", "Creates a specific resource", exe.FlagSet)
|
||||
|
||||
exe.BoolVar(&exe.addPoll, "add-poll", false, "Set to true to add a poll when creating a status")
|
||||
exe.Var(&exe.attachmentIDs, "attachment-id", "The ID of the media attachment")
|
||||
exe.StringVar(&exe.content, "content", "", "The content of the created resource")
|
||||
exe.StringVar(&exe.contentType, "content-type", "plain", "The type that the contents should be parsed from (valid values are plain and markdown)")
|
||||
exe.BoolVar(&exe.federated, "enable-federation", true, "Set to true to federate the status beyond the local timelines")
|
||||
|
@ -169,6 +178,9 @@ func NewCreateExecutor(
|
|||
exe.StringVar(&exe.language, "language", "", "The ISO 639 language code for this status")
|
||||
exe.StringVar(&exe.listRepliesPolicy, "list-replies-policy", "list", "The replies policy of the list")
|
||||
exe.StringVar(&exe.listTitle, "list-title", "", "The title of the list")
|
||||
exe.Var(&exe.mediaDescriptions, "media-description", "The description of the media attachment that will be used as the alt-text")
|
||||
exe.Var(&exe.mediaFocusValues, "media-focus", "The focus of the media file")
|
||||
exe.Var(&exe.mediaFiles, "media-file", "The path to the media file")
|
||||
exe.BoolVar(&exe.pollAllowsMultipleChoices, "poll-allows-multiple-choices", false, "Set to true to allow viewers to make multiple choices in the poll")
|
||||
exe.Var(&exe.pollExpiresIn, "poll-expires-in", "The duration in which the poll is open for")
|
||||
exe.BoolVar(&exe.pollHidesVoteCounts, "poll-hides-vote-counts", false, "Set to true to hide the vote count until the poll is closed")
|
||||
|
@ -213,9 +225,12 @@ type EditExecutor struct {
|
|||
*flag.FlagSet
|
||||
printer *printer.Printer
|
||||
config *config.Config
|
||||
attachmentIDs internalFlag.StringSliceValue
|
||||
listID string
|
||||
listTitle string
|
||||
listRepliesPolicy string
|
||||
mediaDescriptions internalFlag.StringSliceValue
|
||||
mediaFocusValues internalFlag.StringSliceValue
|
||||
resourceType string
|
||||
}
|
||||
|
||||
|
@ -224,16 +239,22 @@ func NewEditExecutor(
|
|||
config *config.Config,
|
||||
) *EditExecutor {
|
||||
exe := EditExecutor{
|
||||
FlagSet: flag.NewFlagSet("edit", flag.ExitOnError),
|
||||
printer: printer,
|
||||
config: config,
|
||||
FlagSet: flag.NewFlagSet("edit", flag.ExitOnError),
|
||||
printer: printer,
|
||||
config: config,
|
||||
attachmentIDs: internalFlag.NewStringSliceValue(),
|
||||
mediaDescriptions: internalFlag.NewStringSliceValue(),
|
||||
mediaFocusValues: internalFlag.NewStringSliceValue(),
|
||||
}
|
||||
|
||||
exe.Usage = usage.ExecutorUsageFunc("edit", "Edit a specific resource", exe.FlagSet)
|
||||
|
||||
exe.Var(&exe.attachmentIDs, "attachment-id", "The ID of the media attachment")
|
||||
exe.StringVar(&exe.listID, "list-id", "", "The ID of the list in question")
|
||||
exe.StringVar(&exe.listTitle, "list-title", "", "The title of the list")
|
||||
exe.StringVar(&exe.listRepliesPolicy, "list-replies-policy", "", "The replies policy of the list")
|
||||
exe.Var(&exe.mediaDescriptions, "media-description", "The description of the media attachment that will be used as the alt-text")
|
||||
exe.Var(&exe.mediaFocusValues, "media-focus", "The focus of the media file")
|
||||
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
|
||||
|
||||
return &exe
|
||||
|
|
|
@ -4,8 +4,19 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const filePrefix string = "file@"
|
||||
|
||||
func ReadContents(text string) (string, error) {
|
||||
if !strings.HasPrefix(text, filePrefix) {
|
||||
return text, nil
|
||||
}
|
||||
|
||||
return ReadFile(strings.TrimPrefix(text, filePrefix))
|
||||
}
|
||||
|
||||
func ReadFile(path string) (string, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
|
|
|
@ -96,6 +96,18 @@
|
|||
"type": "string",
|
||||
"description": "The replies policy of the list"
|
||||
},
|
||||
"media-description": {
|
||||
"type": "StringSliceValue",
|
||||
"description": "The description of the media attachment that will be used as the alt-text"
|
||||
},
|
||||
"media-file": {
|
||||
"type": "StringSliceValue",
|
||||
"description": "The path to the media file"
|
||||
},
|
||||
"media-focus": {
|
||||
"type": "StringSliceValue",
|
||||
"description": "The focus of the media file"
|
||||
},
|
||||
"mute-duration": {
|
||||
"type": "TimeDurationValue",
|
||||
"description": "Specify how long the mute should last for. To mute indefinitely, set this to 0s"
|
||||
|
@ -234,6 +246,7 @@
|
|||
"additionalFields": [],
|
||||
"flags": [
|
||||
{ "flag": "add-poll", "default": "false" },
|
||||
{ "flag": "attachment-id", "fieldName": "attachmentIDs" },
|
||||
{ "flag": "content", "default": "" },
|
||||
{ "flag": "content-type", "default": "plain" },
|
||||
{ "flag": "enable-federation", "fieldName": "federated", "default": "true" },
|
||||
|
@ -245,6 +258,9 @@
|
|||
{ "flag": "language", "default": "" },
|
||||
{ "flag": "list-replies-policy", "default": "list" },
|
||||
{ "flag": "list-title", "default": "" },
|
||||
{ "flag": "media-description", "fieldName": "mediaDescriptions" },
|
||||
{ "flag": "media-focus", "fieldName": "mediaFocusValues" },
|
||||
{ "flag": "media-file", "fieldName": "mediaFiles" },
|
||||
{ "flag": "poll-allows-multiple-choices", "default": "false" },
|
||||
{ "flag": "poll-expires-in" },
|
||||
{ "flag": "poll-hides-vote-counts", "default": "false" },
|
||||
|
@ -271,9 +287,12 @@
|
|||
"edit": {
|
||||
"additionalFields": [],
|
||||
"flags": [
|
||||
{ "flag": "attachment-id", "fieldName": "attachmentIDs" },
|
||||
{ "flag": "list-id", "fieldName": "listID", "default": ""},
|
||||
{ "flag": "list-title", "default": "" },
|
||||
{ "flag": "list-replies-policy", "default": "" },
|
||||
{ "flag": "media-description", "fieldName": "mediaDescriptions" },
|
||||
{ "flag": "media-focus", "fieldName": "mediaFocusValues" },
|
||||
{ "flag": "type", "fieldName": "resourceType", "default": "" }
|
||||
],
|
||||
"summary": "Edit a specific resource",
|
||||
|
|
Loading…
Reference in a new issue