diff --git a/internal/client/poll.go b/internal/client/poll.go index bf1bc50..7e55253 100644 --- a/internal/client/poll.go +++ b/internal/client/poll.go @@ -45,7 +45,7 @@ func (g *Client) VoteInPoll(pollID string, choices []int) error { } requestBody := bytes.NewBuffer(data) - url := g.Authentication.Instance + pollPath + "/" + pollID + "/vote" + url := g.Authentication.Instance + pollPath + "/" + pollID + "/votes" if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil { return fmt.Errorf("received an error after sending the request to vote in the poll: %w", err) diff --git a/internal/executor/add.go b/internal/executor/add.go index 99946d7..3c85cb3 100644 --- a/internal/executor/add.go +++ b/internal/executor/add.go @@ -5,6 +5,7 @@ package executor import ( + "errors" "flag" "fmt" @@ -19,6 +20,8 @@ type AddExecutor struct { toResourceType string listID string statusID string + pollID string + choices PollChoices accountNames AccountNames content string } @@ -34,10 +37,12 @@ func NewAddExecutor(tlf TopLevelFlags, name, summary string) *AddExecutor { addExe.StringVar(&addExe.resourceType, flagType, "", "Specify the resource type to add (e.g. account, note)") addExe.StringVar(&addExe.toResourceType, flagTo, "", "Specify the target resource type to add to (e.g. list, account, etc)") - addExe.StringVar(&addExe.listID, flagListID, "", "The ID of the list to add to") + addExe.StringVar(&addExe.listID, flagListID, "", "The ID of the list") addExe.StringVar(&addExe.statusID, flagStatusID, "", "The ID of the status") - addExe.Var(&addExe.accountNames, flagAccountName, "The name of the account") addExe.StringVar(&addExe.content, flagContent, "", "The content of the resource") + addExe.StringVar(&addExe.pollID, flagPollID, "", "The ID of the poll") + addExe.Var(&addExe.accountNames, flagAccountName, "The name of the account") + addExe.Var(&addExe.choices, flagChoose, "Specify your choice ") addExe.Usage = commandUsageFunc(name, summary, addExe.FlagSet) @@ -54,6 +59,7 @@ func (a *AddExecutor) Execute() error { resourceAccount: a.addToAccount, resourceBookmarks: a.addToBookmarks, resourceStatus: a.addToStatus, + resourcePoll: a.addToPoll, } doFunc, ok := funcMap[a.toResourceType] @@ -227,3 +233,50 @@ func (a *AddExecutor) addBoostToStatus(gtsClient *client.Client) error { return nil } + +func (a *AddExecutor) addToPoll(gtsClient *client.Client) error { + if a.pollID == "" { + return FlagNotSetError{flagText: flagPollID} + } + + funcMap := map[string]func(*client.Client) error{ + resourceVote: a.addVoteToPoll, + } + + doFunc, ok := funcMap[a.resourceType] + if !ok { + return UnsupportedAddOperationError{ + ResourceType: a.resourceType, + AddToResourceType: a.toResourceType, + } + } + + return doFunc(gtsClient) +} + +func (a *AddExecutor) addVoteToPoll(gtsClient *client.Client) error { + if len(a.choices) == 0 { + return errors.New("please use --" + flagChoose + " to make a choice in this poll") + } + + poll, err := gtsClient.GetPoll(a.pollID) + if err != nil { + return fmt.Errorf("unable to retrieve the poll: %w", err) + } + + if poll.Expired { + return errors.New("this poll has expired") + } + + if !poll.Multiple && len(a.choices) > 1 { + return errors.New("this poll does not allow multiple choices") + } + + if err := gtsClient.VoteInPoll(a.pollID, []int(a.choices)); err != nil { + return fmt.Errorf("unable to add your vote(s) to the poll: %w", err) + } + + fmt.Println("Successfully added your vote(s) to the poll.") + + return nil +} diff --git a/internal/executor/flags.go b/internal/executor/flags.go index a2319d4..42e2052 100644 --- a/internal/executor/flags.go +++ b/internal/executor/flags.go @@ -4,11 +4,16 @@ package executor -import "strings" +import ( + "fmt" + "strconv" + "strings" +) const ( flagAccountName = "account-name" flagBrowser = "browser" + flagChoose = "choose" flagContentType = "content-type" flagContent = "content" flagEnableFederation = "enable-federation" @@ -59,3 +64,30 @@ type TopLevelFlags struct { NoColor *bool Pager string } + +type PollChoices []int + +func (p *PollChoices) String() string { + value := "Choices: " + + for ind, vote := range *p { + if ind == len(*p)-1 { + value += strconv.Itoa(vote) + } else { + value += strconv.Itoa(vote) + ", " + } + } + + return value +} + +func (p *PollChoices) Set(text string) error { + value, err := strconv.Atoi(text) + if err != nil { + return fmt.Errorf("unable to parse the value to an integer: %w", err) + } + + *p = append(*p, value) + + return nil +} diff --git a/internal/executor/resources.go b/internal/executor/resources.go index 4b119a1..a634113 100644 --- a/internal/executor/resources.go +++ b/internal/executor/resources.go @@ -22,4 +22,5 @@ const ( resourceStar = "star" resourceStarred = "starred" resourceTimeline = "timeline" + resourceVote = "vote" )