feat: deleting statuses #48

Manually merged
dananglin merged 1 commit from delete-a-status into main 2024-08-16 19:00:43 +01:00
6 changed files with 119 additions and 3 deletions
Showing only changes of commit c0f1f7d03a - Show all commits

View file

@ -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.<br>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

View file

@ -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
}

View file

@ -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 {
@ -13,6 +16,7 @@ func (d *DeleteExecutor) Execute() error {
funcMap := map[string]func(*client.Client) error{
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
}

View file

@ -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

View file

@ -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
}

View file

@ -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"
@ -278,6 +282,8 @@
"additionalFields": [],
"flags": [
{ "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",