Skip to content

Commit

Permalink
[feature] Media attachment placeholders (#2331)
Browse files Browse the repository at this point in the history
* [feature] Use placeholders for unknown media types

* fix read of underreported small files

* switch to reduce nesting

* simplify cleanup
  • Loading branch information
tsmethurst committed Nov 10, 2023
1 parent c7ecab9 commit ba9d6b4
Show file tree
Hide file tree
Showing 41 changed files with 1,473 additions and 842 deletions.
4 changes: 2 additions & 2 deletions internal/api/client/followrequests/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ func (suite *GetTestSuite) TestGet() {
"header_static": "http://localhost:8080/assets/default_header.png",
"followers_count": 0,
"following_count": 0,
"statuses_count": 0,
"last_status_at": null,
"statuses_count": 1,
"last_status_at": "2023-11-02T10:44:25.000Z",
"emojis": [],
"fields": []
}
Expand Down
8 changes: 4 additions & 4 deletions internal/api/client/media/mediacreate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ func (suite *MediaCreateTestSuite) TestMediaCreateSuccessful() {
X: -0.5,
Y: 0.5,
},
}, attachmentReply.Meta)
suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", attachmentReply.Blurhash)
}, *attachmentReply.Meta)
suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", *attachmentReply.Blurhash)
suite.NotEmpty(attachmentReply.ID)
suite.NotEmpty(attachmentReply.URL)
suite.NotEmpty(attachmentReply.PreviewURL)
Expand Down Expand Up @@ -301,8 +301,8 @@ func (suite *MediaCreateTestSuite) TestMediaCreateSuccessfulV2() {
X: -0.5,
Y: 0.5,
},
}, attachmentReply.Meta)
suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", attachmentReply.Blurhash)
}, *attachmentReply.Meta)
suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", *attachmentReply.Blurhash)
suite.NotEmpty(attachmentReply.ID)
suite.Nil(attachmentReply.URL)
suite.NotEmpty(attachmentReply.PreviewURL)
Expand Down
4 changes: 2 additions & 2 deletions internal/api/client/media/mediaupdate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ func (suite *MediaUpdateTestSuite) TestUpdateImage() {
Original: apimodel.MediaDimensions{Width: 800, Height: 450, FrameRate: "", Duration: 0, Bitrate: 0, Size: "800x450", Aspect: 1.7777778},
Small: apimodel.MediaDimensions{Width: 256, Height: 144, FrameRate: "", Duration: 0, Bitrate: 0, Size: "256x144", Aspect: 1.7777778},
Focus: &apimodel.MediaFocus{X: -0.1, Y: 0.3},
}, attachmentReply.Meta)
suite.Equal(toUpdate.Blurhash, attachmentReply.Blurhash)
}, *attachmentReply.Meta)
suite.Equal(toUpdate.Blurhash, *attachmentReply.Blurhash)
suite.Equal(toUpdate.ID, attachmentReply.ID)
suite.Equal(toUpdate.URL, *attachmentReply.URL)
suite.NotEmpty(toUpdate.Thumbnail.URL, attachmentReply.PreviewURL)
Expand Down
8 changes: 4 additions & 4 deletions internal/api/model/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ type Attachment struct {
URL *string `json:"url"`
// A shorter URL for the attachment.
// In our case, we just give the URL again since we don't create smaller URLs.
TextURL string `json:"text_url"`
TextURL *string `json:"text_url"`
// The location of a scaled-down preview of the attachment.
// example: https://example.org/fileserver/some_id/attachments/some_id/small/attachment.jpeg
PreviewURL string `json:"preview_url"`
PreviewURL *string `json:"preview_url"`
// The location of the full-size original attachment on the remote server.
// Only defined for instances other than our own.
// example: https://some-other-server.org/attachments/original/ahhhhh.jpeg
Expand All @@ -83,13 +83,13 @@ type Attachment struct {
// example: https://some-other-server.org/attachments/small/ahhhhh.jpeg
PreviewRemoteURL *string `json:"preview_remote_url"`
// Metadata for this attachment.
Meta MediaMeta `json:"meta,omitempty"`
Meta *MediaMeta `json:"meta"`
// Alt text that describes what is in the media attachment.
// example: This is a picture of a kitten.
Description *string `json:"description"`
// A hash computed by the BlurHash algorithm, for generating colorful preview thumbnails when media has not been downloaded yet.
// See https://github.com/woltapp/blurhash
Blurhash string `json:"blurhash,omitempty"`
Blurhash *string `json:"blurhash"`
}

// MediaMeta models media metadata.
Expand Down
2 changes: 1 addition & 1 deletion internal/cleaner/media.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ func (m *Media) isOrphaned(ctx context.Context, path string) (bool, error) {

case media.TypeEmoji:
// Generate static URL for this emoji to lookup.
staticURL := uris.GenerateURIForAttachment(
staticURL := uris.URIForAttachment(
pathParts[1], // instance account ID
string(media.TypeEmoji),
string(media.SizeStatic),
Expand Down
10 changes: 5 additions & 5 deletions internal/cleaner/media_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ func (suite *MediaTestSuite) TestUncacheRemote() {
after := time.Now().Add(-24 * time.Hour)
totalUncached, err := suite.cleaner.Media().UncacheRemote(ctx, after)
suite.NoError(err)
suite.Equal(2, totalUncached)
suite.Equal(3, totalUncached)

uncachedAttachment, err := suite.db.GetAttachmentByID(ctx, testStatusAttachment.ID)
suite.NoError(err)
Expand All @@ -327,7 +327,7 @@ func (suite *MediaTestSuite) TestUncacheRemoteDry() {
after := time.Now().Add(-24 * time.Hour)
totalUncached, err := suite.cleaner.Media().UncacheRemote(gtscontext.SetDryRun(ctx), after)
suite.NoError(err)
suite.Equal(2, totalUncached)
suite.Equal(3, totalUncached)

uncachedAttachment, err := suite.db.GetAttachmentByID(ctx, testStatusAttachment.ID)
suite.NoError(err)
Expand All @@ -344,7 +344,7 @@ func (suite *MediaTestSuite) TestUncacheRemoteTwice() {

totalUncached, err := suite.cleaner.Media().UncacheRemote(ctx, after)
suite.NoError(err)
suite.Equal(2, totalUncached)
suite.Equal(3, totalUncached)

// final uncache should uncache nothing, since the first uncache already happened
totalUncachedAgain, err := suite.cleaner.Media().UncacheRemote(ctx, after)
Expand All @@ -360,7 +360,7 @@ func (suite *MediaTestSuite) TestUncacheAndRecache() {
after := time.Now().Add(-24 * time.Hour)
totalUncached, err := suite.cleaner.Media().UncacheRemote(ctx, after)
suite.NoError(err)
suite.Equal(2, totalUncached)
suite.Equal(3, totalUncached)

// media should no longer be stored
_, err = suite.storage.Get(ctx, testStatusAttachment.File.Path)
Expand Down Expand Up @@ -424,5 +424,5 @@ func (suite *MediaTestSuite) TestUncacheOneNonExistent() {
after := time.Now().Add(-24 * time.Hour)
totalUncached, err := suite.cleaner.Media().UncacheRemote(ctx, after)
suite.NoError(err)
suite.Equal(2, totalUncached)
suite.Equal(3, totalUncached)
}
2 changes: 1 addition & 1 deletion internal/db/bundb/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (suite *BasicTestSuite) TestGetAllStatuses() {
s := []*gtsmodel.Status{}
err := suite.db.GetAll(context.Background(), &s)
suite.NoError(err)
suite.Len(s, 20)
suite.Len(s, 21)
}

func (suite *BasicTestSuite) TestGetAllNotNull() {
Expand Down
4 changes: 2 additions & 2 deletions internal/db/bundb/media_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ func (suite *MediaTestSuite) TestGetAttachmentByID() {
func (suite *MediaTestSuite) TestGetOlder() {
attachments, err := suite.db.GetCachedAttachmentsOlderThan(context.Background(), time.Now(), 20)
suite.NoError(err)
suite.Len(attachments, 2)
suite.Len(attachments, 3)
}

func (suite *MediaTestSuite) TestGetCachedAttachmentsOlderThan() {
ctx := context.Background()

attachments, err := suite.db.GetCachedAttachmentsOlderThan(ctx, time.Now(), 20)
suite.NoError(err)
suite.Len(attachments, 2)
suite.Len(attachments, 3)
}

func TestMediaTestSuite(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions internal/db/bundb/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ func (s *statusDB) PutStatus(ctx context.Context, status *gtsmodel.Status) error
if _, err := tx.
NewUpdate().
Model(a).
Column("status_id", "updated_at").
Where("? = ?", bun.Ident("media_attachment.id"), a.ID).
Exec(ctx); err != nil {
if !errors.Is(err, db.ErrAlreadyExists) {
Expand Down
14 changes: 2 additions & 12 deletions internal/federation/dereferencing/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -622,21 +622,16 @@ func (d *Dereferencer) fetchRemoteAccountAvatar(ctx context.Context, tsport tran
processing, ok := d.derefAvatars[latestAcc.AvatarRemoteURL]

if !ok {
var err error

// Set the media data function to dereference avatar from URI.
data := func(ctx context.Context) (io.ReadCloser, int64, error) {
return tsport.DereferenceMedia(ctx, avatarURI)
}

// Create new media processing request from the media manager instance.
processing, err = d.mediaManager.PreProcessMedia(ctx, data, latestAcc.ID, &media.AdditionalMediaInfo{
processing = d.mediaManager.PreProcessMedia(data, latestAcc.ID, &media.AdditionalMediaInfo{
Avatar: func() *bool { v := true; return &v }(),
RemoteURL: &latestAcc.AvatarRemoteURL,
})
if err != nil {
return gtserror.Newf("error preprocessing media for attachment %s: %w", latestAcc.AvatarRemoteURL, err)
}

// Store media in map to mark as processing.
d.derefAvatars[latestAcc.AvatarRemoteURL] = processing
Expand Down Expand Up @@ -713,21 +708,16 @@ func (d *Dereferencer) fetchRemoteAccountHeader(ctx context.Context, tsport tran
processing, ok := d.derefHeaders[latestAcc.HeaderRemoteURL]

if !ok {
var err error

// Set the media data function to dereference avatar from URI.
data := func(ctx context.Context) (io.ReadCloser, int64, error) {
return tsport.DereferenceMedia(ctx, headerURI)
}

// Create new media processing request from the media manager instance.
processing, err = d.mediaManager.PreProcessMedia(ctx, data, latestAcc.ID, &media.AdditionalMediaInfo{
processing = d.mediaManager.PreProcessMedia(data, latestAcc.ID, &media.AdditionalMediaInfo{
Header: func() *bool { v := true; return &v }(),
RemoteURL: &latestAcc.HeaderRemoteURL,
})
if err != nil {
return gtserror.Newf("error preprocessing media for attachment %s: %w", latestAcc.HeaderRemoteURL, err)
}

// Store media in map to mark as processing.
d.derefHeaders[latestAcc.HeaderRemoteURL] = processing
Expand Down
54 changes: 0 additions & 54 deletions internal/federation/dereferencing/media.go

This file was deleted.

0 comments on commit ba9d6b4

Please sign in to comment.