From dd76a9a857d7a7c400403704e7c9cb6d43ed7868 Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Mon, 3 Jun 2024 06:53:31 +0100 Subject: [PATCH] feat: add bookmark support Add support for viewing the user's list of bookmarks, as well as adding and removing statuses from the list. --- internal/client/statuses.go | 48 +++++++++++++++++++++++++++++++++++++ internal/executor/add.go | 39 +++++++++++++++++++++++++++--- internal/executor/const.go | 1 + internal/executor/remove.go | 45 +++++++++++++++++++++++++++++----- internal/executor/show.go | 16 +++++++++++++ 5 files changed, 140 insertions(+), 9 deletions(-) diff --git a/internal/client/statuses.go b/internal/client/statuses.go index 30a1086..89e1655 100644 --- a/internal/client/statuses.go +++ b/internal/client/statuses.go @@ -62,3 +62,51 @@ func (g *Client) CreateStatus(form CreateStatusForm) (model.Status, error) { return status, nil } + +func (g *Client) GetBookmarks(limit int) (model.StatusList, error) { + path := fmt.Sprintf("/api/v1/bookmarks?limit=%d", limit) + url := g.Authentication.Instance + path + + bookmarks := model.StatusList{ + Type: model.StatusListBookMarks, + Name: "BOOKMARKS", + Statuses: nil, + } + + if err := g.sendRequest(http.MethodGet, url, nil, &bookmarks.Statuses); err != nil { + return bookmarks, fmt.Errorf( + "received an error after sending the request to get the bookmarks: %w", + err, + ) + } + + return bookmarks, nil +} + +func (g *Client) AddStatusToBookmarks(statusID string) error { + path := fmt.Sprintf("/api/v1/statuses/%s/bookmark", statusID) + url := g.Authentication.Instance + path + + if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil { + return fmt.Errorf( + "received an error after sending the request to add the status to the list of bookmarks: %w", + err, + ) + } + + return nil +} + +func (g *Client) RemoveStatusFromBookmarks(statusID string) error { + path := fmt.Sprintf("/api/v1/statuses/%s/unbookmark", statusID) + url := g.Authentication.Instance + path + + if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil { + return fmt.Errorf( + "received an error after sending the request to remove the status from the list of bookmarks: %w", + err, + ) + } + + return nil +} diff --git a/internal/executor/add.go b/internal/executor/add.go index 567ef4d..46fa0fb 100644 --- a/internal/executor/add.go +++ b/internal/executor/add.go @@ -18,6 +18,7 @@ type AddExecutor struct { resourceType string toResourceType string listID string + statusID string accountNames AccountNames content string } @@ -34,7 +35,8 @@ func NewAddExecutor(tlf TopLevelFlags, name, summary string) *AddExecutor { addExe.StringVar(&addExe.resourceType, flagType, "", "specify the resource type to add (e.g. account, note)") addExe.StringVar(&addExe.toResourceType, flagTo, "", "specify the target resource type to add to (e.g. list, account, etc)") addExe.StringVar(&addExe.listID, flagListID, "", "the ID of the list to add to") - addExe.Var(&addExe.accountNames, flagAccountName, "the name of the account to add to the resource") + addExe.StringVar(&addExe.statusID, flagStatusID, "", "the ID of the status") + addExe.Var(&addExe.accountNames, flagAccountName, "the name of the account") addExe.StringVar(&addExe.content, flagContent, "", "the content of the note") addExe.Usage = commandUsageFunc(name, summary, addExe.FlagSet) @@ -48,8 +50,9 @@ func (a *AddExecutor) Execute() error { } funcMap := map[string]func(*client.Client) error{ - resourceList: a.addToList, - resourceAccount: a.addToAccount, + resourceList: a.addToList, + resourceAccount: a.addToAccount, + resourceBookmarks: a.addToBookmarks, } doFunc, ok := funcMap[a.toResourceType] @@ -151,3 +154,33 @@ func (a *AddExecutor) addNoteToAccount(gtsClient *client.Client) error { return nil } + +func (a *AddExecutor) addToBookmarks(gtsClient *client.Client) error { + funcMap := map[string]func(*client.Client) error{ + resourceStatus: a.addStatusToBookmarks, + } + + doFunc, ok := funcMap[a.resourceType] + if !ok { + return UnsupportedAddOperationError{ + ResourceType: a.resourceType, + AddToResourceType: a.toResourceType, + } + } + + return doFunc(gtsClient) +} + +func (a *AddExecutor) addStatusToBookmarks(gtsClient *client.Client) error { + if a.statusID == "" { + return FlagNotSetError{flagText: flagStatusID} + } + + if err := gtsClient.AddStatusToBookmarks(a.statusID); err != nil { + return fmt.Errorf("unable to add the status to your bookmarks: %w", err) + } + + fmt.Println("Successfully added the status to your bookmarks.") + + return nil +} diff --git a/internal/executor/const.go b/internal/executor/const.go index f126f1d..58263f7 100644 --- a/internal/executor/const.go +++ b/internal/executor/const.go @@ -44,4 +44,5 @@ const ( resourceNote = "note" resourceStatus = "status" resourceTimeline = "timeline" + resourceBookmarks = "bookmarks" ) diff --git a/internal/executor/remove.go b/internal/executor/remove.go index 16fd326..70c769e 100644 --- a/internal/executor/remove.go +++ b/internal/executor/remove.go @@ -18,6 +18,7 @@ type RemoveExecutor struct { resourceType string fromResourceType string listID string + statusID string accountNames AccountNames } @@ -33,6 +34,7 @@ func NewRemoveExecutor(tlf TopLevelFlags, name, summary string) *RemoveExecutor removeExe.StringVar(&removeExe.resourceType, flagType, "", "specify the resource type to remove (e.g. account, note)") removeExe.StringVar(&removeExe.fromResourceType, flagFrom, "", "specify the resource type to remove from (e.g. list, account, etc)") removeExe.StringVar(&removeExe.listID, flagListID, "", "the ID of the list to remove from") + removeExe.StringVar(&removeExe.statusID, flagStatusID, "", "the ID of the status") removeExe.Var(&removeExe.accountNames, flagAccountName, "the name of the account to remove from the resource") removeExe.Usage = commandUsageFunc(name, summary, removeExe.FlagSet) @@ -46,8 +48,9 @@ func (r *RemoveExecutor) Execute() error { } funcMap := map[string]func(*client.Client) error{ - resourceList: r.removeFromList, - resourceAccount: r.removeFromAccount, + resourceList: r.removeFromList, + resourceAccount: r.removeFromAccount, + resourceBookmarks: r.removeFromBookmarks, } doFunc, ok := funcMap[r.fromResourceType] @@ -90,13 +93,13 @@ func (r *RemoveExecutor) removeAccountsFromList(gtsClient *client.Client) error accountIDs := make([]string, len(r.accountNames)) - for i := range r.accountNames { - accountID, err := getTheirAccountID(gtsClient, r.accountNames[i]) + for ind := range r.accountNames { + accountID, err := getTheirAccountID(gtsClient, r.accountNames[ind]) if err != nil { - return fmt.Errorf("unable to get the account ID for %s, %w", r.accountNames[i], err) + return fmt.Errorf("unable to get the account ID for %s, %w", r.accountNames[ind], err) } - accountIDs[i] = accountID + accountIDs[ind] = accountID } if err := gtsClient.RemoveAccountsFromList(r.listID, accountIDs); err != nil { @@ -142,3 +145,33 @@ func (r *RemoveExecutor) removeNoteFromAccount(gtsClient *client.Client) error { return nil } + +func (r *RemoveExecutor) removeFromBookmarks(gtsClient *client.Client) error { + funcMap := map[string]func(*client.Client) error{ + resourceStatus: r.removeStatusFromBookmarks, + } + + doFunc, ok := funcMap[r.resourceType] + if !ok { + return UnsupportedRemoveOperationError{ + ResourceType: r.resourceType, + RemoveFromResourceType: r.fromResourceType, + } + } + + return doFunc(gtsClient) +} + +func (r *RemoveExecutor) removeStatusFromBookmarks(gtsClient *client.Client) error { + if r.statusID == "" { + return FlagNotSetError{flagText: flagStatusID} + } + + if err := gtsClient.RemoveStatusFromBookmarks(r.statusID); err != nil { + return fmt.Errorf("unable to remove the status from your bookmarks: %w", err) + } + + fmt.Println("Successfully removed the status from your bookmarks.") + + return nil +} diff --git a/internal/executor/show.go b/internal/executor/show.go index b53d11b..f72f129 100644 --- a/internal/executor/show.go +++ b/internal/executor/show.go @@ -66,6 +66,7 @@ func (c *ShowExecutor) Execute() error { resourceFollowers: c.showFollowers, resourceFollowing: c.showFollowing, resourceBlocked: c.showBlocked, + resourceBookmarks: c.showBookmarks, } doFunc, ok := funcMap[c.resourceType] @@ -313,3 +314,18 @@ func (c *ShowExecutor) showBlocked(gtsClient *client.Client) error { return nil } + +func (c *ShowExecutor) showBookmarks(gtsClient *client.Client) error { + bookmarks, err := gtsClient.GetBookmarks(c.limit) + if err != nil { + return fmt.Errorf("unable to retrieve the list of bookmarks: %w", err) + } + + if len(bookmarks.Statuses) > 0 { + utilities.Display(bookmarks, *c.topLevelFlags.NoColor) + } else { + fmt.Println("You have no bookmarks.") + } + + return nil +} -- 2.45.2