Compare commits
4 commits
1cd451ae72
...
87d8f0ad04
Author | SHA1 | Date | |
---|---|---|---|
87d8f0ad04 | |||
72eff2b654 | |||
b98c0fc993 | |||
f223e0417c |
19 changed files with 182 additions and 131 deletions
|
@ -79,10 +79,9 @@ func (g *Client) DownloadMedia(url, path string) error {
|
|||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf(
|
||||
"did not receive an OK response from the GoToSocial server: got %d",
|
||||
response.StatusCode,
|
||||
)
|
||||
return BadStatusCodeError{
|
||||
statusCode: response.StatusCode,
|
||||
}
|
||||
}
|
||||
|
||||
file, err := os.Create(path)
|
||||
|
|
|
@ -30,3 +30,22 @@ func (e ResponseError) Error() string {
|
|||
e.Message,
|
||||
)
|
||||
}
|
||||
|
||||
type BadStatusCodeError struct {
|
||||
statusCode int
|
||||
}
|
||||
|
||||
func (e BadStatusCodeError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"did not receive an OK response from the GoToSocial server: got %d",
|
||||
e.statusCode,
|
||||
)
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (e Error) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
|
|
@ -3,15 +3,12 @@ package client
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal"
|
||||
)
|
||||
|
||||
var errEmptyAccessToken = errors.New("received an empty access token")
|
||||
|
||||
type tokenRequest struct {
|
||||
RedirectURI string `json:"redirect_uri"`
|
||||
ClientID string `json:"client_id"`
|
||||
|
@ -59,7 +56,7 @@ func (g *Client) UpdateToken(code string) error {
|
|||
}
|
||||
|
||||
if response.AccessToken == "" {
|
||||
return errEmptyAccessToken
|
||||
return Error{"received an empty access token"}
|
||||
}
|
||||
|
||||
g.Authentication.AccessToken = response.AccessToken
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package executor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||
|
@ -40,8 +39,8 @@ func (a *AddExecutor) addToList(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[a.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedAddOperationError{
|
||||
ResourceType: a.resourceType,
|
||||
AddToResourceType: a.toResourceType,
|
||||
resourceType: a.resourceType,
|
||||
addToResourceType: a.toResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +70,7 @@ func (a *AddExecutor) addAccountsToList(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
if !relationship.Following {
|
||||
return NotFollowingError{Account: accounts[ind].Acct}
|
||||
return NotFollowingError{account: accounts[ind].Acct}
|
||||
}
|
||||
|
||||
accountIDs[ind] = accounts[ind].ID
|
||||
|
@ -94,8 +93,8 @@ func (a *AddExecutor) addToAccount(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[a.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedAddOperationError{
|
||||
ResourceType: a.resourceType,
|
||||
AddToResourceType: a.toResourceType,
|
||||
resourceType: a.resourceType,
|
||||
addToResourceType: a.toResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +108,7 @@ func (a *AddExecutor) addNoteToAccount(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
if a.content == "" {
|
||||
return errors.New("please add content to the status that you want to create")
|
||||
return Error{"please add content to the note you want to add"}
|
||||
}
|
||||
|
||||
if err := gtsClient.SetPrivateNote(accountID, a.content); err != nil {
|
||||
|
@ -129,8 +128,8 @@ func (a *AddExecutor) addToBookmarks(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[a.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedAddOperationError{
|
||||
ResourceType: a.resourceType,
|
||||
AddToResourceType: a.toResourceType,
|
||||
resourceType: a.resourceType,
|
||||
addToResourceType: a.toResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,8 +165,8 @@ func (a *AddExecutor) addToStatus(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[a.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedAddOperationError{
|
||||
ResourceType: a.resourceType,
|
||||
AddToResourceType: a.toResourceType,
|
||||
resourceType: a.resourceType,
|
||||
addToResourceType: a.toResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +195,7 @@ func (a *AddExecutor) addBoostToStatus(gtsClient *client.Client) error {
|
|||
|
||||
func (a *AddExecutor) addVoteToStatus(gtsClient *client.Client) error {
|
||||
if a.votes.Empty() {
|
||||
return NoVotesError{}
|
||||
return Error{"please add your vote(s) to the poll"}
|
||||
}
|
||||
|
||||
status, err := gtsClient.GetStatus(a.statusID)
|
||||
|
@ -205,15 +204,15 @@ func (a *AddExecutor) addVoteToStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
if status.Poll == nil {
|
||||
return NoPollInStatusError{}
|
||||
return Error{"this status does not have a poll"}
|
||||
}
|
||||
|
||||
if status.Poll.Expired {
|
||||
return PollClosedError{}
|
||||
return Error{"this poll is closed"}
|
||||
}
|
||||
|
||||
if !status.Poll.Multiple && !a.votes.ExpectedLength(1) {
|
||||
return MultipleChoiceError{}
|
||||
return Error{"this poll does not allow multiple choices"}
|
||||
}
|
||||
|
||||
myAccountID, err := getAccountID(gtsClient, true, nil)
|
||||
|
@ -222,7 +221,7 @@ func (a *AddExecutor) addVoteToStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
if status.Account.ID == myAccountID {
|
||||
return PollOwnerVoteError{}
|
||||
return Error{"you cannot vote in your own poll"}
|
||||
}
|
||||
|
||||
pollID := status.Poll.ID
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package executor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||
|
@ -72,27 +71,35 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
if !c.mediaFiles.Empty() {
|
||||
descriptionsExists := false
|
||||
focusValuesExists := false
|
||||
expectedLength := len(c.mediaFiles)
|
||||
mediaDescriptions := make([]string, expectedLength)
|
||||
numMediaFiles := len(c.mediaFiles)
|
||||
mediaDescriptions := make([]string, numMediaFiles)
|
||||
|
||||
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.mediaDescriptions.ExpectedLength(numMediaFiles) {
|
||||
return MismatchedNumMediaValuesError{
|
||||
valueType: "media descriptions",
|
||||
numValues: len(c.mediaDescriptions),
|
||||
numMediaFiles: numMediaFiles,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 !c.mediaFocusValues.ExpectedLength(numMediaFiles) {
|
||||
return MismatchedNumMediaValuesError{
|
||||
valueType: "media focus values",
|
||||
numValues: len(c.mediaFocusValues),
|
||||
numMediaFiles: numMediaFiles,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if descriptionsExists {
|
||||
for ind := 0; ind < expectedLength; ind++ {
|
||||
for ind := 0; ind < numMediaFiles; ind++ {
|
||||
mediaDesc, err := utilities.ReadContents(c.mediaDescriptions[ind])
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read the contents from %s: %w", c.mediaDescriptions[ind], err)
|
||||
|
@ -102,7 +109,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
}
|
||||
|
||||
for ind := 0; ind < expectedLength; ind++ {
|
||||
for ind := 0; ind < numMediaFiles; ind++ {
|
||||
var (
|
||||
mediaFile string
|
||||
description string
|
||||
|
@ -133,7 +140,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
if c.content == "" && len(attachmentIDs) == 0 {
|
||||
return errors.New("please add content to the status that you want to create")
|
||||
return Error{"please add content to the status that you want to create"}
|
||||
}
|
||||
|
||||
content, err := utilities.ReadContents(c.content)
|
||||
|
@ -144,7 +151,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
numAttachmentIDs := len(attachmentIDs)
|
||||
|
||||
if c.addPoll && numAttachmentIDs > 0 {
|
||||
return fmt.Errorf("attaching media to a poll is not allowed")
|
||||
return Error{"attaching media to a poll is not allowed"}
|
||||
}
|
||||
|
||||
preferences, err := gtsClient.GetUserPreferences()
|
||||
|
@ -202,7 +209,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
|
||||
if c.addPoll {
|
||||
if len(c.pollOptions) == 0 {
|
||||
return NoPollOptionError{}
|
||||
return Error{"no options were provided for this poll"}
|
||||
}
|
||||
|
||||
poll := client.CreateStatusPollForm{
|
||||
|
@ -228,27 +235,31 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error {
|
|||
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,
|
||||
)
|
||||
return UnexpectedNumValuesError{
|
||||
name: "media files",
|
||||
expected: expectedNumValues,
|
||||
actual: len(c.mediaFiles),
|
||||
}
|
||||
}
|
||||
|
||||
description := ""
|
||||
if !c.mediaDescriptions.Empty() {
|
||||
if !c.mediaDescriptions.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media descriptions: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
return UnexpectedNumValuesError{
|
||||
name: "media descriptions",
|
||||
expected: expectedNumValues,
|
||||
actual: len(c.mediaDescriptions),
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
description, err = utilities.ReadContents(c.mediaDescriptions[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"unable to read the contents from %s: %w",
|
||||
c.mediaDescriptions[0],
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -256,11 +267,13 @@ func (c *CreateExecutor) createMediaAttachment(gtsClient *client.Client) error {
|
|||
focus := ""
|
||||
if !c.mediaFocusValues.Empty() {
|
||||
if !c.mediaFocusValues.ExpectedLength(expectedNumValues) {
|
||||
return fmt.Errorf(
|
||||
"received an unexpected number of media focus values: want %d",
|
||||
expectedNumValues,
|
||||
)
|
||||
return UnexpectedNumValuesError{
|
||||
name: "media focus values",
|
||||
expected: expectedNumValues,
|
||||
actual: len(c.mediaFocusValues),
|
||||
}
|
||||
}
|
||||
|
||||
focus = c.mediaFocusValues[0]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package executor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
|
@ -62,7 +61,7 @@ func (d *DeleteExecutor) deleteStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
if status.Account.ID != myAccountID {
|
||||
return errors.New("unable to delete the status because the status does not belong to you")
|
||||
return Error{"unable to delete the status because the status does not belong to you"}
|
||||
}
|
||||
|
||||
text, err := gtsClient.DeleteStatus(d.statusID)
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
package executor
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Error struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (e Error) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
type FlagNotSetError struct {
|
||||
flagText string
|
||||
}
|
||||
|
@ -23,94 +33,87 @@ func (e NoAccountSpecifiedError) Error() string {
|
|||
}
|
||||
|
||||
type UnsupportedAddOperationError struct {
|
||||
ResourceType string
|
||||
AddToResourceType string
|
||||
resourceType string
|
||||
addToResourceType string
|
||||
}
|
||||
|
||||
func (e UnsupportedAddOperationError) Error() string {
|
||||
return "adding '" +
|
||||
e.ResourceType +
|
||||
e.resourceType +
|
||||
"' to '" +
|
||||
e.AddToResourceType +
|
||||
e.addToResourceType +
|
||||
"' is not supported"
|
||||
}
|
||||
|
||||
type UnsupportedRemoveOperationError struct {
|
||||
ResourceType string
|
||||
RemoveFromResourceType string
|
||||
resourceType string
|
||||
removeFromResourceType string
|
||||
}
|
||||
|
||||
func (e UnsupportedRemoveOperationError) Error() string {
|
||||
return "removing '" +
|
||||
e.ResourceType +
|
||||
e.resourceType +
|
||||
"' from '" +
|
||||
e.RemoveFromResourceType +
|
||||
e.removeFromResourceType +
|
||||
"' is not supported"
|
||||
}
|
||||
|
||||
type UnsupportedShowOperationError struct {
|
||||
ResourceType string
|
||||
ShowFromResourceType string
|
||||
resourceType string
|
||||
showFromResourceType string
|
||||
}
|
||||
|
||||
func (e UnsupportedShowOperationError) Error() string {
|
||||
return "showing '" +
|
||||
e.ResourceType +
|
||||
e.resourceType +
|
||||
"' from '" +
|
||||
e.ShowFromResourceType +
|
||||
e.showFromResourceType +
|
||||
"' is not supported"
|
||||
}
|
||||
|
||||
type UnknownCommandError struct {
|
||||
Command string
|
||||
command string
|
||||
}
|
||||
|
||||
func (e UnknownCommandError) Error() string {
|
||||
return "unknown command '" + e.Command + "'"
|
||||
}
|
||||
|
||||
type PollClosedError struct{}
|
||||
|
||||
func (e PollClosedError) Error() string {
|
||||
return "this poll is closed"
|
||||
}
|
||||
|
||||
type MultipleChoiceError struct{}
|
||||
|
||||
func (e MultipleChoiceError) Error() string {
|
||||
return "this poll does not allow multiple choices"
|
||||
}
|
||||
|
||||
type NoPollOptionError struct{}
|
||||
|
||||
func (e NoPollOptionError) Error() string {
|
||||
return "no options were provided for this poll, please use the --" +
|
||||
flagPollOption +
|
||||
" flag to add options to the poll"
|
||||
}
|
||||
|
||||
type NoVotesError struct{}
|
||||
|
||||
func (e NoVotesError) Error() string {
|
||||
return "no votes were made, please add your vote(s) using the --vote flag"
|
||||
}
|
||||
|
||||
type NoPollInStatusError struct{}
|
||||
|
||||
func (e NoPollInStatusError) Error() string {
|
||||
return "this status does not have a poll"
|
||||
}
|
||||
|
||||
type PollOwnerVoteError struct{}
|
||||
|
||||
func (e PollOwnerVoteError) Error() string {
|
||||
return "you cannot vote in your own poll"
|
||||
return "unknown command '" + e.command + "'"
|
||||
}
|
||||
|
||||
type NotFollowingError struct {
|
||||
Account string
|
||||
account string
|
||||
}
|
||||
|
||||
func (e NotFollowingError) Error() string {
|
||||
return "you are not following " + e.Account
|
||||
return "you are not following " + e.account
|
||||
}
|
||||
|
||||
type MismatchedNumMediaValuesError struct {
|
||||
valueType string
|
||||
numValues int
|
||||
numMediaFiles int
|
||||
}
|
||||
|
||||
func (e MismatchedNumMediaValuesError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"unexpected number of %s: received %d media files but got %d %s",
|
||||
e.valueType,
|
||||
e.numMediaFiles,
|
||||
e.numValues,
|
||||
e.valueType,
|
||||
)
|
||||
}
|
||||
|
||||
type UnexpectedNumValuesError struct {
|
||||
name string
|
||||
actual int
|
||||
expected int
|
||||
}
|
||||
|
||||
func (e UnexpectedNumValuesError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"received an unexpected number of %s: received %d, expected %d",
|
||||
e.name,
|
||||
e.actual,
|
||||
e.expected,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ func execute(
|
|||
|
||||
exe, ok := executorMap[command]
|
||||
if !ok {
|
||||
return UnknownCommandError{Command: command}
|
||||
return UnknownCommandError{command: command}
|
||||
}
|
||||
|
||||
if err := exe.Parse(args); err != nil {
|
||||
|
|
|
@ -184,7 +184,7 @@ func NewCreateExecutor(
|
|||
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.spoilerText, "spoiler-text", "", "The subject, summary or content warning for the status")
|
||||
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")
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ const (
|
|||
flagInstance = "instance"
|
||||
flagListID = "list-id"
|
||||
flagListTitle = "list-title"
|
||||
flagPollOption = "poll-option"
|
||||
flagStatusID = "status-id"
|
||||
flagTag = "tag"
|
||||
flagTo = "to"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package executor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||
|
@ -69,13 +68,14 @@ func (m *MuteExecutor) muteStatus(gtsClient *client.Client) error {
|
|||
for _, mention := range status.Mentions {
|
||||
if mention.ID == myAccountID {
|
||||
canMute = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !canMute {
|
||||
return errors.New("unable to mute the status because you are not the owner and you are not mentioned in it")
|
||||
return Error{"unable to mute the status because you are not the owner and you are not mentioned in it"}
|
||||
}
|
||||
|
||||
if err := gtsClient.MuteStatus(m.statusID); err != nil {
|
||||
|
|
|
@ -39,8 +39,8 @@ func (r *RemoveExecutor) removeFromList(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[r.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedRemoveOperationError{
|
||||
ResourceType: r.resourceType,
|
||||
RemoveFromResourceType: r.fromResourceType,
|
||||
resourceType: r.resourceType,
|
||||
removeFromResourceType: r.fromResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,8 +84,8 @@ func (r *RemoveExecutor) removeFromAccount(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[r.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedRemoveOperationError{
|
||||
ResourceType: r.resourceType,
|
||||
RemoveFromResourceType: r.fromResourceType,
|
||||
resourceType: r.resourceType,
|
||||
removeFromResourceType: r.fromResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,8 @@ func (r *RemoveExecutor) removeFromBookmarks(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[r.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedRemoveOperationError{
|
||||
ResourceType: r.resourceType,
|
||||
RemoveFromResourceType: r.fromResourceType,
|
||||
resourceType: r.resourceType,
|
||||
removeFromResourceType: r.fromResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,8 +151,8 @@ func (r *RemoveExecutor) removeFromStatus(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[r.resourceType]
|
||||
if !ok {
|
||||
return UnsupportedRemoveOperationError{
|
||||
ResourceType: r.resourceType,
|
||||
RemoveFromResourceType: r.fromResourceType,
|
||||
resourceType: r.resourceType,
|
||||
removeFromResourceType: r.fromResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -257,8 +257,8 @@ func (s *ShowExecutor) showFollowers(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[s.fromResourceType]
|
||||
if !ok {
|
||||
return UnsupportedShowOperationError{
|
||||
ResourceType: s.resourceType,
|
||||
ShowFromResourceType: s.fromResourceType,
|
||||
resourceType: s.resourceType,
|
||||
showFromResourceType: s.fromResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,8 +297,8 @@ func (s *ShowExecutor) showFollowing(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[s.fromResourceType]
|
||||
if !ok {
|
||||
return UnsupportedShowOperationError{
|
||||
ResourceType: s.resourceType,
|
||||
ShowFromResourceType: s.fromResourceType,
|
||||
resourceType: s.resourceType,
|
||||
showFromResourceType: s.fromResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,8 +444,8 @@ func (s *ShowExecutor) showMedia(gtsClient *client.Client) error {
|
|||
doFunc, ok := funcMap[s.fromResourceType]
|
||||
if !ok {
|
||||
return UnsupportedShowOperationError{
|
||||
ResourceType: s.resourceType,
|
||||
ShowFromResourceType: s.fromResourceType,
|
||||
resourceType: s.resourceType,
|
||||
showFromResourceType: s.fromResourceType,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package executor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||
|
@ -64,13 +63,14 @@ func (m *UnmuteExecutor) unmuteStatus(gtsClient *client.Client) error {
|
|||
for _, mention := range status.Mentions {
|
||||
if mention.ID == myAccountID {
|
||||
canUnmute = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !canUnmute {
|
||||
return errors.New("unable to unmute the status because you are not the owner and you are not mentioned in it")
|
||||
return Error{"unable to unmute the status because you are not the owner and you are not mentioned in it"}
|
||||
}
|
||||
|
||||
if err := gtsClient.UnmuteStatus(m.statusID); err != nil {
|
||||
|
|
|
@ -28,7 +28,7 @@ type Status struct {
|
|||
ReblogsCount int `json:"reblogs_count"`
|
||||
RepliesCount int `json:"replies_count"`
|
||||
Sensitive bool `json:"sensitive"`
|
||||
SpolierText string `json:"spoiler_text"`
|
||||
SpoilerText string `json:"spoiler_text"`
|
||||
Tags []Tag `json:"tags"`
|
||||
Text string `json:"text"`
|
||||
URI string `json:"uri"`
|
||||
|
@ -83,7 +83,7 @@ type StatusReblogged struct {
|
|||
RebloggsCount int `json:"reblogs_count"`
|
||||
RepliesCount int `json:"replies_count"`
|
||||
Sensitive bool `json:"sensitive"`
|
||||
SpolierText string `json:"spoiler_text"`
|
||||
SpoilerText string `json:"spoiler_text"`
|
||||
Tags []Tag `json:"tags"`
|
||||
Text string `json:"text"`
|
||||
URI string `json:"uri"`
|
||||
|
|
|
@ -27,6 +27,7 @@ const (
|
|||
|
||||
type theme struct {
|
||||
reset string
|
||||
bold string
|
||||
boldblue string
|
||||
boldmagenta string
|
||||
green string
|
||||
|
@ -53,6 +54,7 @@ func NewPrinter(
|
|||
) *Printer {
|
||||
theme := theme{
|
||||
reset: "\033[0m",
|
||||
bold: "\033[1m",
|
||||
boldblue: "\033[34;1m",
|
||||
boldmagenta: "\033[35;1m",
|
||||
green: "\033[32m",
|
||||
|
@ -115,6 +117,14 @@ func (p Printer) fieldFormat(text string) string {
|
|||
return p.theme.green + text + p.theme.reset
|
||||
}
|
||||
|
||||
func (p Printer) bold(text string) string {
|
||||
if p.noColor {
|
||||
return text
|
||||
}
|
||||
|
||||
return p.theme.bold + text + p.theme.reset
|
||||
}
|
||||
|
||||
func (p Printer) fullDisplayNameFormat(displayName, acct string) string {
|
||||
// use this pattern to remove all emoji strings
|
||||
pattern := regexp.MustCompile(`\s:[A-Za-z0-9_]*:`)
|
||||
|
@ -133,11 +143,11 @@ func (p Printer) fullDisplayNameFormat(displayName, acct string) string {
|
|||
}
|
||||
|
||||
func (p Printer) formatDate(date time.Time) string {
|
||||
return date.Local().Format(dateFormat)
|
||||
return date.Local().Format(dateFormat) //nolint:gosmopolitan
|
||||
}
|
||||
|
||||
func (p Printer) formatDateTime(date time.Time) string {
|
||||
return date.Local().Format(dateTimeFormat)
|
||||
return date.Local().Format(dateTimeFormat) //nolint:gosmopolitan
|
||||
}
|
||||
|
||||
func (p Printer) print(text string) {
|
||||
|
|
|
@ -18,6 +18,12 @@ func (p Printer) PrintStatus(status model.Status, userAccountID string) {
|
|||
builder.WriteString("\n\n" + p.headerFormat("STATUS ID:"))
|
||||
builder.WriteString("\n" + status.ID)
|
||||
|
||||
// The subject, summary of content warning of the status
|
||||
if status.SpoilerText != "" {
|
||||
builder.WriteString("\n\n" + p.headerFormat("SUMMARY:"))
|
||||
builder.WriteString("\n" + status.SpoilerText)
|
||||
}
|
||||
|
||||
// The content of the status.
|
||||
builder.WriteString("\n\n" + p.headerFormat("CONTENT:"))
|
||||
builder.WriteString(p.convertHTMLToText(status.Content, true))
|
||||
|
@ -97,6 +103,7 @@ func (p Printer) statusList(list model.StatusList, userAccountID string) string
|
|||
content := status.Content
|
||||
poll := status.Poll
|
||||
mediaAttachments := status.MediaAttachments
|
||||
summary := status.SpoilerText
|
||||
|
||||
switch {
|
||||
case status.Reblog != nil:
|
||||
|
@ -115,6 +122,8 @@ func (p Printer) statusList(list model.StatusList, userAccountID string) string
|
|||
content = status.Reblog.Content
|
||||
poll = status.Reblog.Poll
|
||||
mediaAttachments = status.Reblog.MediaAttachments
|
||||
summary = status.Reblog.SpoilerText
|
||||
|
||||
case status.InReplyToID != "":
|
||||
builder.WriteString("\n" + p.wrapLines(
|
||||
p.fullDisplayNameFormat(status.Account.DisplayName, status.Account.Acct)+
|
||||
|
@ -127,6 +136,10 @@ func (p Printer) statusList(list model.StatusList, userAccountID string) string
|
|||
builder.WriteString("\n" + p.fullDisplayNameFormat(status.Account.DisplayName, status.Account.Acct) + " posted:")
|
||||
}
|
||||
|
||||
if summary != "" {
|
||||
builder.WriteString("\n\n" + p.bold(p.wrapLines(summary, 0)))
|
||||
}
|
||||
|
||||
builder.WriteString("\n" + p.convertHTMLToText(content, true))
|
||||
|
||||
if poll != nil {
|
||||
|
|
|
@ -50,7 +50,7 @@ func OpenLink(browser, url string) error {
|
|||
cmd := strings.Split(browser, " ")
|
||||
cmd = append(cmd, url)
|
||||
|
||||
command := exec.Command(cmd[0], cmd[1:]...)
|
||||
command := exec.Command(cmd[0], cmd[1:]...) //nolint:gosec
|
||||
|
||||
if err := command.Start(); err != nil {
|
||||
return fmt.Errorf("received an error after starting the program to view the link: %w", err)
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
},
|
||||
"spoiler-text": {
|
||||
"type": "string",
|
||||
"description": "The text to display as the status' warning or subject"
|
||||
"description": "The subject, summary or content warning for the status"
|
||||
},
|
||||
"status-id": {
|
||||
"type": "string",
|
||||
|
|
Loading…
Reference in a new issue