diff options
Diffstat (limited to 'internal/processing/status')
-rw-r--r-- | internal/processing/status/create.go | 12 | ||||
-rw-r--r-- | internal/processing/status/status.go | 3 | ||||
-rw-r--r-- | internal/processing/status/util.go | 112 | ||||
-rw-r--r-- | internal/processing/status/util_test.go | 207 |
4 files changed, 52 insertions, 282 deletions
diff --git a/internal/processing/status/create.go b/internal/processing/status/create.go index 1a6177ef4..9e9d24c84 100644 --- a/internal/processing/status/create.go +++ b/internal/processing/status/create.go @@ -76,18 +76,6 @@ func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, appli return nil, gtserror.NewErrorInternalError(err) } - if err := p.ProcessMentions(ctx, form, account.ID, newStatus); err != nil { - return nil, gtserror.NewErrorInternalError(err) - } - - if err := p.ProcessTags(ctx, form, account.ID, newStatus); err != nil { - return nil, gtserror.NewErrorInternalError(err) - } - - if err := p.ProcessEmojis(ctx, form, account.ID, newStatus); err != nil { - return nil, gtserror.NewErrorInternalError(err) - } - if err := p.ProcessContent(ctx, form, account.ID, newStatus); err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/status/status.go b/internal/processing/status/status.go index 379b0661f..56b8b23eb 100644 --- a/internal/processing/status/status.go +++ b/internal/processing/status/status.go @@ -67,9 +67,6 @@ type Processor interface { ProcessReplyToID(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, thisAccountID string, status *gtsmodel.Status) gtserror.WithCode ProcessMediaIDs(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, thisAccountID string, status *gtsmodel.Status) gtserror.WithCode ProcessLanguage(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountDefaultLanguage string, status *gtsmodel.Status) error - ProcessMentions(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error - ProcessTags(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error - ProcessEmojis(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error ProcessContent(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error } diff --git a/internal/processing/status/util.go b/internal/processing/status/util.go index 2847d1c42..1115219cd 100644 --- a/internal/processing/status/util.go +++ b/internal/processing/status/util.go @@ -28,8 +28,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" - "github.com/superseriousbusiness/gotosocial/internal/log" - "github.com/superseriousbusiness/gotosocial/internal/util" + "github.com/superseriousbusiness/gotosocial/internal/text" ) func (p *processor) ProcessVisibility(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountDefaultVis gtsmodel.Visibility, status *gtsmodel.Status) error { @@ -212,80 +211,6 @@ func (p *processor) ProcessLanguage(ctx context.Context, form *apimodel.Advanced return nil } -func (p *processor) ProcessMentions(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error { - mentionedAccountNames := util.DeriveMentionNamesFromText(form.Status) - mentions := []*gtsmodel.Mention{} - mentionIDs := []string{} - - for _, mentionedAccountName := range mentionedAccountNames { - gtsMention, err := p.parseMention(ctx, mentionedAccountName, accountID, status.ID) - if err != nil { - log.Errorf("ProcessMentions: error parsing mention %s from status: %s", mentionedAccountName, err) - continue - } - - if err := p.db.Put(ctx, gtsMention); err != nil { - log.Errorf("ProcessMentions: error putting mention in db: %s", err) - } - - mentions = append(mentions, gtsMention) - mentionIDs = append(mentionIDs, gtsMention.ID) - } - - // add full populated gts menchies to the status for passing them around conveniently - status.Mentions = mentions - // add just the ids of the mentioned accounts to the status for putting in the db - status.MentionIDs = mentionIDs - - return nil -} - -func (p *processor) ProcessTags(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error { - tags := []string{} - gtsTags, err := p.db.TagStringsToTags(ctx, util.DeriveHashtagsFromText(form.Status), accountID) - if err != nil { - return fmt.Errorf("error generating hashtags from status: %s", err) - } - for _, tag := range gtsTags { - if err := p.db.Put(ctx, tag); err != nil { - if !errors.Is(err, db.ErrAlreadyExists) { - return fmt.Errorf("error putting tags in db: %s", err) - } - } - tags = append(tags, tag.ID) - } - // add full populated gts tags to the status for passing them around conveniently - status.Tags = gtsTags - // add just the ids of the used tags to the status for putting in the db - status.TagIDs = tags - return nil -} - -func (p *processor) ProcessEmojis(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error { - // for each emoji shortcode in the text, check if it's an enabled - // emoji on this instance, and if so, add it to the status - emojiShortcodes := util.DeriveEmojisFromText(form.SpoilerText + "\n\n" + form.Status) - status.Emojis = make([]*gtsmodel.Emoji, 0, len(emojiShortcodes)) - status.EmojiIDs = make([]string, 0, len(emojiShortcodes)) - - for _, shortcode := range emojiShortcodes { - emoji, err := p.db.GetEmojiByShortcodeDomain(ctx, shortcode, "") - if err != nil { - if err != db.ErrNoEntries { - log.Errorf("error getting local emoji with shortcode %s: %s", shortcode, err) - } - continue - } - - if *emoji.VisibleInPicker && !*emoji.Disabled { - status.Emojis = append(status.Emojis, emoji) - status.EmojiIDs = append(status.EmojiIDs, emoji.ID) - } - } - - return nil -} - func (p *processor) ProcessContent(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountID string, status *gtsmodel.Status) error { // if there's nothing in the status at all we can just return early if form.Status == "" { @@ -311,16 +236,43 @@ func (p *processor) ProcessContent(ctx context.Context, form *apimodel.AdvancedS } // parse content out of the status depending on what format has been submitted - var formatted string + var f text.FormatFunc switch form.Format { case apimodel.StatusFormatPlain: - formatted = p.formatter.FromPlain(ctx, form.Status, status.Mentions, status.Tags) + f = p.formatter.FromPlain case apimodel.StatusFormatMarkdown: - formatted = p.formatter.FromMarkdown(ctx, form.Status, status.Mentions, status.Tags, status.Emojis) + f = p.formatter.FromMarkdown default: return fmt.Errorf("format %s not recognised as a valid status format", form.Format) } + formatted := f(ctx, p.parseMention, accountID, status.ID, form.Status) + + // add full populated gts {mentions, tags, emojis} to the status for passing them around conveniently + // add just their ids to the status for putting in the db + status.Mentions = formatted.Mentions + status.MentionIDs = make([]string, 0, len(formatted.Mentions)) + for _, gtsmention := range formatted.Mentions { + status.MentionIDs = append(status.MentionIDs, gtsmention.ID) + } + + status.Tags = formatted.Tags + status.TagIDs = make([]string, 0, len(formatted.Tags)) + for _, gtstag := range formatted.Tags { + status.TagIDs = append(status.TagIDs, gtstag.ID) + } + + status.Emojis = formatted.Emojis + status.EmojiIDs = make([]string, 0, len(formatted.Emojis)) + for _, gtsemoji := range formatted.Emojis { + status.EmojiIDs = append(status.EmojiIDs, gtsemoji.ID) + } + + spoilerformatted := p.formatter.FromPlainEmojiOnly(ctx, p.parseMention, accountID, status.ID, form.SpoilerText) + for _, gtsemoji := range spoilerformatted.Emojis { + status.Emojis = append(status.Emojis, gtsemoji) + status.EmojiIDs = append(status.EmojiIDs, gtsemoji.ID) + } - status.Content = formatted + status.Content = formatted.HTML return nil } diff --git a/internal/processing/status/util_test.go b/internal/processing/status/util_test.go index d4be4337b..acd823188 100644 --- a/internal/processing/status/util_test.go +++ b/internal/processing/status/util_test.go @@ -29,22 +29,23 @@ import ( ) const ( - statusText1 = "Another test @foss_satan@fossbros-anonymous.io\n\n#Hashtag\n\nText" - statusText1ExpectedFull = "<p>Another test <span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span><br/><br/><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a><br/><br/>Text</p>" - statusText1ExpectedPartial = "<p>Another test <span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span><br/><br/>#Hashtag<br/><br/>Text</p>" - statusText2 = "Another test @foss_satan@fossbros-anonymous.io\n\n#Hashtag\n\n#hashTAG" - status2TextExpectedFull = "<p>Another test <span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span><br/><br/><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a><br/><br/><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashTAG</span></a></p>" - status2TextExpectedPartial = "<p>Another test <span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span><br/><br/>#Hashtag<br/><br/>#hashTAG</p>" + statusText1 = "Another test @foss_satan@fossbros-anonymous.io\n\n#Hashtag\n\nText" + statusText1Expected = "<p>Another test <span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span><br><br><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a><br><br>Text</p>" + statusText2 = "Another test @foss_satan@fossbros-anonymous.io\n\n#Hashtag\n\n#hashTAG" + status2TextExpected = "<p>Another test <span class=\"h-card\"><a href=\"http://fossbros-anonymous.io/@foss_satan\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>foss_satan</span></a></span><br><br><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>Hashtag</span></a><br><br><a href=\"http://localhost:8080/tags/Hashtag\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hashTAG</span></a></p>" ) type UtilTestSuite struct { StatusStandardTestSuite } -func (suite *UtilTestSuite) TestProcessMentions1() { +func (suite *UtilTestSuite) TestProcessContent1() { + /* + TEST PREPARATION + */ + // we need to partially process the status first since processContent expects a status with some stuff already set on it creatingAccount := suite.testAccounts["local_account_1"] mentionedAccount := suite.testAccounts["remote_account_1"] - form := &apimodel.AdvancedStatusCreateForm{ StatusCreateRequest: apimodel.StatusCreateRequest{ Status: statusText1, @@ -70,8 +71,13 @@ func (suite *UtilTestSuite) TestProcessMentions1() { ID: "01FCTDD78JJMX3K9KPXQ7ZQ8BJ", } - err := suite.status.ProcessMentions(context.Background(), form, creatingAccount.ID, status) + /* + ACTUAL TEST + */ + + err := suite.status.ProcessContent(context.Background(), form, creatingAccount.ID, status) suite.NoError(err) + suite.Equal(statusText1Expected, status.Content) suite.Len(status.Mentions, 1) newMention := status.Mentions[0] @@ -88,63 +94,16 @@ func (suite *UtilTestSuite) TestProcessMentions1() { suite.Equal(newMention.ID, status.MentionIDs[0]) } -func (suite *UtilTestSuite) TestProcessContentFull1() { - /* - TEST PREPARATION - */ - // we need to partially process the status first since processContent expects a status with some stuff already set on it - creatingAccount := suite.testAccounts["local_account_1"] - form := &apimodel.AdvancedStatusCreateForm{ - StatusCreateRequest: apimodel.StatusCreateRequest{ - Status: statusText1, - MediaIDs: []string{}, - Poll: nil, - InReplyToID: "", - Sensitive: false, - SpoilerText: "", - Visibility: apimodel.VisibilityPublic, - ScheduledAt: "", - Language: "en", - Format: apimodel.StatusFormatPlain, - }, - AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{ - Federated: nil, - Boostable: nil, - Replyable: nil, - Likeable: nil, - }, - } - - status := >smodel.Status{ - ID: "01FCTDD78JJMX3K9KPXQ7ZQ8BJ", - } - - err := suite.status.ProcessMentions(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - suite.Empty(status.Content) // shouldn't be set yet - - err = suite.status.ProcessTags(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - suite.Empty(status.Content) // shouldn't be set yet - - /* - ACTUAL TEST - */ - - err = suite.status.ProcessContent(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - suite.Equal(statusText1ExpectedFull, status.Content) -} - -func (suite *UtilTestSuite) TestProcessContentPartial1() { +func (suite *UtilTestSuite) TestProcessContent2() { /* TEST PREPARATION */ // we need to partially process the status first since processContent expects a status with some stuff already set on it creatingAccount := suite.testAccounts["local_account_1"] + mentionedAccount := suite.testAccounts["remote_account_1"] form := &apimodel.AdvancedStatusCreateForm{ StatusCreateRequest: apimodel.StatusCreateRequest{ - Status: statusText1, + Status: statusText2, MediaIDs: []string{}, Poll: nil, InReplyToID: "", @@ -167,50 +126,14 @@ func (suite *UtilTestSuite) TestProcessContentPartial1() { ID: "01FCTDD78JJMX3K9KPXQ7ZQ8BJ", } - err := suite.status.ProcessMentions(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - suite.Empty(status.Content) // shouldn't be set yet - /* ACTUAL TEST */ - err = suite.status.ProcessContent(context.Background(), form, creatingAccount.ID, status) + err := suite.status.ProcessContent(context.Background(), form, creatingAccount.ID, status) suite.NoError(err) - suite.Equal(statusText1ExpectedPartial, status.Content) -} -func (suite *UtilTestSuite) TestProcessMentions2() { - creatingAccount := suite.testAccounts["local_account_1"] - mentionedAccount := suite.testAccounts["remote_account_1"] - - form := &apimodel.AdvancedStatusCreateForm{ - StatusCreateRequest: apimodel.StatusCreateRequest{ - Status: statusText2, - MediaIDs: []string{}, - Poll: nil, - InReplyToID: "", - Sensitive: false, - SpoilerText: "", - Visibility: apimodel.VisibilityPublic, - ScheduledAt: "", - Language: "en", - Format: apimodel.StatusFormatPlain, - }, - AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{ - Federated: nil, - Boostable: nil, - Replyable: nil, - Likeable: nil, - }, - } - - status := >smodel.Status{ - ID: "01FCTDD78JJMX3K9KPXQ7ZQ8BJ", - } - - err := suite.status.ProcessMentions(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) + suite.Equal(status2TextExpected, status.Content) suite.Len(status.Mentions, 1) newMention := status.Mentions[0] @@ -227,96 +150,6 @@ func (suite *UtilTestSuite) TestProcessMentions2() { suite.Equal(newMention.ID, status.MentionIDs[0]) } -func (suite *UtilTestSuite) TestProcessContentFull2() { - /* - TEST PREPARATION - */ - // we need to partially process the status first since processContent expects a status with some stuff already set on it - creatingAccount := suite.testAccounts["local_account_1"] - form := &apimodel.AdvancedStatusCreateForm{ - StatusCreateRequest: apimodel.StatusCreateRequest{ - Status: statusText2, - MediaIDs: []string{}, - Poll: nil, - InReplyToID: "", - Sensitive: false, - SpoilerText: "", - Visibility: apimodel.VisibilityPublic, - ScheduledAt: "", - Language: "en", - Format: apimodel.StatusFormatPlain, - }, - AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{ - Federated: nil, - Boostable: nil, - Replyable: nil, - Likeable: nil, - }, - } - - status := >smodel.Status{ - ID: "01FCTDD78JJMX3K9KPXQ7ZQ8BJ", - } - - err := suite.status.ProcessMentions(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - suite.Empty(status.Content) // shouldn't be set yet - - err = suite.status.ProcessTags(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - suite.Empty(status.Content) // shouldn't be set yet - - /* - ACTUAL TEST - */ - - err = suite.status.ProcessContent(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - - suite.Equal(status2TextExpectedFull, status.Content) -} - -func (suite *UtilTestSuite) TestProcessContentPartial2() { - /* - TEST PREPARATION - */ - // we need to partially process the status first since processContent expects a status with some stuff already set on it - creatingAccount := suite.testAccounts["local_account_1"] - form := &apimodel.AdvancedStatusCreateForm{ - StatusCreateRequest: apimodel.StatusCreateRequest{ - Status: statusText2, - MediaIDs: []string{}, - Poll: nil, - InReplyToID: "", - Sensitive: false, - SpoilerText: "", - Visibility: apimodel.VisibilityPublic, - ScheduledAt: "", - Language: "en", - Format: apimodel.StatusFormatPlain, - }, - AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{ - Federated: nil, - Boostable: nil, - Replyable: nil, - Likeable: nil, - }, - } - - status := >smodel.Status{ - ID: "01FCTDD78JJMX3K9KPXQ7ZQ8BJ", - } - - err := suite.status.ProcessMentions(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - suite.Empty(status.Content) - - err = suite.status.ProcessContent(context.Background(), form, creatingAccount.ID, status) - suite.NoError(err) - - suite.Equal(status2TextExpectedPartial, status.Content) -} - func TestUtilTestSuite(t *testing.T) { suite.Run(t, new(UtilTestSuite)) } |