From ca48d1bfce2a48eeb50e34e735c7d9bc59a0b37d Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Fri, 31 May 2024 00:11:02 +0100 Subject: [PATCH] feat: post a status from a file Allow users to post a status from a file using the --from-file flag. If both --content and --from-file flags are used then the --content flag takes precedence. --- internal/executor/add.go | 5 ++++- internal/executor/const.go | 1 + internal/executor/create.go | 26 +++++++++++++++++++++----- internal/executor/errors.go | 13 +++++++++++-- internal/utilities/file.go | 15 +++++++++++++++ 5 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 internal/utilities/file.go diff --git a/internal/executor/add.go b/internal/executor/add.go index d7956a8..9920986 100644 --- a/internal/executor/add.go +++ b/internal/executor/add.go @@ -133,7 +133,10 @@ func (a *AddExecutor) addNoteToAccount(gtsClient *client.Client) error { } if a.content == "" { - return EmptyContentError{} + return EmptyContentError{ + ResourceType: resourceNote, + Hint: "please use --" + flagContent, + } } if err := gtsClient.SetPrivateNote(accountID, a.content); err != nil { diff --git a/internal/executor/const.go b/internal/executor/const.go index 407973f..d3d48cd 100644 --- a/internal/executor/const.go +++ b/internal/executor/const.go @@ -10,6 +10,7 @@ const ( flagEnableReplies = "enable-replies" flagEnableReposts = "enable-reposts" flagFrom = "from" + flagFromFile = "from-file" flagInstance = "instance" flagLanguage = "language" flagLimit = "limit" diff --git a/internal/executor/create.go b/internal/executor/create.go index 274fec6..3f6c4f8 100644 --- a/internal/executor/create.go +++ b/internal/executor/create.go @@ -6,6 +6,7 @@ import ( "codeflow.dananglin.me.uk/apollo/enbas/internal/client" "codeflow.dananglin.me.uk/apollo/enbas/internal/model" + "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" ) type CreateExecutor struct { @@ -19,6 +20,7 @@ type CreateExecutor struct { sensitive bool content string contentType string + fromFile string language string spoilerText string resourceType string @@ -41,6 +43,7 @@ func NewCreateExecutor(tlf TopLevelFlags, name, summary string) *CreateExecutor createExe.BoolVar(&createExe.sensitive, flagSensitive, false, "specify if the status should be marked as sensitive") 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.StringVar(&createExe.fromFile, flagFromFile, "", "the file path where to read the contents from") createExe.StringVar(&createExe.language, flagLanguage, "", "the ISO 639 language code for this status") 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") @@ -103,15 +106,28 @@ func (c *CreateExecutor) createList(gtsClient *client.Client) error { } func (c *CreateExecutor) createStatus(gtsClient *client.Client) error { - if c.content == "" { - return FlagNotSetError{flagText: flagContent} - } - var ( + err error + content string language string visibility string ) + switch { + case c.content != "": + content = c.content + case c.fromFile != "": + content, err = utilities.ReadFile(c.fromFile) + if err != nil { + 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, + } + } + preferences, err := gtsClient.GetUserPreferences() if err != nil { fmt.Println("WARNING: Unable to get your posting preferences; %w", err) @@ -140,7 +156,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error { } form := client.CreateStatusForm{ - Content: c.content, + Content: content, ContentType: parsedContentType, Language: language, SpoilerText: c.spoilerText, diff --git a/internal/executor/errors.go b/internal/executor/errors.go index 766103a..f0c26e5 100644 --- a/internal/executor/errors.go +++ b/internal/executor/errors.go @@ -48,10 +48,19 @@ func (e UnsupportedRemoveOperationError) Error() string { return "removing '" + e.ResourceType + "' from '" + e.RemoveFromResourceType + "' is not supported" } -type EmptyContentError struct{} +type EmptyContentError struct{ + ResourceType string + Hint string +} func (e EmptyContentError) Error() string { - return "content should not be empty" + message := "the content of this " + e.ResourceType + " should not be empty" + + if e.Hint != "" { + message += ", " + e.Hint + } + + return message } type InvalidStatusVisibilityError struct { diff --git a/internal/utilities/file.go b/internal/utilities/file.go new file mode 100644 index 0000000..3c40e87 --- /dev/null +++ b/internal/utilities/file.go @@ -0,0 +1,15 @@ +package utilities + +import ( + "fmt" + "os" +) + +func ReadFile(path string) (string, error) { + data, err := os.ReadFile(path) + if err != nil { + return "", fmt.Errorf("unable to read the data from the file; %w", err) + } + + return string(data), nil +}