summaryrefslogtreecommitdiff
path: root/internal/federation/dereferencing/emoji.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/federation/dereferencing/emoji.go')
-rw-r--r--internal/federation/dereferencing/emoji.go89
1 files changed, 80 insertions, 9 deletions
diff --git a/internal/federation/dereferencing/emoji.go b/internal/federation/dereferencing/emoji.go
index 22b5a0442..3174fa2f9 100644
--- a/internal/federation/dereferencing/emoji.go
+++ b/internal/federation/dereferencing/emoji.go
@@ -134,11 +134,6 @@ func (d *Dereferencer) RefreshEmoji(
*gtsmodel.Emoji,
error,
) {
- // Can't refresh local.
- if emoji.IsLocal() {
- return emoji, nil
- }
-
// Check emoji is up-to-date
// with provided extra info.
switch {
@@ -156,8 +151,18 @@ func (d *Dereferencer) RefreshEmoji(
force = true
}
- // Check if needs updating.
- if *emoji.Cached && !force {
+ // Check if needs
+ // force refresh.
+ if !force {
+
+ // We still want to make sure
+ // the emoji is cached. Simply
+ // check whether emoji is cached.
+ return d.RecacheEmoji(ctx, emoji)
+ }
+
+ // Can't refresh local.
+ if emoji.IsLocal() {
return emoji, nil
}
@@ -191,8 +196,8 @@ func (d *Dereferencer) RefreshEmoji(
return tsport.DereferenceMedia(ctx, url, int64(maxsz))
}
- // Refresh emoji with prepared info.
- return d.mediaManager.RefreshEmoji(ctx,
+ // Update emoji with prepared info.
+ return d.mediaManager.UpdateEmoji(ctx,
emoji,
data,
info,
@@ -201,6 +206,72 @@ func (d *Dereferencer) RefreshEmoji(
)
}
+// RecacheEmoji handles the simplest case which is that
+// of an existing emoji that only needs to be recached.
+// It handles the case of both local emojis, and those
+// already cached as no-ops.
+//
+// Please note that even if an error is returned,
+// an emoji model may still be returned if the error
+// was only encountered during actual dereferencing.
+// In this case, it will act as a placeholder.
+func (d *Dereferencer) RecacheEmoji(
+ ctx context.Context,
+ emoji *gtsmodel.Emoji,
+) (
+ *gtsmodel.Emoji,
+ error,
+) {
+ // Can't recache local.
+ if emoji.IsLocal() {
+ return emoji, nil
+ }
+
+ if *emoji.Cached {
+ // Already cached.
+ return emoji, nil
+ }
+
+ // Get shortcode domain for locks + logging.
+ shortcodeDomain := emoji.ShortcodeDomain()
+
+ // Ensure we have a valid image remote URL.
+ url, err := url.Parse(emoji.ImageRemoteURL)
+ if err != nil {
+ err := gtserror.Newf("invalid image remote url %s for emoji %s: %w", emoji.ImageRemoteURL, shortcodeDomain, err)
+ return nil, err
+ }
+
+ // Pass along for safe processing.
+ return d.processEmojiSafely(ctx,
+ shortcodeDomain,
+ func() (*media.ProcessingEmoji, error) {
+
+ // Acquire new instance account transport for emoji dereferencing.
+ tsport, err := d.transportController.NewTransportForUsername(ctx, "")
+ if err != nil {
+ err := gtserror.Newf("error getting instance transport: %w", err)
+ return nil, err
+ }
+
+ // Get maximum supported remote emoji size.
+ maxsz := config.GetMediaEmojiRemoteMaxSize()
+
+ // Prepare data function to dereference remote emoji media.
+ data := func(context.Context) (io.ReadCloser, error) {
+ return tsport.DereferenceMedia(ctx, url, int64(maxsz))
+ }
+
+ // Recache emoji with prepared info.
+ return d.mediaManager.CacheEmoji(ctx,
+ emoji,
+ data,
+ )
+ },
+ )
+
+}
+
// processingEmojiSafely provides concurrency-safe processing of
// an emoji with given shortcode+domain. if a copy of the emoji is
// not already being processed, the given 'process' callback will