summaryrefslogtreecommitdiff
path: root/internal/processing/account
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2023-02-23 23:11:10 +0100
committerLibravatar GitHub <noreply@github.com>2023-02-23 22:11:10 +0000
commit689a10fe176706342704dc75e10d7c1f23d35540 (patch)
treee3540ce586c1a803c4290f3a06de631a6274e8dd /internal/processing/account
parent[chore] improve opengraph descripiton tag (#1550) (diff)
downloadgotosocial-689a10fe176706342704dc75e10d7c1f23d35540.tar.xz
[bugfix] Fix deleted status causing issues when getting bookmark (#1551)
* [bugfix] Delete bookmark when status deleted * [chore] Give bookmark processing func some love * fix paging + embetter tests
Diffstat (limited to 'internal/processing/account')
-rw-r--r--internal/processing/account/bookmarks.go92
1 files changed, 53 insertions, 39 deletions
diff --git a/internal/processing/account/bookmarks.go b/internal/processing/account/bookmarks.go
index 7551b1e0c..28688c20d 100644
--- a/internal/processing/account/bookmarks.go
+++ b/internal/processing/account/bookmarks.go
@@ -20,69 +20,83 @@ package account
import (
"context"
- "fmt"
+ "errors"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
+ "github.com/superseriousbusiness/gotosocial/internal/id"
+ "github.com/superseriousbusiness/gotosocial/internal/log"
"github.com/superseriousbusiness/gotosocial/internal/util"
)
+// BookmarksGet returns a pageable response of statuses that are bookmarked by requestingAccount.
+// Paging for this response is done based on bookmark ID rather than status ID.
func (p *Processor) BookmarksGet(ctx context.Context, requestingAccount *gtsmodel.Account, limit int, maxID string, minID string) (*apimodel.PageableResponse, gtserror.WithCode) {
- if requestingAccount == nil {
- return nil, gtserror.NewErrorForbidden(fmt.Errorf("cannot retrieve bookmarks without a requesting account"))
- }
-
bookmarks, err := p.db.GetBookmarks(ctx, requestingAccount.ID, limit, maxID, minID)
if err != nil {
return nil, gtserror.NewErrorInternalError(err)
}
- count := len(bookmarks)
- filtered := make([]*gtsmodel.Status, 0, len(bookmarks))
- nextMaxIDValue := ""
- prevMinIDValue := ""
- for i, b := range bookmarks {
- s, err := p.db.GetStatusByID(ctx, b.StatusID)
- if err != nil {
- return nil, gtserror.NewErrorInternalError(err)
- }
-
- visible, err := p.filter.StatusVisible(ctx, s, requestingAccount)
- if err == nil && visible {
- if i == count-1 {
- nextMaxIDValue = b.ID
- }
+ var (
+ count = len(bookmarks)
+ items = make([]interface{}, 0, count)
+ nextMaxIDValue = id.Highest
+ prevMinIDValue = id.Lowest
+ )
- if i == 0 {
- prevMinIDValue = b.ID
+ for _, bookmark := range bookmarks {
+ status, err := p.db.GetStatusByID(ctx, bookmark.StatusID)
+ if err != nil {
+ if errors.Is(err, db.ErrNoEntries) {
+ // We just don't have the status for some reason.
+ // Skip this one.
+ continue
}
-
- filtered = append(filtered, s)
+ return nil, gtserror.NewErrorInternalError(err) // A real error has occurred.
}
- }
- count = len(filtered)
+ visible, err := p.filter.StatusVisible(ctx, status, requestingAccount)
+ if err != nil {
+ log.Errorf(ctx, "error checking bookmarked status visibility: %s", err)
+ continue
+ }
- if count == 0 {
- return util.EmptyPageableResponse(), nil
- }
+ if !visible {
+ continue
+ }
- items := []interface{}{}
- for _, s := range filtered {
- item, err := p.tc.StatusToAPIStatus(ctx, s, requestingAccount)
+ // Convert the status.
+ item, err := p.tc.StatusToAPIStatus(ctx, status, requestingAccount)
if err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("error converting status to api: %s", err))
+ log.Errorf(ctx, "error converting bookmarked status to api: %s", err)
+ continue
}
items = append(items, item)
+
+ // Page based on bookmark ID, not status ID.
+ // Note that we only set these values here
+ // when we're certain that the caller is able
+ // to see the status, *and* we're sure that
+ // we can produce an api model representation.
+ if bookmark.ID < nextMaxIDValue {
+ nextMaxIDValue = bookmark.ID // Lowest ID (for paging down).
+ }
+ if bookmark.ID > prevMinIDValue {
+ prevMinIDValue = bookmark.ID // Highest ID (for paging up).
+ }
+ }
+
+ if len(items) == 0 {
+ return util.EmptyPageableResponse(), nil
}
return util.PackagePageableResponse(util.PageableResponseParams{
- Items: items,
- Path: "/api/v1/bookmarks",
- NextMaxIDValue: nextMaxIDValue,
- PrevMinIDValue: prevMinIDValue,
- Limit: limit,
- ExtraQueryParams: []string{},
+ Items: items,
+ Path: "/api/v1/bookmarks",
+ NextMaxIDValue: nextMaxIDValue,
+ PrevMinIDValue: prevMinIDValue,
+ Limit: limit,
})
}