diff --git a/docs/manual.md b/docs/manual.md index a89a464..aae11bb 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -453,6 +453,8 @@ enbas show --type status --status-id 01J1Z9PT0243JT9QNQ5W96Z8CA ### Create a status +Creates a new status. + - Create a simple status that is publicly visible. ``` enbas create --type status --content-type plain --visibility public --content "Hello, Fediverse!" @@ -531,7 +533,19 @@ Additional flags for polls. ### Delete a status -_Not yet supported_ +Deletes a status that belongs to you. +You can optionally save the text of the deleted status for redrafting purposes. +The saved text will be written to a text file within your cache directory. + +``` +enbas delete --type status --status-id 01J5B0N6DKZGYPQEZW9HWKV0VA +``` + +| flag | type | required | description | default | +|------|------|----------|-------------|---------| +| `type` | string | true | The resource you want to delete.
Here this should be `status`. | | +| `status-id` | string | true | The ID of the status that you want to delete. | | +| `save-text` | bool | false | Set to `true` to save the text of the deleted status. | false | ### Boost (Repost) a status diff --git a/internal/client/statuses.go b/internal/client/statuses.go index 9dc1e16..b005694 100644 --- a/internal/client/statuses.go +++ b/internal/client/statuses.go @@ -311,3 +311,26 @@ func (g *Client) UnmuteStatus(statusID string) error { 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..8bfe8a9 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 the status does not belong to you") + } + + 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 text was successfully saved to '" + path + "'.") + } + + return nil +} diff --git a/internal/executor/executors.go b/internal/executor/executors.go index 2b48d57..3b5ab40 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 13762f4..2ab3749 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",