diff options
Diffstat (limited to 'internal/db/pg/pg.go')
-rw-r--r-- | internal/db/pg/pg.go | 91 |
1 files changed, 58 insertions, 33 deletions
diff --git a/internal/db/pg/pg.go b/internal/db/pg/pg.go index f8c2fdbe8..d3590a027 100644 --- a/internal/db/pg/pg.go +++ b/internal/db/pg/pg.go @@ -456,23 +456,35 @@ func (ps *postgresService) GetFavesByAccountID(accountID string, faves *[]gtsmod return nil } -func (ps *postgresService) GetStatusesByAccountID(accountID string, statuses *[]gtsmodel.Status) error { - if err := ps.conn.Model(statuses).Where("account_id = ?", accountID).Select(); err != nil { +func (ps *postgresService) CountStatusesByAccountID(accountID string) (int, error) { + count, err := ps.conn.Model(>smodel.Status{}).Where("account_id = ?", accountID).Count() + if err != nil { if err == pg.ErrNoRows { - return db.ErrNoEntries{} + return 0, nil } - return err + return 0, err } - return nil + return count, nil } -func (ps *postgresService) GetStatusesByTimeDescending(accountID string, statuses *[]gtsmodel.Status, limit int) error { +func (ps *postgresService) GetStatusesByTimeDescending(accountID string, statuses *[]gtsmodel.Status, limit int, excludeReplies bool, maxID string, pinned bool, mediaOnly bool) error { q := ps.conn.Model(statuses).Order("created_at DESC") + if accountID != "" { + q = q.Where("account_id = ?", accountID) + } if limit != 0 { q = q.Limit(limit) } - if accountID != "" { - q = q.Where("account_id = ?", accountID) + if excludeReplies { + q = q.Where("? IS NULL", pg.Ident("in_reply_to_id")) + } + if pinned { + q = q.Where("pinned = ?", true) + } + if mediaOnly { + q = q.WhereGroup(func(q *pg.Query) (*pg.Query, error) { + return q.Where("? IS NOT NULL", pg.Ident("attachments")).Where("attachments != '{}'"), nil + }) } if err := q.Select(); err != nil { if err == pg.ErrNoRows { @@ -679,20 +691,23 @@ func (ps *postgresService) StatusVisible(targetStatus *gtsmodel.Status, targetAc } // if the target user doesn't exist (anymore) then the status also shouldn't be visible - targetUser := >smodel.User{} - if err := ps.conn.Model(targetUser).Where("account_id = ?", targetAccount.ID).Select(); err != nil { - l.Debug("target user could not be selected") - if err == pg.ErrNoRows { - return false, db.ErrNoEntries{} + // note: we only do this for local users + if targetAccount.Domain == "" { + targetUser := >smodel.User{} + if err := ps.conn.Model(targetUser).Where("account_id = ?", targetAccount.ID).Select(); err != nil { + l.Debug("target user could not be selected") + if err == pg.ErrNoRows { + return false, db.ErrNoEntries{} + } + return false, err } - return false, err - } - // if target user is disabled, not yet approved, or not confirmed then don't show the status - // (although in the latter two cases it's unlikely they posted a status yet anyway, but you never know!) - if targetUser.Disabled || !targetUser.Approved || targetUser.ConfirmedAt.IsZero() { - l.Debug("target user is disabled, not approved, or not confirmed") - return false, nil + // if target user is disabled, not yet approved, or not confirmed then don't show the status + // (although in the latter two cases it's unlikely they posted a status yet anyway, but you never know!) + if targetUser.Disabled || !targetUser.Approved || targetUser.ConfirmedAt.IsZero() { + l.Debug("target user is disabled, not approved, or not confirmed") + return false, nil + } } // If requesting account is nil, that means whoever requested the status didn't auth, or their auth failed. @@ -755,6 +770,7 @@ func (ps *postgresService) StatusVisible(targetStatus *gtsmodel.Status, targetAc if blocked, err := ps.Blocked(relevantAccounts.ReplyToAccount.ID, requestingAccount.ID); err != nil { return false, err } else if blocked { + l.Debug("a block exists between requesting account and reply to account") return false, nil } } @@ -764,6 +780,7 @@ func (ps *postgresService) StatusVisible(targetStatus *gtsmodel.Status, targetAc if blocked, err := ps.Blocked(relevantAccounts.BoostedAccount.ID, requestingAccount.ID); err != nil { return false, err } else if blocked { + l.Debug("a block exists between requesting account and boosted account") return false, nil } } @@ -773,6 +790,7 @@ func (ps *postgresService) StatusVisible(targetStatus *gtsmodel.Status, targetAc if blocked, err := ps.Blocked(relevantAccounts.BoostedReplyToAccount.ID, requestingAccount.ID); err != nil { return false, err } else if blocked { + l.Debug("a block exists between requesting account and boosted reply to account") return false, nil } } @@ -782,9 +800,17 @@ func (ps *postgresService) StatusVisible(targetStatus *gtsmodel.Status, targetAc if blocked, err := ps.Blocked(a.ID, requestingAccount.ID); err != nil { return false, err } else if blocked { + l.Debug("a block exists between requesting account and a mentioned account") return false, nil } } + + // if the requesting account is mentioned in the status it should always be visible + for _, acct := range relevantAccounts.MentionedAccounts { + if acct.ID == requestingAccount.ID { + return true, nil // yep it's mentioned! + } + } } // at this point we know neither account blocks the other, or another account mentioned or otherwise referred to in the status @@ -800,6 +826,7 @@ func (ps *postgresService) StatusVisible(targetStatus *gtsmodel.Status, targetAc return false, err } if !follows { + l.Debug("requested status is followers only but requesting account is not a follower") return false, nil } return true, nil @@ -810,16 +837,12 @@ func (ps *postgresService) StatusVisible(targetStatus *gtsmodel.Status, targetAc return false, err } if !mutuals { + l.Debug("requested status is mutuals only but accounts aren't mufos") return false, nil } return true, nil case gtsmodel.VisibilityDirect: - // make sure the requesting account is mentioned in the status - for _, menchie := range targetStatus.Mentions { - if menchie == requestingAccount.ID { - return true, nil // yep it's mentioned! - } - } + l.Debug("requesting account requests a status it's not mentioned in") return false, nil // it's not mentioned -_- } @@ -890,10 +913,16 @@ func (ps *postgresService) PullRelevantAccountsFromStatus(targetStatus *gtsmodel } // now get all accounts with IDs that are mentioned in the status - for _, mentionedAccountID := range targetStatus.Mentions { + for _, mentionID := range targetStatus.Mentions { + + mention := >smodel.Mention{} + if err := ps.conn.Model(mention).Where("id = ?", mentionID).Select(); err != nil { + return accounts, fmt.Errorf("error getting mention with id %s: %s", mentionID, err) + } + mentionedAccount := >smodel.Account{} - if err := ps.conn.Model(mentionedAccount).Where("id = ?", mentionedAccountID).Select(); err != nil { - return accounts, err + if err := ps.conn.Model(mentionedAccount).Where("id = ?", mention.TargetAccountID).Select(); err != nil { + return accounts, fmt.Errorf("error getting mentioned account: %s", err) } accounts.MentionedAccounts = append(accounts.MentionedAccounts, mentionedAccount) } @@ -929,10 +958,6 @@ func (ps *postgresService) StatusBookmarkedBy(status *gtsmodel.Status, accountID return ps.conn.Model(>smodel.StatusBookmark{}).Where("status_id = ?", status.ID).Where("account_id = ?", accountID).Exists() } -func (ps *postgresService) StatusPinnedBy(status *gtsmodel.Status, accountID string) (bool, error) { - return ps.conn.Model(>smodel.StatusPin{}).Where("status_id = ?", status.ID).Where("account_id = ?", accountID).Exists() -} - func (ps *postgresService) FaveStatus(status *gtsmodel.Status, accountID string) (*gtsmodel.StatusFave, error) { // first check if a fave already exists, we can just return if so existingFave := >smodel.StatusFave{} |