diff options
| author | 2025-09-18 16:33:23 +0200 | |
|---|---|---|
| committer | 2025-09-18 16:33:23 +0200 | |
| commit | 6607e1c9444d0814b72762a46814ff0812d96343 (patch) | |
| tree | 9bbf15038b1a37b01bfcf7010dbe376e70b504d0 /internal/db/bundb | |
| parent | [chore] update dependencies (#4441) (diff) | |
| download | gotosocial-6607e1c9444d0814b72762a46814ff0812d96343.tar.xz | |
[feature] add paging support to rss feed endpoint, and support JSON / atom feed types (#4442)
originally based on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4396
hope this is okay https://codeberg.org/zordsdavini !
closes https://codeberg.org/superseriousbusiness/gotosocial/issues/4411
closes https://codeberg.org/superseriousbusiness/gotosocial/issues/3407
Co-authored-by: Arnas Udovic <zordsdavini@gmail.com>
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4442
Co-authored-by: kim <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
Diffstat (limited to 'internal/db/bundb')
| -rw-r--r-- | internal/db/bundb/account.go | 109 | ||||
| -rw-r--r-- | internal/db/bundb/account_test.go | 2 |
2 files changed, 38 insertions, 73 deletions
diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index 603740f17..8276016d7 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -900,7 +900,7 @@ func (a *accountDB) GetAccountFaves(ctx context.Context, accountID string) ([]*g return *faves, nil } -func qMediaOnly(q *bun.SelectQuery) *bun.SelectQuery { +func selectOnlyWithMedia(q *bun.SelectQuery) *bun.SelectQuery { // Attachments are stored as a json object; this // implementation differs between SQLite and Postgres, // so we have to be thorough to cover all eventualities @@ -908,14 +908,14 @@ func qMediaOnly(q *bun.SelectQuery) *bun.SelectQuery { switch d := q.Dialect().Name(); d { case dialect.PG: return q. - Where("? IS NOT NULL", bun.Ident("status.attachments")). - Where("? != '{}'", bun.Ident("status.attachments")) + Where("? IS NOT NULL", bun.Ident("attachments")). + Where("? != '{}'", bun.Ident("attachments")) case dialect.SQLite: return q. - Where("? IS NOT NULL", bun.Ident("status.attachments")). - Where("? != 'null'", bun.Ident("status.attachments")). - Where("? != '[]'", bun.Ident("status.attachments")) + Where("? IS NOT NULL", bun.Ident("attachments")). + Where("? != 'null'", bun.Ident("attachments")). + Where("? != '[]'", bun.Ident("attachments")) default: panic("dialect " + d.String() + " was neither pg nor sqlite") @@ -963,9 +963,9 @@ func (a *accountDB) GetAccountStatuses(ctx context.Context, accountID string, li q = q.Where("? IS NULL", bun.Ident("status.boost_of_id")) } - // Respect media-only preference. if mediaOnly { - q = qMediaOnly(q) + // Respect mediaOnly pref. + q = selectOnlyWithMedia(q) } if publicOnly { @@ -1041,12 +1041,16 @@ func (a *accountDB) GetAccountPinnedStatuses(ctx context.Context, accountID stri return a.state.DB.GetStatusesByIDs(ctx, statusIDs) } +var webStatusVisibilities = bun.In([]gtsmodel.Visibility{ + gtsmodel.VisibilityPublic, + gtsmodel.VisibilityUnlocked, +}) + func (a *accountDB) GetAccountWebStatuses( ctx context.Context, account *gtsmodel.Account, + page *paging.Page, mediaOnly bool, - limit int, - maxID string, ) ([]*gtsmodel.Status, error) { if account.Username == config.GetHost() { // Instance account @@ -1071,74 +1075,35 @@ func (a *accountDB) GetAccountWebStatuses( return nil, nil } - // Ensure reasonable - if limit < 0 { - limit = 0 - } + return loadStatusTimelinePage(ctx, a.db, a.state, - // Make educated guess for slice size - statusIDs := make([]string, 0, limit) + // Paging + // params. + page, - q := a.db. - NewSelect(). - TableExpr("? AS ?", bun.Ident("statuses"), bun.Ident("status")). - // Select only IDs from table - Column("status.id"). - Where("? = ?", bun.Ident("status.account_id"), account.ID) + // The actual meat of the account web statuses query. + func(q *bun.SelectQuery) (*bun.SelectQuery, error) { + q = q.Where("? = ?", bun.Ident("account_id"), account.ID) - // Select statuses according to - // account's web visibility prefs. - if publicOnly { - // Only Public statuses. - q = q.Where("? = ?", bun.Ident("status.visibility"), gtsmodel.VisibilityPublic) - } else { - // Public or Unlocked. - visis := []gtsmodel.Visibility{ - gtsmodel.VisibilityPublic, - gtsmodel.VisibilityUnlocked, - } - q = q.Where("? IN (?)", bun.Ident("status.visibility"), bun.In(visis)) - } - - // Don't show replies, boosts, or - // local-only statuses on the web view. - q = q. - Where("? IS NULL", bun.Ident("status.in_reply_to_uri")). - Where("? IS NULL", bun.Ident("status.boost_of_id")). - Where("? = ?", bun.Ident("status.federated"), true) - - // Respect media-only preference. - if mediaOnly { - q = qMediaOnly(q) - } - - // Return only statuses LOWER (ie., older) than maxID - if maxID == "" { - maxID = id.Highest - } - q = q.Where("? < ?", bun.Ident("status.id"), maxID) - - if limit > 0 { - // limit amount of statuses returned - q = q.Limit(limit) - } - - if limit > 0 { - // limit amount of statuses returned - q = q.Limit(limit) - } - - q = q.Order("status.id DESC") + if publicOnly { + q = q.Where("? = ?", bun.Ident("visibility"), gtsmodel.VisibilityPublic) + } else { + q = q.Where("? IN (?)", bun.Ident("visibility"), webStatusVisibilities) + } - if err := q.Scan(ctx, &statusIDs); err != nil { - return nil, err - } + // Don't show replies, boosts, or local-only in web view. + q = q.Where("? IS NULL", bun.Ident("in_reply_to_uri")). + Where("? IS NULL", bun.Ident("boost_of_id")). + Where("? = ?", bun.Ident("federated"), true) - if len(statusIDs) == 0 { - return nil, db.ErrNoEntries - } + if mediaOnly { + // Respect mediaOnly pref. + q = selectOnlyWithMedia(q) + } - return a.state.DB.GetStatusesByIDs(ctx, statusIDs) + return q, nil + }, + ) } func (a *accountDB) GetAccountSettings( diff --git a/internal/db/bundb/account_test.go b/internal/db/bundb/account_test.go index 4c4cad3dd..fb86b5d5d 100644 --- a/internal/db/bundb/account_test.go +++ b/internal/db/bundb/account_test.go @@ -49,7 +49,7 @@ func (suite *AccountTestSuite) TestGetAccountStatuses() { } func (suite *AccountTestSuite) TestGetAccountWebStatusesMediaOnly() { - statuses, err := suite.db.GetAccountWebStatuses(suite.T().Context(), suite.testAccounts["local_account_3"], true, 20, "") + statuses, err := suite.db.GetAccountWebStatuses(suite.T().Context(), suite.testAccounts["local_account_3"], &paging.Page{Limit: 20}, true) suite.NoError(err) suite.Len(statuses, 2) } |
