start working on parent/child statuses
This commit is contained in:
parent
a42e05eee0
commit
6a053ecfd8
|
@ -217,6 +217,12 @@ type DB interface {
|
||||||
// GetFaveCountForStatus returns the amount of faves/likes recorded for a status, or an error if something goes wrong
|
// GetFaveCountForStatus returns the amount of faves/likes recorded for a status, or an error if something goes wrong
|
||||||
GetFaveCountForStatus(status *gtsmodel.Status) (int, error)
|
GetFaveCountForStatus(status *gtsmodel.Status) (int, error)
|
||||||
|
|
||||||
|
// StatusParents get the parent statuses of a given status.
|
||||||
|
StatusParents(status *gtsmodel.Status) ([]*gtsmodel.Status, error)
|
||||||
|
|
||||||
|
// StatusChildren gets the child statuses of a given status.
|
||||||
|
StatusChildren(status *gtsmodel.Status) ([]*gtsmodel.Status, error)
|
||||||
|
|
||||||
// StatusFavedBy checks if a given status has been faved by a given account ID
|
// StatusFavedBy checks if a given status has been faved by a given account ID
|
||||||
StatusFavedBy(status *gtsmodel.Status, accountID string) (bool, error)
|
StatusFavedBy(status *gtsmodel.Status, accountID string) (bool, error)
|
||||||
|
|
||||||
|
|
|
@ -807,14 +807,26 @@ func (ps *postgresService) GetRelationship(requestingAccount string, targetAccou
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *postgresService) Follows(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, error) {
|
func (ps *postgresService) Follows(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, error) {
|
||||||
|
if sourceAccount == nil || targetAccount == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
return ps.conn.Model(>smodel.Follow{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists()
|
return ps.conn.Model(>smodel.Follow{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *postgresService) FollowRequested(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, error) {
|
func (ps *postgresService) FollowRequested(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, error) {
|
||||||
|
if sourceAccount == nil || targetAccount == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
return ps.conn.Model(>smodel.FollowRequest{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists()
|
return ps.conn.Model(>smodel.FollowRequest{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *postgresService) Mutuals(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, error) {
|
func (ps *postgresService) Mutuals(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, error) {
|
||||||
|
if account1 == nil || account2 == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// make sure account 1 follows account 2
|
// make sure account 1 follows account 2
|
||||||
f1, err := ps.conn.Model(>smodel.Follow{}).Where("account_id = ?", account1.ID).Where("target_account_id = ?", account2.ID).Exists()
|
f1, err := ps.conn.Model(>smodel.Follow{}).Where("account_id = ?", account1.ID).Where("target_account_id = ?", account2.ID).Exists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package pg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ps *postgresService) StatusParents(status *gtsmodel.Status) ([]*gtsmodel.Status, error) {
|
||||||
|
parents := []*gtsmodel.Status{}
|
||||||
|
ps.statusParent(status, &parents)
|
||||||
|
|
||||||
|
return parents, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *postgresService) statusParent(status *gtsmodel.Status, foundStatuses *[]*gtsmodel.Status) {
|
||||||
|
if status.InReplyToID == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parentStatus := >smodel.Status{}
|
||||||
|
if err := ps.conn.Model(parentStatus).Where("id = ?", status.InReplyToID).Select(); err == nil {
|
||||||
|
*foundStatuses = append(*foundStatuses, parentStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
ps.statusParent(parentStatus, foundStatuses)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *postgresService) StatusChildren(status *gtsmodel.Status) ([]*gtsmodel.Status, error) {
|
||||||
|
children := []*gtsmodel.Status{}
|
||||||
|
// ps.statusChildren(status, &children)
|
||||||
|
|
||||||
|
return children, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *postgresService) statusChildren(status *gtsmodel.Status, foundStatuses *sync.Map) {
|
||||||
|
// immediateChildren := []*gtsmodel.Status{}
|
||||||
|
|
||||||
|
// foundStatuses.Store()
|
||||||
|
|
||||||
|
// err := ps.conn.Model(&immediateChildren).Where("in_reply_to_id = ?", status.ID).Select()
|
||||||
|
// if err != nil {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for _, child := range immediateChildren {
|
||||||
|
// f[""][0] = child
|
||||||
|
// }
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -1,14 +1,73 @@
|
||||||
package status
|
package status
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
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/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *processor) Context(account *gtsmodel.Account, targetStatusID string) (*apimodel.Context, gtserror.WithCode) {
|
func (p *processor) Context(account *gtsmodel.Account, targetStatusID string) (*apimodel.Context, gtserror.WithCode) {
|
||||||
return &apimodel.Context{
|
|
||||||
|
context := &apimodel.Context{
|
||||||
Ancestors: []apimodel.Status{},
|
Ancestors: []apimodel.Status{},
|
||||||
Descendants: []apimodel.Status{},
|
Descendants: []apimodel.Status{},
|
||||||
}, nil
|
}
|
||||||
|
|
||||||
|
targetStatus := >smodel.Status{}
|
||||||
|
if err := p.db.GetByID(targetStatusID, targetStatus); err != nil {
|
||||||
|
if _, ok := err.(db.ErrNoEntries); ok {
|
||||||
|
return nil, gtserror.NewErrorNotFound(err)
|
||||||
|
}
|
||||||
|
return nil, gtserror.NewErrorInternalError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
visible, err := p.filter.StatusVisible(targetStatus, account)
|
||||||
|
if err != nil {
|
||||||
|
return nil, gtserror.NewErrorNotFound(err)
|
||||||
|
}
|
||||||
|
if !visible {
|
||||||
|
return nil, gtserror.NewErrorForbidden(fmt.Errorf("account with id %s does not have permission to view status %s", account.ID, targetStatusID))
|
||||||
|
}
|
||||||
|
|
||||||
|
parents, err := p.db.StatusParents(targetStatus)
|
||||||
|
if err != nil {
|
||||||
|
return nil, gtserror.NewErrorInternalError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, status := range parents {
|
||||||
|
if v, err := p.filter.StatusVisible(status, account); err == nil && v {
|
||||||
|
mastoStatus, err := p.tc.StatusToMasto(status, account)
|
||||||
|
if err == nil {
|
||||||
|
context.Ancestors = append(context.Ancestors, *mastoStatus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
children, err := p.db.StatusChildren(targetStatus)
|
||||||
|
if err != nil {
|
||||||
|
return nil, gtserror.NewErrorInternalError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, status := range children {
|
||||||
|
if v, err := p.filter.StatusVisible(status, account); err == nil && v {
|
||||||
|
mastoStatus, err := p.tc.StatusToMasto(status, account)
|
||||||
|
if err == nil {
|
||||||
|
context.Ancestors = append(context.Ancestors, *mastoStatus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(context.Ancestors, func(i int, j int) bool {
|
||||||
|
return context.Ancestors[i].ID < context.Ancestors[j].ID
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Slice(context.Descendants, func(i int, j int) bool {
|
||||||
|
return context.Descendants[i].ID < context.Descendants[j].ID
|
||||||
|
})
|
||||||
|
|
||||||
|
return context, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,10 @@ func (f *filter) StatusHometimelineable(targetStatus *gtsmodel.Status, requestin
|
||||||
l := f.log.WithFields(logrus.Fields{
|
l := f.log.WithFields(logrus.Fields{
|
||||||
"func": "StatusHometimelineable",
|
"func": "StatusHometimelineable",
|
||||||
"statusID": targetStatus.ID,
|
"statusID": targetStatus.ID,
|
||||||
"requestingAccountID": requestingAccount.ID,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// status owner should always be able to see their status in their timeline so we can return early if this is the case
|
// status owner should always be able to see their status in their timeline so we can return early if this is the case
|
||||||
if targetStatus.AccountID == requestingAccount.ID {
|
if requestingAccount != nil && targetStatus.AccountID == requestingAccount.ID {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue