diff --git a/example/config.json b/example/config.json new file mode 100644 index 0000000..0e3be4c --- /dev/null +++ b/example/config.json @@ -0,0 +1,16 @@ +{ + "credentialsFile": "~/.config/enbas/credentials.json", + "cacheDirectory": "~/.cache/enbas", + "lineWrapMaxWidth": 80, + "http": { + "timeout": 5, + "mediaTimeout": 30 + }, + "integrations": { + "browser": "firefox", + "editor": "vim", + "pager": "less -FIRX", + "imageViewer": "feh --scale-down", + "videoPlayer": "mpv" + } +} diff --git a/internal/client/statuses.go b/internal/client/statuses.go index 0b8d60a..130a65b 100644 --- a/internal/client/statuses.go +++ b/internal/client/statuses.go @@ -241,7 +241,7 @@ func (g *Client) ReblogStatus(statusID string) error { if err := g.sendRequest(params); err != nil { return fmt.Errorf( - "received an error after sending the request to reblog the status; %w", + "received an error after sending the request to reblog the status: %w", err, ) } @@ -262,10 +262,33 @@ func (g *Client) UnreblogStatus(statusID string) error { if err := g.sendRequest(params); err != nil { return fmt.Errorf( - "received an error after sending the request to un-reblog the status; %w", + "received an error after sending the request to un-reblog the status: %w", err, ) } return nil } + +func (g *Client) DeleteStatus(statusID string) (string, error) { + url := g.Authentication.Instance + baseStatusesPath + "/" + statusID + + var status model.Status + + params := requestParameters{ + httpMethod: http.MethodDelete, + url: url, + requestBody: nil, + contentType: "", + output: &status, + } + + if err := g.sendRequest(params); err != nil { + return "", fmt.Errorf( + "received an error after sending the request to delete the status: %w", + err, + ) + } + + return status.Text, nil +} diff --git a/internal/executor/delete.go b/internal/executor/delete.go index 0b27fc5..7de803f 100644 --- a/internal/executor/delete.go +++ b/internal/executor/delete.go @@ -1,9 +1,12 @@ package executor import ( + "errors" "fmt" + "path/filepath" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" + "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" ) func (d *DeleteExecutor) Execute() error { @@ -12,7 +15,8 @@ func (d *DeleteExecutor) Execute() error { } funcMap := map[string]func(*client.Client) error{ - resourceList: d.deleteList, + resourceList: d.deleteList, + resourceStatus: d.deleteStatus, } doFunc, ok := funcMap[d.resourceType] @@ -41,3 +45,54 @@ func (d *DeleteExecutor) deleteList(gtsClient *client.Client) error { return nil } + +func (d *DeleteExecutor) deleteStatus(gtsClient *client.Client) error { + if d.statusID == "" { + return FlagNotSetError{flagText: flagStatusID} + } + + status, err := gtsClient.GetStatus(d.statusID) + if err != nil { + return fmt.Errorf("unable to get the status: %w", err) + } + + myAccountID, err := getAccountID(gtsClient, true, nil) + if err != nil { + return fmt.Errorf("unable to get your account ID: %w", err) + } + + if status.Account.ID != myAccountID { + return errors.New("unable to delete the status because you are not the owner") + } + + text, err := gtsClient.DeleteStatus(d.statusID) + if err != nil { + return fmt.Errorf("unable to delete the status: %w", err) + } + + d.printer.PrintSuccess("The status was successfully deleted.") + + if d.saveText { + cacheDir := filepath.Join( + utilities.CalculateCacheDir( + d.config.CacheDirectory, + utilities.GetFQDN(gtsClient.Authentication.Instance), + ), + "statuses", + ) + + if err := utilities.EnsureDirectory(cacheDir); err != nil { + return fmt.Errorf("unable to ensure the existence of the directory %q: %w", cacheDir, err) + } + + path := filepath.Join(cacheDir, fmt.Sprintf("deleted-status-%s.txt", d.statusID)) + + if err := utilities.SaveTextToFile(path, text); err != nil { + return fmt.Errorf("unable to save the text to %q: %w", path, err) + } + + d.printer.PrintSuccess("The status' text was successfully written to '" + path + "'.") + } + + return nil +} diff --git a/internal/executor/executors.go b/internal/executor/executors.go index 1ef1ee1..a2d504c 100644 --- a/internal/executor/executors.go +++ b/internal/executor/executors.go @@ -199,6 +199,8 @@ type DeleteExecutor struct { printer *printer.Printer config *config.Config listID string + saveText bool + statusID string resourceType string } @@ -215,6 +217,8 @@ func NewDeleteExecutor( exe.Usage = usage.ExecutorUsageFunc("delete", "Deletes a specific resource", exe.FlagSet) exe.StringVar(&exe.listID, "list-id", "", "The ID of the list in question") + exe.BoolVar(&exe.saveText, "save-text", false, "Set to true to save the text of the deleted status") + exe.StringVar(&exe.statusID, "status-id", "", "The ID of the status") exe.StringVar(&exe.resourceType, "type", "", "The type of resource you want to action on (e.g. account, status)") return &exe diff --git a/internal/utilities/file.go b/internal/utilities/file.go index ffbdc2c..5e857ef 100644 --- a/internal/utilities/file.go +++ b/internal/utilities/file.go @@ -55,3 +55,17 @@ func FileExists(path string) (bool, error) { return true, nil } + +func SaveTextToFile(path, text string) error { + file, err := os.Create(path) + if err != nil { + return fmt.Errorf("unable to open %q: %w", path, err) + } + defer file.Close() + + if _, err := fmt.Fprint(file, text); err != nil { + return fmt.Errorf("received an error writing the text to the file: %w", err) + } + + return nil +} diff --git a/schema/enbas_cli_schema.json b/schema/enbas_cli_schema.json index 3199e0a..c88f6cc 100644 --- a/schema/enbas_cli_schema.json +++ b/schema/enbas_cli_schema.json @@ -152,6 +152,10 @@ "type": "StringSliceValue", "description": "A poll option. Use this multiple times to set multiple options" }, + "save-text": { + "type": "bool", + "description": "Set to true to save the text of the deleted status" + }, "sensitive": { "type": "BoolPtrValue", "description": "Set to true if the status should be marked as sensitive" @@ -277,7 +281,9 @@ "delete": { "additionalFields": [], "flags": [ - { "flag": "list-id", "fieldName": "listID", "default": ""}, + { "flag": "list-id", "fieldName": "listID", "default": ""}, + { "flag": "save-text", "default": "false" }, + { "flag": "status-id", "fieldName": "statusID", "default": "" }, { "flag": "type", "fieldName": "resourceType", "default": "" } ], "summary": "Deletes a specific resource",