summaryrefslogtreecommitdiff
path: root/internal/processing/conversations
diff options
context:
space:
mode:
Diffstat (limited to 'internal/processing/conversations')
-rw-r--r--internal/processing/conversations/conversations.go41
-rw-r--r--internal/processing/conversations/conversations_test.go9
-rw-r--r--internal/processing/conversations/get.go9
-rw-r--r--internal/processing/conversations/read.go6
-rw-r--r--internal/processing/conversations/update.go125
5 files changed, 72 insertions, 118 deletions
diff --git a/internal/processing/conversations/conversations.go b/internal/processing/conversations/conversations.go
index a4b8b7234..e31f60500 100644
--- a/internal/processing/conversations/conversations.go
+++ b/internal/processing/conversations/conversations.go
@@ -22,9 +22,8 @@ import (
"errors"
"code.superseriousbusiness.org/gotosocial/internal/db"
- "code.superseriousbusiness.org/gotosocial/internal/filter/usermute"
+ "code.superseriousbusiness.org/gotosocial/internal/filter/mutes"
"code.superseriousbusiness.org/gotosocial/internal/filter/visibility"
- "code.superseriousbusiness.org/gotosocial/internal/gtscontext"
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
"code.superseriousbusiness.org/gotosocial/internal/state"
@@ -32,20 +31,23 @@ import (
)
type Processor struct {
- state *state.State
- converter *typeutils.Converter
- filter *visibility.Filter
+ state *state.State
+ converter *typeutils.Converter
+ visFilter *visibility.Filter
+ muteFilter *mutes.Filter
}
func New(
state *state.State,
converter *typeutils.Converter,
- filter *visibility.Filter,
+ visFilter *visibility.Filter,
+ muteFilter *mutes.Filter,
) Processor {
return Processor{
- state: state,
- converter: converter,
- filter: filter,
+ state: state,
+ converter: converter,
+ visFilter: visFilter,
+ muteFilter: muteFilter,
}
}
@@ -95,13 +97,13 @@ func (p *Processor) getConversationOwnedBy(
}
// getFiltersAndMutes gets the given account's filters and compiled mute list.
-func (p *Processor) getFiltersAndMutes(
+func (p *Processor) getFilters(
ctx context.Context,
requestingAccount *gtsmodel.Account,
-) ([]*gtsmodel.Filter, *usermute.CompiledUserMuteList, gtserror.WithCode) {
+) ([]*gtsmodel.Filter, gtserror.WithCode) {
filters, err := p.state.DB.GetFiltersForAccountID(ctx, requestingAccount.ID)
if err != nil {
- return nil, nil, gtserror.NewErrorInternalError(
+ return nil, gtserror.NewErrorInternalError(
gtserror.Newf(
"DB error getting filters for account %s: %w",
requestingAccount.ID,
@@ -109,18 +111,5 @@ func (p *Processor) getFiltersAndMutes(
),
)
}
-
- mutes, err := p.state.DB.GetAccountMutes(gtscontext.SetBarebones(ctx), requestingAccount.ID, nil)
- if err != nil {
- return nil, nil, gtserror.NewErrorInternalError(
- gtserror.Newf(
- "DB error getting mutes for account %s: %w",
- requestingAccount.ID,
- err,
- ),
- )
- }
- compiledMutes := usermute.NewCompiledUserMuteList(mutes)
-
- return filters, compiledMutes, nil
+ return filters, nil
}
diff --git a/internal/processing/conversations/conversations_test.go b/internal/processing/conversations/conversations_test.go
index 40145c2fb..383938564 100644
--- a/internal/processing/conversations/conversations_test.go
+++ b/internal/processing/conversations/conversations_test.go
@@ -27,6 +27,7 @@ import (
dbtest "code.superseriousbusiness.org/gotosocial/internal/db/test"
"code.superseriousbusiness.org/gotosocial/internal/email"
"code.superseriousbusiness.org/gotosocial/internal/federation"
+ "code.superseriousbusiness.org/gotosocial/internal/filter/mutes"
"code.superseriousbusiness.org/gotosocial/internal/filter/visibility"
"code.superseriousbusiness.org/gotosocial/internal/gtsmodel"
"code.superseriousbusiness.org/gotosocial/internal/log"
@@ -53,7 +54,8 @@ type ConversationsTestSuite struct {
federator *federation.Federator
emailSender email.Sender
sentEmails map[string]string
- filter *visibility.Filter
+ visFilter *visibility.Filter
+ muteFilter *mutes.Filter
// standard suite models
testTokens map[string]*gtsmodel.Token
@@ -104,7 +106,8 @@ func (suite *ConversationsTestSuite) SetupTest() {
suite.state.DB = suite.db
suite.state.AdminActions = admin.New(suite.state.DB, &suite.state.Workers)
suite.tc = typeutils.NewConverter(&suite.state)
- suite.filter = visibility.NewFilter(&suite.state)
+ suite.visFilter = visibility.NewFilter(&suite.state)
+ suite.muteFilter = mutes.NewFilter(&suite.state)
suite.storage = testrig.NewInMemoryStorage()
suite.state.Storage = suite.storage
@@ -115,7 +118,7 @@ func (suite *ConversationsTestSuite) SetupTest() {
suite.sentEmails = make(map[string]string)
suite.emailSender = testrig.NewEmailSender("../../../web/template/", suite.sentEmails)
- suite.conversationsProcessor = conversations.New(&suite.state, suite.tc, suite.filter)
+ suite.conversationsProcessor = conversations.New(&suite.state, suite.tc, suite.visFilter, suite.muteFilter)
testrig.StandardDBSetup(suite.db, nil)
testrig.StandardStorageSetup(suite.storage, "../../../testrig/media")
diff --git a/internal/processing/conversations/get.go b/internal/processing/conversations/get.go
index 9218942bf..5324466c9 100644
--- a/internal/processing/conversations/get.go
+++ b/internal/processing/conversations/get.go
@@ -64,23 +64,20 @@ func (p *Processor) GetAll(
items := make([]interface{}, 0, count)
- filters, mutes, errWithCode := p.getFiltersAndMutes(ctx, requestingAccount)
+ filters, errWithCode := p.getFilters(ctx, requestingAccount)
if errWithCode != nil {
return nil, errWithCode
}
for _, conversation := range conversations {
// Convert conversation to frontend API model.
- apiConversation, err := p.converter.ConversationToAPIConversation(
- ctx,
+ apiConversation, err := p.converter.ConversationToAPIConversation(ctx,
conversation,
requestingAccount,
filters,
- mutes,
)
if err != nil {
- log.Errorf(
- ctx,
+ log.Errorf(ctx,
"error converting conversation %s to API representation: %v",
conversation.ID,
err,
diff --git a/internal/processing/conversations/read.go b/internal/processing/conversations/read.go
index 42f369582..4d16a4eeb 100644
--- a/internal/processing/conversations/read.go
+++ b/internal/processing/conversations/read.go
@@ -44,17 +44,15 @@ func (p *Processor) Read(
return nil, gtserror.NewErrorInternalError(err)
}
- filters, mutes, errWithCode := p.getFiltersAndMutes(ctx, requestingAccount)
+ filters, errWithCode := p.getFilters(ctx, requestingAccount)
if errWithCode != nil {
return nil, errWithCode
}
- apiConversation, err := p.converter.ConversationToAPIConversation(
- ctx,
+ apiConversation, err := p.converter.ConversationToAPIConversation(ctx,
conversation,
requestingAccount,
filters,
- mutes,
)
if err != nil {
err = gtserror.Newf("error converting conversation %s to API representation: %w", id, err)
diff --git a/internal/processing/conversations/update.go b/internal/processing/conversations/update.go
index 1651d5367..e4024a24a 100644
--- a/internal/processing/conversations/update.go
+++ b/internal/processing/conversations/update.go
@@ -31,10 +31,14 @@ import (
"code.superseriousbusiness.org/gotosocial/internal/util"
)
-// ConversationNotification carries the arguments to processing/stream.Processor.Conversation.
+// ConversationNotification carries the arguments
+// to processing/stream.Processor.Conversation.
type ConversationNotification struct {
- // AccountID of a local account to deliver the notification to.
+
+ // AccountID of a local account to
+ // deliver the notification to.
AccountID string
+
// Conversation as the notification payload.
Conversation *apimodel.Conversation
}
@@ -46,11 +50,13 @@ func (p *Processor) UpdateConversationsForStatus(ctx context.Context, status *gt
// Only DMs are considered part of conversations.
return nil, nil
}
+
if status.BoostOfID != "" {
// Boosts can't be part of conversations.
// FUTURE: This may change if we ever implement quote posts.
return nil, nil
}
+
if status.ThreadID == "" {
// If the status doesn't have a thread ID, it didn't mention a local account,
// and thus can't be part of a conversation.
@@ -77,51 +83,15 @@ func (p *Processor) UpdateConversationsForStatus(ctx context.Context, status *gt
}
localAccount := participant
- // If the status is not visible to this account, skip processing it for this account.
- visible, err := p.filter.StatusVisible(ctx, localAccount, status)
+ // If status not visible to this account, skip further processing.
+ visible, err := p.visFilter.StatusVisible(ctx, localAccount, status)
if err != nil {
- log.Errorf(
- ctx,
- "error checking status %s visibility for account %s: %v",
- status.ID,
- localAccount.ID,
- err,
- )
+ log.Errorf(ctx, "error checking status %s visibility for account %s: %v", status.URI, localAccount.URI, err)
continue
} else if !visible {
continue
}
- // Is the status filtered or muted for this user?
- // Converting the status to an API status runs the filter/mute checks.
- filters, mutes, errWithCode := p.getFiltersAndMutes(ctx, localAccount)
- if errWithCode != nil {
- log.Error(ctx, errWithCode)
- continue
- }
- _, err = p.converter.StatusToAPIStatus(
- ctx,
- status,
- localAccount,
- statusfilter.FilterContextNotifications,
- filters,
- mutes,
- )
- if err != nil {
- // If the status matched a hide filter, skip processing it for this account.
- // If there was another kind of error, log that and skip it anyway.
- if !errors.Is(err, statusfilter.ErrHideStatus) {
- log.Errorf(
- ctx,
- "error checking status %s filtering/muting for account %s: %v",
- status.ID,
- localAccount.ID,
- err,
- )
- }
- continue
- }
-
// Collect other accounts participating in the conversation.
otherAccounts := make([]*gtsmodel.Account, 0, len(allParticipantsSet)-1)
otherAccountIDs := make([]string, 0, len(allParticipantsSet)-1)
@@ -133,20 +103,14 @@ func (p *Processor) UpdateConversationsForStatus(ctx context.Context, status *gt
}
// Check for a previously existing conversation, if there is one.
- conversation, err := p.state.DB.GetConversationByThreadAndAccountIDs(
- ctx,
+ conversation, err := p.state.DB.GetConversationByThreadAndAccountIDs(ctx,
status.ThreadID,
localAccount.ID,
otherAccountIDs,
)
if err != nil && !errors.Is(err, db.ErrNoEntries) {
- log.Errorf(
- ctx,
- "error trying to find a previous conversation for status %s and account %s: %v",
- status.ID,
- localAccount.ID,
- err,
- )
+ log.Errorf(ctx, "error finding previous conversation for status %s and account %s: %v",
+ status.URI, localAccount.URI, err)
continue
}
@@ -172,6 +136,7 @@ func (p *Processor) UpdateConversationsForStatus(ctx context.Context, status *gt
conversation.LastStatusID = status.ID
conversation.LastStatus = status
}
+
// If the conversation is unread, leave it marked as unread.
// If the conversation is read but this status might not have been, mark the conversation as unread.
if !statusAuthoredByConversationOwner {
@@ -181,43 +146,29 @@ func (p *Processor) UpdateConversationsForStatus(ctx context.Context, status *gt
// Create or update the conversation.
err = p.state.DB.UpsertConversation(ctx, conversation)
if err != nil {
- log.Errorf(
- ctx,
- "error creating or updating conversation %s for status %s and account %s: %v",
- conversation.ID,
- status.ID,
- localAccount.ID,
- err,
- )
+ log.Errorf(ctx, "error creating or updating conversation %s for status %s and account %s: %v",
+ conversation.ID, status.URI, localAccount.URI, err)
continue
}
// Link the conversation to the status.
if err := p.state.DB.LinkConversationToStatus(ctx, conversation.ID, status.ID); err != nil {
- log.Errorf(
- ctx,
- "error linking conversation %s to status %s: %v",
- conversation.ID,
- status.ID,
- err,
- )
+ log.Errorf(ctx, "error linking conversation %s to status %s: %v",
+ conversation.ID, status.URI, err)
continue
}
// Convert the conversation to API representation.
- apiConversation, err := p.converter.ConversationToAPIConversation(
- ctx,
+ apiConversation, err := p.converter.ConversationToAPIConversation(ctx,
conversation,
localAccount,
- filters,
- mutes,
+ nil,
)
if err != nil {
// If the conversation's last status matched a hide filter, skip it.
// If there was another kind of error, log that and skip it anyway.
if !errors.Is(err, statusfilter.ErrHideStatus) {
- log.Errorf(
- ctx,
+ log.Errorf(ctx,
"error converting conversation %s to API representation for account %s: %v",
status.ID,
localAccount.ID,
@@ -227,15 +178,31 @@ func (p *Processor) UpdateConversationsForStatus(ctx context.Context, status *gt
continue
}
- // Generate a notification,
- // unless the status was authored by the user who would be notified,
- // in which case they already know.
- if status.AccountID != localAccount.ID {
- notifications = append(notifications, ConversationNotification{
- AccountID: localAccount.ID,
- Conversation: apiConversation,
- })
+ // If status was authored by this participant,
+ // don't bother notifying, they already know!
+ if status.AccountID == localAccount.ID {
+ continue
}
+
+ // Check whether status is muted to local participant.
+ muted, err := p.muteFilter.StatusNotificationsMuted(ctx,
+ localAccount,
+ status,
+ )
+ if err != nil {
+ log.Errorf(ctx, "error checking status mute: %v", err)
+ continue
+ }
+
+ if muted {
+ continue
+ }
+
+ // Generate a notification,
+ notifications = append(notifications, ConversationNotification{
+ AccountID: localAccount.ID,
+ Conversation: apiConversation,
+ })
}
return notifications, nil