checkpoint: add create to the schema

This commit is contained in:
Dan Anglin 2024-08-11 00:16:12 +01:00
parent 733a1fc9ac
commit 7d2daf77cf
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
6 changed files with 242 additions and 138 deletions

View file

@ -114,6 +114,7 @@ func customFlagValueType(flagType string) bool {
"MultiStringFlagValue": {},
"MultiIntFlagValue": {},
"TimeDurationFlagValue": {},
"BoolPtrFlagValue": {},
}
_, exists := customFlagValueTypes[flagType]

View file

@ -106,8 +106,6 @@ func run() error {
executor.CommandCreate: executor.NewCreateExecutor(
enbasPrinter,
enbasConfig,
executor.CommandCreate,
executor.CommandSummaryLookup(executor.CommandCreate),
),
executor.CommandDelete: executor.NewDeleteExecutor(
enbasPrinter,

View file

@ -1,94 +1,13 @@
package executor
import (
"flag"
"fmt"
"strconv"
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
)
type CreateExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
addPoll bool
boostable bool
federated bool
likeable bool
pollAllowsMultipleChoices bool
pollHidesVoteCounts bool
replyable bool
sensitive *bool
content string
contentType string
fromFile string
inReplyTo string
language string
resourceType string
listTitle string
listRepliesPolicy string
spoilerText string
visibility string
pollExpiresIn TimeDurationFlagValue
pollOptions MultiStringFlagValue
}
func NewCreateExecutor(printer *printer.Printer, config *config.Config, name, summary string) *CreateExecutor {
createExe := CreateExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: printer,
config: config,
}
createExe.StringVar(&createExe.resourceType, flagType, "", "Specify the type of resource to create")
// Flags for statuses
createExe.BoolVar(&createExe.boostable, flagEnableReposts, true, "Specify if the status can be reposted/boosted by others")
createExe.StringVar(&createExe.content, flagContent, "", "The content of the status to create")
createExe.StringVar(&createExe.contentType, flagContentType, "plain", "The type that the contents should be parsed from (valid values are plain and markdown)")
createExe.BoolVar(&createExe.federated, flagEnableFederation, true, "Specify if the status can be federated beyond the local timelines")
createExe.StringVar(&createExe.fromFile, flagFromFile, "", "The file path where to read the contents from")
createExe.StringVar(&createExe.inReplyTo, flagInReplyTo, "", "The ID of the status that you want to reply to")
createExe.StringVar(&createExe.language, flagLanguage, "", "The ISO 639 language code for this status")
createExe.BoolVar(&createExe.likeable, flagEnableLikes, true, "Specify if the status can be liked/favourited")
createExe.BoolVar(&createExe.replyable, flagEnableReplies, true, "Specify if the status can be replied to")
createExe.StringVar(&createExe.spoilerText, flagSpoilerText, "", "The text to display as the status' warning or subject")
createExe.StringVar(&createExe.visibility, flagVisibility, "", "The visibility of the posted status")
createExe.BoolFunc(flagSensitive, "Specify if the status should be marked as sensitive", func(value string) error {
boolVal, err := strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("unable to parse %q as a boolean value: %w", value, err)
}
createExe.sensitive = new(bool)
*createExe.sensitive = boolVal
return nil
})
// Flags specifically for polls
createExe.BoolVar(&createExe.addPoll, flagAddPoll, false, "Add a poll to the status")
createExe.BoolVar(&createExe.pollAllowsMultipleChoices, flagPollAllowsMultipleChoices, false, "The poll allows viewers to make multiple choices in the poll")
createExe.BoolVar(&createExe.pollHidesVoteCounts, flagPollHidesVoteCounts, false, "The poll will hide the vote count until it is closed")
createExe.Var(&createExe.pollOptions, flagPollOption, "A poll option. Use this multiple times to set multiple options")
createExe.Var(&createExe.pollExpiresIn, flagPollExpiresIn, "The duration in which the poll is open for")
// Flags for lists
createExe.StringVar(&createExe.listTitle, flagListTitle, "", "Specify the title of the list")
createExe.StringVar(&createExe.listRepliesPolicy, flagListRepliesPolicy, "list", "Specify the policy of the replies for this list (valid values are followed, list and none)")
createExe.Usage = commandUsageFunc(name, summary, createExe.FlagSet)
return &createExe
}
func (c *CreateExecutor) Execute() error {
if c.resourceType == "" {
return FlagNotSetError{flagText: flagType}
@ -179,8 +98,8 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
visibility = preferences.PostingDefaultVisibility
}
if c.sensitive != nil {
sensitive = *c.sensitive
if c.sensitive.Value != nil {
sensitive = *c.sensitive.Value
} else {
sensitive = preferences.PostingDefaultSensitive
}

View file

@ -64,6 +64,71 @@ func NewBlockExecutor(
return &exe
}
// CreateExecutor is the executor for the create command.
type CreateExecutor struct {
*flag.FlagSet
printer *printer.Printer
config *config.Config
addPoll bool
content string
contentType string
federated bool
likeable bool
replyable bool
boostable bool
fromFile string
inReplyTo string
language string
listRepliesPolicy string
listTitle string
pollAllowsMultipleChoices bool
pollExpiresIn TimeDurationFlagValue
pollHidesVoteCounts bool
pollOptions MultiStringFlagValue
sensitive BoolPtrFlagValue
spoilerText string
resourceType string
visibility string
}
func NewCreateExecutor(
printer *printer.Printer,
config *config.Config,
) *CreateExecutor {
exe := CreateExecutor{
FlagSet: flag.NewFlagSet("create", flag.ExitOnError),
printer: printer,
config: config,
pollExpiresIn: NewTimeDurationFlagValue(),
pollOptions: NewMultiStringFlagValue(),
sensitive: NewBoolPtrFlagValue(),
}
exe.Usage = commandUsageFunc("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.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")
exe.BoolVar(&exe.likeable, "enable-likes", true, "Set to true to allow the status to be liked (favourited)")
exe.BoolVar(&exe.replyable, "enable-replies", true, "Set to true to allow viewers to reply to the status")
exe.BoolVar(&exe.boostable, "enable-reposts", true, "Set to true to allow the status to be reposted (boosted) by others")
exe.StringVar(&exe.fromFile, "from-file", "", "The file path where to read the contents from")
exe.StringVar(&exe.inReplyTo, "in-reply-to", "", "The ID of the status that you want to reply to")
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.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")
exe.Var(&exe.pollOptions, "poll-option", "A poll option. Use this multiple times to set multiple options")
exe.Var(&exe.sensitive, "sensitive", "Set to true if the status should be marked as sensitive")
exe.StringVar(&exe.spoilerText, "spoiler-text", "", "The text to display as the status' warning or subject")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
exe.StringVar(&exe.visibility, "visibility", "", "The visibility of the posted status")
return &exe
}
// DeleteExecutor is the executor for the delete command.
type DeleteExecutor struct {
*flag.FlagSet
@ -83,7 +148,7 @@ func NewDeleteExecutor(
config: config,
}
exe.Usage = commandUsageFunc("delete", "Delete a specific resource", exe.FlagSet)
exe.Usage = commandUsageFunc("delete", "Deletes a specific resource", exe.FlagSet)
exe.StringVar(&exe.listID, "list-id", "", "The ID of the list in question")
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")

View file

@ -8,58 +8,47 @@ import (
)
const (
flagAddPoll = "add-poll"
flagAccountName = "account-name"
flagAllImages = "all-images"
flagAllVideos = "all-videos"
flagAttachmentID = "attachment-id"
flagBrowser = "browser"
flagContentType = "content-type"
flagContent = "content"
flagEnableFederation = "enable-federation"
flagEnableLikes = "enable-likes"
flagEnableReplies = "enable-replies"
flagEnableReposts = "enable-reposts"
flagExcludeBoosts = "exclude-boosts"
flagExcludeReplies = "exclude-replies"
flagFrom = "from"
flagFromFile = "from-file"
flagInReplyTo = "in-reply-to"
flagInstance = "instance"
flagLanguage = "language"
flagLimit = "limit"
flagListID = "list-id"
flagListTitle = "list-title"
flagListRepliesPolicy = "list-replies-policy"
flagMyAccount = "my-account"
flagMuteDuration = "mute-duration"
flagMuteNotifications = "mute-notifications"
flagOnlyMedia = "only-media"
flagOnlyPinned = "only-pinned"
flagOnlyPublic = "only-public"
flagPollAllowsMultipleChoices = "poll-allows-multiple-choices"
flagPollExpiresIn = "poll-expires-in"
flagPollHidesVoteCounts = "poll-hides-vote-counts"
flagPollID = "poll-id"
flagPollOption = "poll-option"
flagSensitive = "sensitive"
flagSkipRelationship = "skip-relationship"
flagShowPreferences = "show-preferences"
flagShowStatuses = "show-statuses"
flagSpoilerText = "spoiler-text"
flagStatusID = "status-id"
flagTag = "tag"
flagTimelineCategory = "timeline-category"
flagTo = "to"
flagType = "type"
flagVisibility = "visibility"
flagVote = "vote"
)
type MultiStringFlagValue []string
func (v *MultiStringFlagValue) String() string {
return strings.Join(*v, ", ")
func NewMultiStringFlagValue() MultiStringFlagValue {
arr := make([]string, 0, 3)
return MultiStringFlagValue(arr)
}
func (v MultiStringFlagValue) String() string {
return strings.Join(v, ", ")
}
func (v *MultiStringFlagValue) Set(value string) error {
@ -72,11 +61,17 @@ func (v *MultiStringFlagValue) Set(value string) error {
type MultiIntFlagValue []int
func (v *MultiIntFlagValue) String() string {
func NewMultiIntFlagValue() MultiIntFlagValue {
arr := make([]int, 0, 3)
return MultiIntFlagValue(arr)
}
func (v MultiIntFlagValue) String() string {
value := "Choices: "
for ind, vote := range *v {
if ind == len(*v)-1 {
for ind, vote := range v {
if ind == len(v)-1 {
value += strconv.Itoa(vote)
} else {
value += strconv.Itoa(vote) + ", "
@ -121,3 +116,33 @@ func (v *TimeDurationFlagValue) Set(text string) error {
return nil
}
type BoolPtrFlagValue struct {
Value *bool
}
func NewBoolPtrFlagValue() BoolPtrFlagValue {
return BoolPtrFlagValue{
Value: nil,
}
}
func (b BoolPtrFlagValue) String() string {
if b.Value == nil {
return "NOT SET"
}
return strconv.FormatBool(*b.Value)
}
func (b *BoolPtrFlagValue) Set(value string) error {
boolVar, err := strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("unable to parse %q as a boolean value: %w", value, err)
}
b.Value = new(bool)
*b.Value = boolVar
return nil
}

View file

@ -4,14 +4,54 @@
"type": "string",
"description": "The name of the account"
},
"add-poll": {
"type": "bool",
"description": "Set to true to add a poll when creating a status"
},
"content": {
"type": "string",
"description": "The content of the created resource"
},
"content-type": {
"type": "string",
"description": "The type that the contents should be parsed from (valid values are plain and markdown)"
},
"enable-federation": {
"type": "bool",
"description": "Set to true to federate the status beyond the local timelines"
},
"enable-likes": {
"type": "bool",
"description": "Set to true to allow the status to be liked (favourited)"
},
"enable-replies": {
"type": "bool",
"description": "Set to true to allow viewers to reply to the status"
},
"enable-reposts": {
"type": "bool",
"description": "Set to true to allow the status to be reposted (boosted) by others"
},
"from-file": {
"type": "string",
"description": "The file path where to read the contents from"
},
"full": {
"type": "bool",
"description": "Set to true to print the build information in full"
},
"in-reply-to": {
"type": "string",
"description": "The ID of the status that you want to reply to"
},
"instance": {
"type": "string",
"description": "The instance that you want to log into"
},
"language": {
"type": "string",
"description": "The ISO 639 language code for this status"
},
"list-id": {
"type": "string",
"description": "The ID of the list in question"
@ -36,10 +76,34 @@
"type": "bool",
"description": "Get notifications from statuses from the account you want to follow"
},
"poll-allows-multiple-choices": {
"type": "bool",
"description": "Set to true to allow viewers to make multiple choices in the poll"
},
"poll-expires-in": {
"type": "TimeDurationFlagValue",
"description": "The duration in which the poll is open for"
},
"poll-hides-vote-counts": {
"type": "bool",
"description": "Set to true to hide the vote count until the poll is closed"
},
"poll-option": {
"type": "MultiStringFlagValue",
"description": "A poll option. Use this multiple times to set multiple options"
},
"sensitive": {
"type": "BoolPtrFlagValue",
"description": "Set to true if the status should be marked as sensitive"
},
"show-reposts": {
"type": "bool",
"description": "Show reposts from the account you want to follow"
},
"spoiler-text": {
"type": "string",
"description": "The text to display as the status' warning or subject"
},
"type": {
"type": "string",
"description": "The type of resource you want to action on (e.g. account, status)"
@ -47,6 +111,10 @@
"to": {
"type": "string",
"description": "TBC"
},
"visibility": {
"type": "string",
"description": "The visibility of the posted status"
}
},
@ -71,13 +139,41 @@
"useConfig": true,
"usePrinter": true
},
"create": {
"additionalFields": [],
"flags": [
{ "flag": "add-poll", "default": "false" },
{ "flag": "content", "default": "" },
{ "flag": "content-type", "default": "plain" },
{ "flag": "enable-federation", "fieldName": "federated", "default": "true" },
{ "flag": "enable-likes", "fieldName": "likeable", "default": "true" },
{ "flag": "enable-replies", "fieldName": "replyable", "default": "true" },
{ "flag": "enable-reposts", "fieldName": "boostable", "default": "true" },
{ "flag": "from-file", "default": "" },
{ "flag": "in-reply-to", "default": "" },
{ "flag": "language", "default": "" },
{ "flag": "list-replies-policy", "default": "list" },
{ "flag": "list-title", "default": "" },
{ "flag": "poll-allows-multiple-choices", "default": "false" },
{ "flag": "poll-expires-in" },
{ "flag": "poll-hides-vote-counts", "default": "false" },
{ "flag": "poll-option", "fieldName": "pollOptions" },
{ "flag": "sensitive" },
{ "flag": "spoiler-text", "default": "" },
{ "flag": "type", "fieldName": "resourceType", "default": "" },
{ "flag": "visibility", "default": "" }
],
"summary": "Creates a specific resource",
"useConfig": true,
"usePrinter": true
},
"delete": {
"additionalFields": [],
"flags": [
{ "flag": "list-id", "fieldName": "listID", "default": ""},
{ "flag": "type", "fieldName": "resourceType", "default": "" }
],
"summary": "Delete a specific resource",
"summary": "Deletes a specific resource",
"useConfig": true,
"usePrinter": true
},