mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-29 07:02:45 +00:00
[bugfix] Fix failure to look up remote profiles with duplicate emojis in some cases (#1534)
* Tidy up emoji parsing on profile submission Don't bother reparsing for emoji unless one of the fields that can have emoji in it has changed. Deduplicate emoji between the display name and profile note - I'm not sure whether this was hurting anything, but better safe. * Deduplicate emoji when parsing remote accounts Some servers - Misskey at least - don't deduplicate emoji, so it's possible to get an account which has the same emoji used in both the display name and note and therefore includes that emoji twice in its metadata. When we start trying to put those into our database, we run into a uniqueness constraint and fall over. This change just deduplicates at the point of construction of an account.
This commit is contained in:
parent
2af33d3fb5
commit
f559d46261
|
@ -453,6 +453,7 @@ func ExtractHashtag(i Hashtaggable) (*gtsmodel.Tag, error) {
|
||||||
// ExtractEmojis returns a slice of emojis on the interface.
|
// ExtractEmojis returns a slice of emojis on the interface.
|
||||||
func ExtractEmojis(i WithTag) ([]*gtsmodel.Emoji, error) {
|
func ExtractEmojis(i WithTag) ([]*gtsmodel.Emoji, error) {
|
||||||
emojis := []*gtsmodel.Emoji{}
|
emojis := []*gtsmodel.Emoji{}
|
||||||
|
emojiMap := make(map[string]*gtsmodel.Emoji)
|
||||||
tagsProp := i.GetActivityStreamsTag()
|
tagsProp := i.GetActivityStreamsTag()
|
||||||
if tagsProp == nil {
|
if tagsProp == nil {
|
||||||
return emojis, nil
|
return emojis, nil
|
||||||
|
@ -477,6 +478,9 @@ func ExtractEmojis(i WithTag) ([]*gtsmodel.Emoji, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emojiMap[emoji.URI] = emoji
|
||||||
|
}
|
||||||
|
for _, emoji := range emojiMap {
|
||||||
emojis = append(emojis, emoji)
|
emojis = append(emojis, emoji)
|
||||||
}
|
}
|
||||||
return emojis, nil
|
return emojis, nil
|
||||||
|
|
|
@ -45,23 +45,14 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form
|
||||||
account.Bot = form.Bot
|
account.Bot = form.Bot
|
||||||
}
|
}
|
||||||
|
|
||||||
account.Emojis = []*gtsmodel.Emoji{}
|
reparseEmojis := false
|
||||||
account.EmojiIDs = []string{}
|
|
||||||
|
|
||||||
if form.DisplayName != nil {
|
if form.DisplayName != nil {
|
||||||
if err := validate.DisplayName(*form.DisplayName); err != nil {
|
if err := validate.DisplayName(*form.DisplayName); err != nil {
|
||||||
return nil, gtserror.NewErrorBadRequest(err)
|
return nil, gtserror.NewErrorBadRequest(err)
|
||||||
}
|
}
|
||||||
account.DisplayName = text.SanitizePlaintext(*form.DisplayName)
|
account.DisplayName = text.SanitizePlaintext(*form.DisplayName)
|
||||||
}
|
reparseEmojis = true
|
||||||
|
|
||||||
// Re-parse for emojis regardless of whether the DisplayName changed
|
|
||||||
// because we can't otherwise tell which emojis belong to DisplayName
|
|
||||||
// and which belong to Note
|
|
||||||
formatResult := p.formatter.FromPlainEmojiOnly(ctx, p.parseMention, account.ID, "", account.DisplayName)
|
|
||||||
for _, emoji := range formatResult.Emojis {
|
|
||||||
account.Emojis = append(account.Emojis, emoji)
|
|
||||||
account.EmojiIDs = append(account.EmojiIDs, emoji.ID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.Note != nil {
|
if form.Note != nil {
|
||||||
|
@ -71,23 +62,40 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form
|
||||||
|
|
||||||
// Set the raw note before processing
|
// Set the raw note before processing
|
||||||
account.NoteRaw = *form.Note
|
account.NoteRaw = *form.Note
|
||||||
|
reparseEmojis = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// As per DisplayName, we need to reparse regardless to keep emojis straight
|
if reparseEmojis {
|
||||||
// Process note to generate a valid HTML representation
|
// If either DisplayName or Note changed, reparse both, because we
|
||||||
var f text.FormatFunc
|
// can't otherwise tell which one each emoji belongs to.
|
||||||
if account.StatusFormat == "markdown" {
|
// Deduplicate emojis between the two fields.
|
||||||
f = p.formatter.FromMarkdown
|
emojis := make(map[string]*gtsmodel.Emoji)
|
||||||
} else {
|
formatResult := p.formatter.FromPlainEmojiOnly(ctx, p.parseMention, account.ID, "", account.DisplayName)
|
||||||
f = p.formatter.FromPlain
|
for _, emoji := range formatResult.Emojis {
|
||||||
}
|
emojis[emoji.ID] = emoji
|
||||||
formatted := f(ctx, p.parseMention, account.ID, "", account.NoteRaw)
|
}
|
||||||
|
|
||||||
// Set updated HTML-ified note
|
// Process note to generate a valid HTML representation
|
||||||
account.Note = formatted.HTML
|
var f text.FormatFunc
|
||||||
for _, emoji := range formatted.Emojis {
|
if account.StatusFormat == "markdown" {
|
||||||
account.Emojis = append(account.Emojis, emoji)
|
f = p.formatter.FromMarkdown
|
||||||
account.EmojiIDs = append(account.EmojiIDs, emoji.ID)
|
} else {
|
||||||
|
f = p.formatter.FromPlain
|
||||||
|
}
|
||||||
|
formatted := f(ctx, p.parseMention, account.ID, "", account.NoteRaw)
|
||||||
|
|
||||||
|
// Set updated HTML-ified note
|
||||||
|
account.Note = formatted.HTML
|
||||||
|
for _, emoji := range formatted.Emojis {
|
||||||
|
emojis[emoji.ID] = emoji
|
||||||
|
}
|
||||||
|
|
||||||
|
account.Emojis = []*gtsmodel.Emoji{}
|
||||||
|
account.EmojiIDs = []string{}
|
||||||
|
for eid, emoji := range emojis {
|
||||||
|
account.Emojis = append(account.Emojis, emoji)
|
||||||
|
account.EmojiIDs = append(account.EmojiIDs, eid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.Avatar != nil && form.Avatar.Size != 0 {
|
if form.Avatar != nil && form.Avatar.Size != 0 {
|
||||||
|
|
Loading…
Reference in a new issue