summaryrefslogtreecommitdiff
path: root/internal/federation/dereferencing/util.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-06-06 14:35:50 +0000
committerLibravatar GitHub <noreply@github.com>2024-06-06 15:35:50 +0100
commitb371c2db47a6c93fbea1b06b56eecb7237bc6130 (patch)
treecb351547a11e2bd722272ef9f1e4cc84ee88569c /internal/federation/dereferencing/util.go
parent[feature] Self-serve email change for users (#2957) (diff)
downloadgotosocial-b371c2db47a6c93fbea1b06b56eecb7237bc6130.tar.xz
[bugfix] update media if more than just url changes (#2970)
* refactor status media handling into separate functions, handle case of changed metadata * update fetchRemoteAccount{Avatar,Header} to use new refactored {load,update}Attachment() functions * whoops, nearly marked avatars as headers :') * reformatting to improve legibility
Diffstat (limited to 'internal/federation/dereferencing/util.go')
-rw-r--r--internal/federation/dereferencing/util.go111
1 files changed, 111 insertions, 0 deletions
diff --git a/internal/federation/dereferencing/util.go b/internal/federation/dereferencing/util.go
index 38622f6c1..5cb7a0106 100644
--- a/internal/federation/dereferencing/util.go
+++ b/internal/federation/dereferencing/util.go
@@ -18,11 +18,122 @@
package dereferencing
import (
+ "context"
+ "io"
+ "net/url"
"slices"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
+ "github.com/superseriousbusiness/gotosocial/internal/media"
+ "github.com/superseriousbusiness/gotosocial/internal/transport"
+ "github.com/superseriousbusiness/gotosocial/internal/util"
)
+// loadAttachment handles the case of a new media attachment
+// that requires loading. it stores and caches from given data.
+func (d *Dereferencer) loadAttachment(
+ ctx context.Context,
+ tsport transport.Transport,
+ accountID string, // media account owner
+ remoteURL string,
+ info *media.AdditionalMediaInfo,
+) (
+ *gtsmodel.MediaAttachment,
+ error,
+) {
+ // Parse str as valid URL object.
+ url, err := url.Parse(remoteURL)
+ if err != nil {
+ return nil, gtserror.Newf("invalid remote media url %q: %v", remoteURL, err)
+ }
+
+ // Start pre-processing remote media at remote URL.
+ processing := d.mediaManager.PreProcessMedia(
+ func(ctx context.Context) (io.ReadCloser, int64, error) {
+ return tsport.DereferenceMedia(ctx, url)
+ },
+ accountID,
+ info,
+ )
+
+ // Force attachment loading *right now*.
+ return processing.LoadAttachment(ctx)
+}
+
+// updateAttachment handles the case of an existing media attachment
+// that *may* have changes or need recaching. it checks for changed
+// fields, updating in the database if so, and recaches uncached media.
+func (d *Dereferencer) updateAttachment(
+ ctx context.Context,
+ tsport transport.Transport,
+ existing *gtsmodel.MediaAttachment, // existing attachment
+ media *gtsmodel.MediaAttachment, // (optional) changed media
+) (
+ *gtsmodel.MediaAttachment, // always set
+ error,
+) {
+ if media != nil {
+ // Possible changed media columns.
+ changed := make([]string, 0, 3)
+
+ // Check if attachment description has changed.
+ if existing.Description != media.Description {
+ changed = append(changed, "description")
+ existing.Description = media.Description
+ }
+
+ // Check if attachment blurhash has changed (i.e. content change).
+ if existing.Blurhash != media.Blurhash && media.Blurhash != "" {
+ changed = append(changed, "blurhash", "cached")
+ existing.Blurhash = media.Blurhash
+ existing.Cached = util.Ptr(false)
+ }
+
+ if len(changed) > 0 {
+ // Update the existing attachment model in the database.
+ err := d.state.DB.UpdateAttachment(ctx, existing, changed...)
+ if err != nil {
+ return media, gtserror.Newf("error updating media: %w", err)
+ }
+ }
+ }
+
+ // Check if cached.
+ if *existing.Cached {
+ return existing, nil
+ }
+
+ // Parse str as valid URL object.
+ url, err := url.Parse(existing.RemoteURL)
+ if err != nil {
+ return nil, gtserror.Newf("invalid remote media url %q: %v", media.RemoteURL, err)
+ }
+
+ // Start pre-processing remote media recaching from remote.
+ processing, err := d.mediaManager.PreProcessMediaRecache(
+ ctx,
+ func(ctx context.Context) (io.ReadCloser, int64, error) {
+ return tsport.DereferenceMedia(ctx, url)
+ },
+ existing.ID,
+ )
+ if err != nil {
+ return nil, gtserror.Newf("error processing recache: %w", err)
+ }
+
+ // Force load attachment recache *right now*.
+ recached, err := processing.LoadAttachment(ctx)
+
+ // Always return the error we
+ // receive, but ensure we return
+ // most up-to-date media file.
+ if recached != nil {
+ return recached, err
+ }
+ return existing, err
+}
+
// pollChanged returns whether a poll has changed in way that
// indicates that this should be an entirely new poll. i.e. if
// the available options have changed, or the expiry has increased.