Compare commits
3 commits
b77bbaa6e0
...
2f530bca5a
Author | SHA1 | Date | |
---|---|---|---|
2f530bca5a | |||
64e8d6f0ba | |||
ef2b02b799 |
11 changed files with 179 additions and 197 deletions
|
@ -536,16 +536,7 @@ See [Create a status](#create-a-status).
|
||||||
|
|
||||||
### View a poll
|
### View a poll
|
||||||
|
|
||||||
Prints the poll information to the screen.
|
You can view a poll from a status or timeline.
|
||||||
|
|
||||||
```
|
|
||||||
enbas show --type poll --poll-id 01J0CEEZBZ6E6AYQSJPHCQYBDA
|
|
||||||
```
|
|
||||||
|
|
||||||
| flag | type | required | description | default |
|
|
||||||
|------|------|----------|-------------|---------|
|
|
||||||
| `type` | string | true | The resource you want to view.<br>Here this should be `poll`. | |
|
|
||||||
| `poll-id` | string | true | The ID of the poll that you want to view. | |
|
|
||||||
|
|
||||||
### Vote in a poll
|
### Vote in a poll
|
||||||
|
|
||||||
|
|
|
@ -5,36 +5,34 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pollPath string = "/api/v1/polls"
|
pollPath string = "/api/v1/polls"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *Client) GetPoll(pollID string) (model.Poll, error) {
|
// func (g *Client) GetPoll(pollID string) (model.Poll, error) {
|
||||||
url := g.Authentication.Instance + pollPath + "/" + pollID
|
// url := g.Authentication.Instance + pollPath + "/" + pollID
|
||||||
|
//
|
||||||
var poll model.Poll
|
// var poll model.Poll
|
||||||
|
//
|
||||||
params := requestParameters{
|
// params := requestParameters{
|
||||||
httpMethod: http.MethodGet,
|
// httpMethod: http.MethodGet,
|
||||||
url: url,
|
// url: url,
|
||||||
requestBody: nil,
|
// requestBody: nil,
|
||||||
contentType: "",
|
// contentType: "",
|
||||||
output: &poll,
|
// output: &poll,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if err := g.sendRequest(params); err != nil {
|
// if err := g.sendRequest(params); err != nil {
|
||||||
return model.Poll{}, fmt.Errorf(
|
// return model.Poll{}, fmt.Errorf(
|
||||||
"received an error after sending the request to get the poll: %w",
|
// "received an error after sending the request to get the poll: %w",
|
||||||
err,
|
// err,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return poll, nil
|
// return poll, nil
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (g *Client) VoteInPoll(pollID string, choices []int) error {
|
func (g *Client) VoteInPoll(pollID string, choices []int) error {
|
||||||
form := struct {
|
form := struct {
|
||||||
|
|
|
@ -17,7 +17,6 @@ func (a *AddExecutor) Execute() error {
|
||||||
resourceAccount: a.addToAccount,
|
resourceAccount: a.addToAccount,
|
||||||
resourceBookmarks: a.addToBookmarks,
|
resourceBookmarks: a.addToBookmarks,
|
||||||
resourceStatus: a.addToStatus,
|
resourceStatus: a.addToStatus,
|
||||||
resourcePoll: a.addToPoll,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doFunc, ok := funcMap[a.toResourceType]
|
doFunc, ok := funcMap[a.toResourceType]
|
||||||
|
@ -164,6 +163,7 @@ func (a *AddExecutor) addToStatus(gtsClient *client.Client) error {
|
||||||
resourceStar: a.addStarToStatus,
|
resourceStar: a.addStarToStatus,
|
||||||
resourceLike: a.addStarToStatus,
|
resourceLike: a.addStarToStatus,
|
||||||
resourceBoost: a.addBoostToStatus,
|
resourceBoost: a.addBoostToStatus,
|
||||||
|
resourceVote: a.addVoteToStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
doFunc, ok := funcMap[a.resourceType]
|
doFunc, ok := funcMap[a.resourceType]
|
||||||
|
@ -197,45 +197,40 @@ func (a *AddExecutor) addBoostToStatus(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AddExecutor) addToPoll(gtsClient *client.Client) error {
|
func (a *AddExecutor) addVoteToStatus(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 a.votes.Empty() {
|
if a.votes.Empty() {
|
||||||
return errors.New("please use --" + flagVote + " to make a choice in this poll")
|
return errors.New("please use --" + flagVote + " to make a choice in this poll")
|
||||||
}
|
}
|
||||||
|
|
||||||
poll, err := gtsClient.GetPoll(a.pollID)
|
status, err := gtsClient.GetStatus(a.statusID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve the poll: %w", err)
|
return fmt.Errorf("unable to get the status: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if poll.Expired {
|
if status.Poll == nil {
|
||||||
|
return errors.New("this status does not have a poll")
|
||||||
|
}
|
||||||
|
|
||||||
|
if status.Poll.Expired {
|
||||||
return PollClosedError{}
|
return PollClosedError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !poll.Multiple && !a.votes.ExpectedLength(1) {
|
if !status.Poll.Multiple && !a.votes.ExpectedLength(1) {
|
||||||
return MultipleChoiceError{}
|
return MultipleChoiceError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gtsClient.VoteInPoll(a.pollID, []int(a.votes)); err != nil {
|
myAccountID, err := getAccountID(gtsClient, true, nil, a.config.CredentialsFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get your account ID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if status.Account.ID == myAccountID {
|
||||||
|
return errors.New("you cannot vote in your own poll")
|
||||||
|
}
|
||||||
|
|
||||||
|
pollID := status.Poll.ID
|
||||||
|
|
||||||
|
if err := gtsClient.VoteInPoll(pollID, []int(a.votes)); err != nil {
|
||||||
return fmt.Errorf("unable to add your vote(s) to the poll: %w", err)
|
return fmt.Errorf("unable to add your vote(s) to the poll: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,8 +149,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
||||||
return fmt.Errorf("unable to create the status: %w", err)
|
return fmt.Errorf("unable to create the status: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.printer.PrintSuccess("Successfully created the following status:")
|
c.printer.PrintSuccess("Successfully created the status with ID: " + status.ID)
|
||||||
c.printer.PrintStatus(status)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@ type AddExecutor struct {
|
||||||
accountNames internalFlag.StringSliceValue
|
accountNames internalFlag.StringSliceValue
|
||||||
content string
|
content string
|
||||||
listID string
|
listID string
|
||||||
pollID string
|
|
||||||
statusID string
|
statusID string
|
||||||
toResourceType string
|
toResourceType string
|
||||||
resourceType string
|
resourceType string
|
||||||
|
@ -80,7 +79,6 @@ func NewAddExecutor(
|
||||||
exe.Var(&exe.accountNames, "account-name", "The name of the account")
|
exe.Var(&exe.accountNames, "account-name", "The name of the account")
|
||||||
exe.StringVar(&exe.content, "content", "", "The content of the created resource")
|
exe.StringVar(&exe.content, "content", "", "The content of the created resource")
|
||||||
exe.StringVar(&exe.listID, "list-id", "", "The ID of the list in question")
|
exe.StringVar(&exe.listID, "list-id", "", "The ID of the list in question")
|
||||||
exe.StringVar(&exe.pollID, "poll-id", "", "The ID of the poll")
|
|
||||||
exe.StringVar(&exe.statusID, "status-id", "", "The ID of the status")
|
exe.StringVar(&exe.statusID, "status-id", "", "The ID of the status")
|
||||||
exe.StringVar(&exe.toResourceType, "to", "", "The resource type to action the target resource to (e.g. status)")
|
exe.StringVar(&exe.toResourceType, "to", "", "The resource type to action the target resource to (e.g. status)")
|
||||||
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
|
exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)")
|
||||||
|
@ -434,7 +432,6 @@ type ShowExecutor struct {
|
||||||
onlyMedia bool
|
onlyMedia bool
|
||||||
onlyPinned bool
|
onlyPinned bool
|
||||||
onlyPublic bool
|
onlyPublic bool
|
||||||
pollID string
|
|
||||||
showUserPreferences bool
|
showUserPreferences bool
|
||||||
showStatuses bool
|
showStatuses bool
|
||||||
skipAccountRelationship bool
|
skipAccountRelationship bool
|
||||||
|
@ -472,7 +469,6 @@ func NewShowExecutor(
|
||||||
exe.BoolVar(&exe.onlyMedia, "only-media", false, "Set to true to show only the statuses with media attachments")
|
exe.BoolVar(&exe.onlyMedia, "only-media", false, "Set to true to show only the statuses with media attachments")
|
||||||
exe.BoolVar(&exe.onlyPinned, "only-pinned", false, "Set to true to show only the account's pinned statuses")
|
exe.BoolVar(&exe.onlyPinned, "only-pinned", false, "Set to true to show only the account's pinned statuses")
|
||||||
exe.BoolVar(&exe.onlyPublic, "only-public", false, "Set to true to show only the account's public posts")
|
exe.BoolVar(&exe.onlyPublic, "only-public", false, "Set to true to show only the account's public posts")
|
||||||
exe.StringVar(&exe.pollID, "poll-id", "", "The ID of the poll")
|
|
||||||
exe.BoolVar(&exe.showUserPreferences, "show-preferences", false, "Set to true to view your posting preferences when viewing your account information")
|
exe.BoolVar(&exe.showUserPreferences, "show-preferences", false, "Set to true to view your posting preferences when viewing your account information")
|
||||||
exe.BoolVar(&exe.showStatuses, "show-statuses", false, "Set to true to view the statuses created from the account you are viewing")
|
exe.BoolVar(&exe.showStatuses, "show-statuses", false, "Set to true to view the statuses created from the account you are viewing")
|
||||||
exe.BoolVar(&exe.skipAccountRelationship, "skip-relationship", false, "Set to true to skip showing your relationship to the account that you are viewing")
|
exe.BoolVar(&exe.skipAccountRelationship, "skip-relationship", false, "Set to true to skip showing your relationship to the account that you are viewing")
|
||||||
|
|
|
@ -28,7 +28,6 @@ func (s *ShowExecutor) Execute() error {
|
||||||
resourceLiked: s.showLiked,
|
resourceLiked: s.showLiked,
|
||||||
resourceStarred: s.showLiked,
|
resourceStarred: s.showLiked,
|
||||||
resourceFollowRequest: s.showFollowRequests,
|
resourceFollowRequest: s.showFollowRequests,
|
||||||
resourcePoll: s.showPoll,
|
|
||||||
resourceMutedAccounts: s.showMutedAccounts,
|
resourceMutedAccounts: s.showMutedAccounts,
|
||||||
resourceMedia: s.showMedia,
|
resourceMedia: s.showMedia,
|
||||||
resourceMediaAttachment: s.showMediaAttachment,
|
resourceMediaAttachment: s.showMediaAttachment,
|
||||||
|
@ -76,6 +75,7 @@ func (s *ShowExecutor) showAccount(gtsClient *client.Client) error {
|
||||||
relationship *model.AccountRelationship
|
relationship *model.AccountRelationship
|
||||||
preferences *model.Preferences
|
preferences *model.Preferences
|
||||||
statuses *model.StatusList
|
statuses *model.StatusList
|
||||||
|
myAccountID string
|
||||||
)
|
)
|
||||||
|
|
||||||
if !s.myAccount && !s.skipAccountRelationship {
|
if !s.myAccount && !s.skipAccountRelationship {
|
||||||
|
@ -85,12 +85,15 @@ func (s *ShowExecutor) showAccount(gtsClient *client.Client) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.myAccount && s.showUserPreferences {
|
if s.myAccount {
|
||||||
|
myAccountID = account.ID
|
||||||
|
if s.showUserPreferences {
|
||||||
preferences, err = gtsClient.GetUserPreferences()
|
preferences, err = gtsClient.GetUserPreferences()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve the user preferences: %w", err)
|
return fmt.Errorf("unable to retrieve the user preferences: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if s.showStatuses {
|
if s.showStatuses {
|
||||||
form := client.GetAccountStatusesForm{
|
form := client.GetAccountStatusesForm{
|
||||||
|
@ -109,7 +112,7 @@ func (s *ShowExecutor) showAccount(gtsClient *client.Client) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.printer.PrintAccount(account, relationship, preferences, statuses)
|
s.printer.PrintAccount(account, relationship, preferences, statuses, myAccountID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -132,7 +135,12 @@ func (s *ShowExecutor) showStatus(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.printer.PrintStatus(status)
|
myAccountID, err := getAccountID(gtsClient, true, nil, s.config.CredentialsFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get your account ID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.printer.PrintStatus(status, myAccountID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -181,7 +189,12 @@ func (s *ShowExecutor) showTimeline(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.printer.PrintStatusList(timeline)
|
myAccountID, err := getAccountID(gtsClient, true, nil, s.config.CredentialsFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get your account ID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.printer.PrintStatusList(timeline, myAccountID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -334,7 +347,12 @@ func (s *ShowExecutor) showBookmarks(gtsClient *client.Client) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(bookmarks.Statuses) > 0 {
|
if len(bookmarks.Statuses) > 0 {
|
||||||
s.printer.PrintStatusList(bookmarks)
|
myAccountID, err := getAccountID(gtsClient, true, nil, s.config.CredentialsFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get your account ID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.printer.PrintStatusList(bookmarks, myAccountID)
|
||||||
} else {
|
} else {
|
||||||
s.printer.PrintInfo("You have no bookmarks.\n")
|
s.printer.PrintInfo("You have no bookmarks.\n")
|
||||||
}
|
}
|
||||||
|
@ -349,7 +367,12 @@ func (s *ShowExecutor) showLiked(gtsClient *client.Client) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(liked.Statuses) > 0 {
|
if len(liked.Statuses) > 0 {
|
||||||
s.printer.PrintStatusList(liked)
|
myAccountID, err := getAccountID(gtsClient, true, nil, s.config.CredentialsFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get your account ID: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.printer.PrintStatusList(liked, myAccountID)
|
||||||
} else {
|
} else {
|
||||||
s.printer.PrintInfo("You have no " + s.resourceType + " statuses.\n")
|
s.printer.PrintInfo("You have no " + s.resourceType + " statuses.\n")
|
||||||
}
|
}
|
||||||
|
@ -372,21 +395,6 @@ func (s *ShowExecutor) showFollowRequests(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ShowExecutor) showPoll(gtsClient *client.Client) error {
|
|
||||||
if s.pollID == "" {
|
|
||||||
return FlagNotSetError{flagText: flagPollID}
|
|
||||||
}
|
|
||||||
|
|
||||||
poll, err := gtsClient.GetPoll(s.pollID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to retrieve the poll: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.printer.PrintPoll(poll)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ShowExecutor) showMutedAccounts(gtsClient *client.Client) error {
|
func (s *ShowExecutor) showMutedAccounts(gtsClient *client.Client) error {
|
||||||
muted, err := gtsClient.GetMutedAccounts(s.limit)
|
muted, err := gtsClient.GetMutedAccounts(s.limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -12,6 +12,7 @@ func (p Printer) PrintAccount(
|
||||||
relationship *model.AccountRelationship,
|
relationship *model.AccountRelationship,
|
||||||
preferences *model.Preferences,
|
preferences *model.Preferences,
|
||||||
statuses *model.StatusList,
|
statuses *model.StatusList,
|
||||||
|
userAccountID string,
|
||||||
) {
|
) {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ func (p Printer) PrintAccount(
|
||||||
}
|
}
|
||||||
|
|
||||||
if statuses != nil {
|
if statuses != nil {
|
||||||
builder.WriteString("\n\n" + p.statusList(*statuses))
|
builder.WriteString("\n\n" + p.statusList(*statuses, userAccountID))
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.WriteString("\n\n")
|
builder.WriteString("\n\n")
|
||||||
|
|
|
@ -1,91 +1,2 @@
|
||||||
package printer
|
package printer
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p Printer) PrintPoll(poll model.Poll) {
|
|
||||||
var builder strings.Builder
|
|
||||||
|
|
||||||
builder.WriteString("\n" + p.headerFormat("POLL ID:"))
|
|
||||||
builder.WriteString("\n" + poll.ID)
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("OPTIONS:"))
|
|
||||||
builder.WriteString(p.pollOptions(poll))
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("MULTIPLE CHOICES ALLOWED:"))
|
|
||||||
builder.WriteString("\n" + strconv.FormatBool(poll.Multiple))
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("YOU VOTED:"))
|
|
||||||
builder.WriteString("\n" + strconv.FormatBool(poll.Voted))
|
|
||||||
|
|
||||||
if len(poll.OwnVotes) > 0 {
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("YOUR VOTES:"))
|
|
||||||
|
|
||||||
for _, vote := range poll.OwnVotes {
|
|
||||||
builder.WriteString("\n" + "[" + strconv.Itoa(vote) + "] " + poll.Options[vote].Title)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("EXPIRED:"))
|
|
||||||
builder.WriteString("\n" + strconv.FormatBool(poll.Expired))
|
|
||||||
builder.WriteString("\n\n")
|
|
||||||
|
|
||||||
p.print(builder.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Printer) pollOptions(poll model.Poll) string {
|
|
||||||
var builder strings.Builder
|
|
||||||
|
|
||||||
for ind, option := range poll.Options {
|
|
||||||
var (
|
|
||||||
votage float64
|
|
||||||
percentage int
|
|
||||||
)
|
|
||||||
|
|
||||||
if poll.VotesCount == 0 {
|
|
||||||
percentage = 0
|
|
||||||
} else {
|
|
||||||
votage = float64(option.VotesCount) / float64(poll.VotesCount)
|
|
||||||
percentage = int(math.Floor(100 * votage))
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + "[" + strconv.Itoa(ind) + "] " + option.Title)
|
|
||||||
builder.WriteString(p.pollMeter(votage))
|
|
||||||
builder.WriteString("\n" + strconv.Itoa(option.VotesCount) + " votes " + "(" + strconv.Itoa(percentage) + "%)")
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.fieldFormat("Total votes:") + " " + strconv.Itoa(poll.VotesCount))
|
|
||||||
builder.WriteString("\n" + p.fieldFormat("Poll ID:") + " " + poll.ID)
|
|
||||||
builder.WriteString("\n" + p.fieldFormat("Poll is open until:") + " " + p.formatDateTime(poll.ExpiredAt))
|
|
||||||
|
|
||||||
return builder.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Printer) pollMeter(votage float64) string {
|
|
||||||
numVoteBlocks := int(math.Floor(float64(p.lineWrapCharacterLimit) * votage))
|
|
||||||
numBackgroundBlocks := p.lineWrapCharacterLimit - numVoteBlocks
|
|
||||||
|
|
||||||
voteBlockColor := p.theme.boldgreen
|
|
||||||
backgroundBlockColor := p.theme.grey
|
|
||||||
|
|
||||||
if p.noColor {
|
|
||||||
voteBlockColor = p.theme.reset
|
|
||||||
|
|
||||||
if numVoteBlocks == 0 {
|
|
||||||
numVoteBlocks = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
meter := "\n" + voteBlockColor + strings.Repeat(symbolPollMeter, numVoteBlocks) + p.theme.reset
|
|
||||||
|
|
||||||
if !p.noColor {
|
|
||||||
meter += backgroundBlockColor + strings.Repeat(symbolPollMeter, numBackgroundBlocks) + p.theme.reset
|
|
||||||
}
|
|
||||||
|
|
||||||
return meter
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ const (
|
||||||
noMediaDescription = "This media attachment has no description."
|
noMediaDescription = "This media attachment has no description."
|
||||||
symbolBullet = "\u2022"
|
symbolBullet = "\u2022"
|
||||||
symbolPollMeter = "\u2501"
|
symbolPollMeter = "\u2501"
|
||||||
symbolSuccess = "\u2714"
|
symbolCheckMark = "\u2714"
|
||||||
symbolFailure = "\u2717"
|
symbolFailure = "\u2717"
|
||||||
symbolImage = "\uf03e"
|
symbolImage = "\uf03e"
|
||||||
symbolLiked = "\uf51f"
|
symbolLiked = "\uf51f"
|
||||||
|
@ -78,9 +78,9 @@ func NewPrinter(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Printer) PrintSuccess(text string) {
|
func (p Printer) PrintSuccess(text string) {
|
||||||
success := p.theme.boldgreen + symbolSuccess + p.theme.reset
|
success := p.theme.boldgreen + symbolCheckMark + p.theme.reset
|
||||||
if p.noColor {
|
if p.noColor {
|
||||||
success = symbolSuccess
|
success = symbolCheckMark
|
||||||
}
|
}
|
||||||
|
|
||||||
printToStdout(success + " " + text + "\n")
|
printToStdout(success + " " + text + "\n")
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package printer
|
package printer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p Printer) PrintStatus(status model.Status) {
|
func (p Printer) PrintStatus(status model.Status, userAccountID string) {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
|
|
||||||
// The account information
|
// The account information
|
||||||
|
@ -41,7 +42,13 @@ func (p Printer) PrintStatus(status model.Status) {
|
||||||
|
|
||||||
// If a poll exists in a status, write the contents to the builder.
|
// If a poll exists in a status, write the contents to the builder.
|
||||||
if status.Poll != nil {
|
if status.Poll != nil {
|
||||||
builder.WriteString(p.pollOptions(*status.Poll))
|
pollOwner := false
|
||||||
|
if status.Account.ID == userAccountID {
|
||||||
|
pollOwner = true
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n\n" + p.headerFormat("POLL DETAILS:"))
|
||||||
|
builder.WriteString(p.pollDetails(*status.Poll, pollOwner))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status creation time
|
// Status creation time
|
||||||
|
@ -72,17 +79,18 @@ func (p Printer) PrintStatus(status model.Status) {
|
||||||
p.print(builder.String())
|
p.print(builder.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Printer) PrintStatusList(list model.StatusList) {
|
func (p Printer) PrintStatusList(list model.StatusList, userAccountID string) {
|
||||||
p.print(p.statusList(list))
|
p.print(p.statusList(list, userAccountID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Printer) statusList(list model.StatusList) string {
|
func (p Printer) statusList(list model.StatusList, userAccountID string) string {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
|
|
||||||
builder.WriteString(p.headerFormat(list.Name) + "\n")
|
builder.WriteString(p.headerFormat(list.Name) + "\n")
|
||||||
|
|
||||||
for _, status := range list.Statuses {
|
for _, status := range list.Statuses {
|
||||||
statusID := status.ID
|
statusID := status.ID
|
||||||
|
statusOwnerID := status.Account.ID
|
||||||
createdAt := p.formatDateTime(status.CreatedAt)
|
createdAt := p.formatDateTime(status.CreatedAt)
|
||||||
boostedAt := ""
|
boostedAt := ""
|
||||||
content := status.Content
|
content := status.Content
|
||||||
|
@ -100,6 +108,7 @@ func (p Printer) statusList(list model.StatusList) string {
|
||||||
))
|
))
|
||||||
|
|
||||||
statusID = status.Reblog.ID
|
statusID = status.Reblog.ID
|
||||||
|
statusOwnerID = status.Reblog.Account.ID
|
||||||
createdAt = p.formatDateTime(status.Reblog.CreatedAt)
|
createdAt = p.formatDateTime(status.Reblog.CreatedAt)
|
||||||
boostedAt = p.formatDateTime(status.CreatedAt)
|
boostedAt = p.formatDateTime(status.CreatedAt)
|
||||||
content = status.Reblog.Content
|
content = status.Reblog.Content
|
||||||
|
@ -120,7 +129,12 @@ func (p Printer) statusList(list model.StatusList) string {
|
||||||
builder.WriteString("\n" + p.convertHTMLToText(content, true))
|
builder.WriteString("\n" + p.convertHTMLToText(content, true))
|
||||||
|
|
||||||
if poll != nil {
|
if poll != nil {
|
||||||
builder.WriteString(p.pollOptions(*poll))
|
pollOwner := false
|
||||||
|
if statusOwnerID == userAccountID {
|
||||||
|
pollOwner = true
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString(p.pollDetails(*poll, pollOwner))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, media := range mediaAttachments {
|
for _, media := range mediaAttachments {
|
||||||
|
@ -172,3 +186,78 @@ func (p Printer) statusList(list model.StatusList) string {
|
||||||
|
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Printer) pollDetails(poll model.Poll, owner bool) string {
|
||||||
|
var builder strings.Builder
|
||||||
|
|
||||||
|
for ind, option := range poll.Options {
|
||||||
|
var (
|
||||||
|
votage float64
|
||||||
|
percentage int
|
||||||
|
)
|
||||||
|
|
||||||
|
// Show the poll results under any of the following conditions:
|
||||||
|
// - the user is the owner of the poll
|
||||||
|
// - the poll has expired
|
||||||
|
// - the user has voted in the poll
|
||||||
|
if owner || poll.Expired || poll.Voted {
|
||||||
|
if poll.VotesCount == 0 {
|
||||||
|
percentage = 0
|
||||||
|
} else {
|
||||||
|
votage = float64(option.VotesCount) / float64(poll.VotesCount)
|
||||||
|
percentage = int(math.Floor(100 * votage))
|
||||||
|
}
|
||||||
|
|
||||||
|
optionTitle := "\n\n" + "[" + strconv.Itoa(ind) + "] " + option.Title
|
||||||
|
|
||||||
|
for _, vote := range poll.OwnVotes {
|
||||||
|
if ind == vote {
|
||||||
|
optionTitle += " " + symbolCheckMark
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString(optionTitle)
|
||||||
|
builder.WriteString(p.pollMeter(votage))
|
||||||
|
builder.WriteString("\n" + strconv.Itoa(option.VotesCount) + " votes " + "(" + strconv.Itoa(percentage) + "%)")
|
||||||
|
} else {
|
||||||
|
builder.WriteString("\n" + "[" + strconv.Itoa(ind) + "] " + option.Title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pollStatusField := "Poll is open until: "
|
||||||
|
if poll.Expired {
|
||||||
|
pollStatusField = "Poll was closed on: "
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n\n" + p.fieldFormat(pollStatusField) + p.formatDateTime(poll.ExpiredAt))
|
||||||
|
builder.WriteString("\n" + p.fieldFormat("Total votes: ") + strconv.Itoa(poll.VotesCount))
|
||||||
|
builder.WriteString("\n" + p.fieldFormat("Multiple choices allowed: ") + strconv.FormatBool(poll.Multiple))
|
||||||
|
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Printer) pollMeter(votage float64) string {
|
||||||
|
numVoteBlocks := int(math.Floor(float64(p.lineWrapCharacterLimit) * votage))
|
||||||
|
numBackgroundBlocks := p.lineWrapCharacterLimit - numVoteBlocks
|
||||||
|
|
||||||
|
voteBlockColour := p.theme.boldgreen
|
||||||
|
backgroundBlockColor := p.theme.grey
|
||||||
|
|
||||||
|
if p.noColor {
|
||||||
|
voteBlockColour = p.theme.reset
|
||||||
|
|
||||||
|
if numVoteBlocks == 0 {
|
||||||
|
numVoteBlocks = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
meter := "\n" + voteBlockColour + strings.Repeat(symbolPollMeter, numVoteBlocks) + p.theme.reset
|
||||||
|
|
||||||
|
if !p.noColor {
|
||||||
|
meter += backgroundBlockColor + strings.Repeat(symbolPollMeter, numBackgroundBlocks) + p.theme.reset
|
||||||
|
}
|
||||||
|
|
||||||
|
return meter
|
||||||
|
}
|
||||||
|
|
|
@ -136,10 +136,6 @@
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"description": "Set to true to hide the vote count until the poll is closed"
|
"description": "Set to true to hide the vote count until the poll is closed"
|
||||||
},
|
},
|
||||||
"poll-id": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The ID of the poll"
|
|
||||||
},
|
|
||||||
"poll-option": {
|
"poll-option": {
|
||||||
"type": "StringSliceValue",
|
"type": "StringSliceValue",
|
||||||
"description": "A poll option. Use this multiple times to set multiple options"
|
"description": "A poll option. Use this multiple times to set multiple options"
|
||||||
|
@ -215,7 +211,6 @@
|
||||||
{ "flag": "account-name", "fieldName": "accountNames" },
|
{ "flag": "account-name", "fieldName": "accountNames" },
|
||||||
{ "flag": "content", "default": "" },
|
{ "flag": "content", "default": "" },
|
||||||
{ "flag": "list-id", "fieldName": "listID", "default": "" },
|
{ "flag": "list-id", "fieldName": "listID", "default": "" },
|
||||||
{ "flag": "poll-id", "fieldName": "pollID", "default": "" },
|
|
||||||
{ "flag": "status-id", "fieldName": "statusID", "default": "" },
|
{ "flag": "status-id", "fieldName": "statusID", "default": "" },
|
||||||
{ "flag": "to", "fieldName": "toResourceType", "default": "" },
|
{ "flag": "to", "fieldName": "toResourceType", "default": "" },
|
||||||
{ "flag": "type", "fieldName": "resourceType", "default": "" },
|
{ "flag": "type", "fieldName": "resourceType", "default": "" },
|
||||||
|
@ -367,7 +362,6 @@
|
||||||
{ "flag": "only-media", "default": "false" },
|
{ "flag": "only-media", "default": "false" },
|
||||||
{ "flag": "only-pinned", "default": "false" },
|
{ "flag": "only-pinned", "default": "false" },
|
||||||
{ "flag": "only-public", "default": "false" },
|
{ "flag": "only-public", "default": "false" },
|
||||||
{ "flag": "poll-id", "fieldName": "pollID", "default": "" },
|
|
||||||
{ "flag": "show-preferences", "fieldName": "showUserPreferences", "default": "false" },
|
{ "flag": "show-preferences", "fieldName": "showUserPreferences", "default": "false" },
|
||||||
{ "flag": "show-statuses", "default": "false" },
|
{ "flag": "show-statuses", "default": "false" },
|
||||||
{ "flag": "skip-relationship", "fieldName": "skipAccountRelationship", "default": "false" },
|
{ "flag": "skip-relationship", "fieldName": "skipAccountRelationship", "default": "false" },
|
||||||
|
|
Loading…
Reference in a new issue