summaryrefslogtreecommitdiff
path: root/internal/processing
diff options
context:
space:
mode:
Diffstat (limited to 'internal/processing')
-rw-r--r--internal/processing/common/account.go17
-rw-r--r--internal/processing/common/status.go76
-rw-r--r--internal/processing/status/context.go61
-rw-r--r--internal/processing/workers/surfacetimeline.go19
4 files changed, 115 insertions, 58 deletions
diff --git a/internal/processing/common/account.go b/internal/processing/common/account.go
index 05e974513..ae26e4ebd 100644
--- a/internal/processing/common/account.go
+++ b/internal/processing/common/account.go
@@ -42,6 +42,7 @@ func (p *Processor) GetTargetAccountBy(
// Fetch the target account from db.
target, err := getTargetFromDB()
if err != nil && !errors.Is(err, db.ErrNoEntries) {
+ err := gtserror.Newf("error getting from db: %w", err)
return nil, false, gtserror.NewErrorInternalError(err)
}
@@ -57,6 +58,7 @@ func (p *Processor) GetTargetAccountBy(
// Check whether target account is visible to requesting account.
visible, err = p.visFilter.AccountVisible(ctx, requester, target)
if err != nil {
+ err := gtserror.Newf("error checking visibility: %w", err)
return nil, false, gtserror.NewErrorInternalError(err)
}
@@ -128,7 +130,8 @@ func (p *Processor) GetVisibleTargetAccount(
return target, nil
}
-// GetAPIAccount fetches the appropriate API account model depending on whether requester = target.
+// GetAPIAccount fetches the appropriate API account
+// model depending on whether requester = target.
func (p *Processor) GetAPIAccount(
ctx context.Context,
requester *gtsmodel.Account,
@@ -148,14 +151,15 @@ func (p *Processor) GetAPIAccount(
}
if err != nil {
- err := gtserror.Newf("error converting account: %w", err)
+ err := gtserror.Newf("error converting: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
return apiAcc, nil
}
-// GetAPIAccountBlocked fetches the limited "blocked" account model for given target.
+// GetAPIAccountBlocked fetches the limited
+// "blocked" account model for given target.
func (p *Processor) GetAPIAccountBlocked(
ctx context.Context,
targetAcc *gtsmodel.Account,
@@ -165,7 +169,7 @@ func (p *Processor) GetAPIAccountBlocked(
) {
apiAccount, err := p.converter.AccountToAPIAccountBlocked(ctx, targetAcc)
if err != nil {
- err = gtserror.Newf("error converting account: %w", err)
+ err := gtserror.Newf("error converting: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
return apiAccount, nil
@@ -182,7 +186,7 @@ func (p *Processor) GetAPIAccountSensitive(
) {
apiAccount, err := p.converter.AccountToAPIAccountSensitive(ctx, targetAcc)
if err != nil {
- err = gtserror.Newf("error converting account: %w", err)
+ err := gtserror.Newf("error converting: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
return apiAccount, nil
@@ -226,8 +230,7 @@ func (p *Processor) getVisibleAPIAccounts(
) []*apimodel.Account {
// Start new log entry with
// the above calling func's name.
- l := log.
- WithContext(ctx).
+ l := log.WithContext(ctx).
WithField("caller", log.Caller(calldepth+1))
// Preallocate slice according to expected length.
diff --git a/internal/processing/common/status.go b/internal/processing/common/status.go
index a1d432eb0..dd83a2cc5 100644
--- a/internal/processing/common/status.go
+++ b/internal/processing/common/status.go
@@ -25,6 +25,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
statusfilter "github.com/superseriousbusiness/gotosocial/internal/filter/status"
+ "github.com/superseriousbusiness/gotosocial/internal/filter/usermute"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/log"
@@ -50,6 +51,7 @@ func (p *Processor) GetTargetStatusBy(
// Fetch the target status from db.
target, err := getTargetFromDB()
if err != nil && !errors.Is(err, db.ErrNoEntries) {
+ err := gtserror.Newf("error getting from db: %w", err)
return nil, false, gtserror.NewErrorInternalError(err)
}
@@ -65,6 +67,7 @@ func (p *Processor) GetTargetStatusBy(
// Check whether target status is visible to requesting account.
visible, err = p.visFilter.StatusVisible(ctx, requester, target)
if err != nil {
+ err := gtserror.Newf("error checking visibility: %w", err)
return nil, false, gtserror.NewErrorInternalError(err)
}
@@ -174,14 +177,83 @@ func (p *Processor) GetAPIStatus(
apiStatus *apimodel.Status,
errWithCode gtserror.WithCode,
) {
- apiStatus, err := p.converter.StatusToAPIStatus(ctx, target, requester, statusfilter.FilterContextNone, nil, nil)
+ apiStatus, err := p.converter.StatusToAPIStatus(ctx,
+ target,
+ requester,
+ statusfilter.FilterContextNone,
+ nil,
+ nil,
+ )
if err != nil {
- err = gtserror.Newf("error converting status: %w", err)
+ err := gtserror.Newf("error converting: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
return apiStatus, nil
}
+// GetVisibleAPIStatuses converts a slice of statuses to API
+// model statuses, filtering according to visibility to requester
+// along with given filter context, filters and user mutes.
+//
+// Please note that all errors will be logged at ERROR level,
+// but will not be returned. Callers are likely to run into
+// show-stopping errors in the lead-up to this function.
+func (p *Processor) GetVisibleAPIStatuses(
+ ctx context.Context,
+ requester *gtsmodel.Account,
+ statuses []*gtsmodel.Status,
+ filterContext statusfilter.FilterContext,
+ filters []*gtsmodel.Filter,
+ userMutes []*gtsmodel.UserMute,
+) []apimodel.Status {
+
+ // Start new log entry with
+ // the calling function name
+ // as a field in each entry.
+ l := log.WithContext(ctx).
+ WithField("caller", log.Caller(3))
+
+ // Compile mutes to useable user mutes for type converter.
+ compUserMutes := usermute.NewCompiledUserMuteList(userMutes)
+
+ // Iterate filtered statuses for conversion to API model.
+ apiStatuses := make([]apimodel.Status, 0, len(statuses))
+ for _, status := range statuses {
+
+ // Check whether status is visible to requester.
+ visible, err := p.visFilter.StatusVisible(ctx,
+ requester,
+ status,
+ )
+ if err != nil {
+ l.Errorf("error checking visibility: %v", err)
+ continue
+ }
+
+ if !visible {
+ continue
+ }
+
+ // Convert to API status, taking mute / filter into account.
+ apiStatus, err := p.converter.StatusToAPIStatus(ctx,
+ status,
+ requester,
+ filterContext,
+ filters,
+ compUserMutes,
+ )
+ if err != nil && !errors.Is(err, statusfilter.ErrHideStatus) {
+ l.Errorf("error converting: %v", err)
+ continue
+ }
+
+ // Append converted status to return slice.
+ apiStatuses = append(apiStatuses, *apiStatus)
+ }
+
+ return apiStatuses
+}
+
// InvalidateTimelinedStatus is a shortcut function for invalidating the cached
// representation one status in the home timeline and all list timelines of the
// given accountID. It should only be called in cases where a status update
diff --git a/internal/processing/status/context.go b/internal/processing/status/context.go
index 9f3a7d089..19c6cac18 100644
--- a/internal/processing/status/context.go
+++ b/internal/processing/status/context.go
@@ -24,7 +24,6 @@ import (
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
statusfilter "github.com/superseriousbusiness/gotosocial/internal/filter/status"
- "github.com/superseriousbusiness/gotosocial/internal/filter/usermute"
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -308,22 +307,7 @@ func (p *Processor) ContextGet(
return nil, gtserror.NewErrorInternalError(err)
}
- convert := func(
- ctx context.Context,
- status *gtsmodel.Status,
- requestingAccount *gtsmodel.Account,
- ) (*apimodel.Status, error) {
- return p.converter.StatusToAPIStatus(
- ctx,
- status,
- requestingAccount,
- statusfilter.FilterContextThread,
- filters,
- usermute.NewCompiledUserMuteList(mutes),
- )
- }
-
- // Retrieve the thread context.
+ // Retrieve the full thread context.
threadContext, errWithCode := p.contextGet(
ctx,
requester,
@@ -333,34 +317,27 @@ func (p *Processor) ContextGet(
return nil, errWithCode
}
- apiContext := &apimodel.ThreadContext{
- Ancestors: make([]apimodel.Status, 0, len(threadContext.ancestors)),
- Descendants: make([]apimodel.Status, 0, len(threadContext.descendants)),
- }
+ var apiContext apimodel.ThreadContext
- // Convert ancestors + filter
- // out ones that aren't visible.
- for _, status := range threadContext.ancestors {
- if v, err := p.visFilter.StatusVisible(ctx, requester, status); err == nil && v {
- status, err := convert(ctx, status, requester)
- if err == nil {
- apiContext.Ancestors = append(apiContext.Ancestors, *status)
- }
- }
- }
+ // Convert and filter the thread context ancestors.
+ apiContext.Ancestors = p.c.GetVisibleAPIStatuses(ctx,
+ requester,
+ threadContext.ancestors,
+ statusfilter.FilterContextThread,
+ filters,
+ mutes,
+ )
- // Convert descendants + filter
- // out ones that aren't visible.
- for _, status := range threadContext.descendants {
- if v, err := p.visFilter.StatusVisible(ctx, requester, status); err == nil && v {
- status, err := convert(ctx, status, requester)
- if err == nil {
- apiContext.Descendants = append(apiContext.Descendants, *status)
- }
- }
- }
+ // Convert and filter the thread context descendants
+ apiContext.Descendants = p.c.GetVisibleAPIStatuses(ctx,
+ requester,
+ threadContext.descendants,
+ statusfilter.FilterContextThread,
+ filters,
+ mutes,
+ )
- return apiContext, nil
+ return &apiContext, nil
}
// WebContextGet is like ContextGet, but is explicitly
diff --git a/internal/processing/workers/surfacetimeline.go b/internal/processing/workers/surfacetimeline.go
index 90cb1fed3..b071bd72e 100644
--- a/internal/processing/workers/surfacetimeline.go
+++ b/internal/processing/workers/surfacetimeline.go
@@ -384,8 +384,9 @@ func (s *Surface) timelineStatus(
) (bool, error) {
// Ingest status into given timeline using provided function.
- if inserted, err := ingest(ctx, timelineID, status); err != nil {
- err = gtserror.Newf("error ingesting status %s: %w", status.ID, err)
+ if inserted, err := ingest(ctx, timelineID, status); err != nil &&
+ !errors.Is(err, statusfilter.ErrHideStatus) {
+ err := gtserror.Newf("error ingesting status %s: %w", status.ID, err)
return false, err
} else if !inserted {
// Nothing more to do.
@@ -400,15 +401,19 @@ func (s *Surface) timelineStatus(
filters,
mutes,
)
- if err != nil {
- err = gtserror.Newf("error converting status %s to frontend representation: %w", status.ID, err)
+ if err != nil && !errors.Is(err, statusfilter.ErrHideStatus) {
+ err := gtserror.Newf("error converting status %s to frontend representation: %w", status.ID, err)
return true, err
}
- // The status was inserted so stream it to the user.
- s.Stream.Update(ctx, account, apiStatus, streamType)
+ if apiStatus != nil {
+ // The status was inserted so stream it to the user.
+ s.Stream.Update(ctx, account, apiStatus, streamType)
+ return true, nil
+ }
- return true, nil
+ // Status was hidden.
+ return false, nil
}
// timelineAndNotifyStatusForTagFollowers inserts the status into the