diff options
Diffstat (limited to 'internal/federation')
| -rw-r--r-- | internal/federation/dereferencing/account.go | 14 | ||||
| -rw-r--r-- | internal/federation/dereferencing/media.go | 54 | ||||
| -rw-r--r-- | internal/federation/dereferencing/media_test.go | 161 | ||||
| -rw-r--r-- | internal/federation/dereferencing/status.go | 31 | 
4 files changed, 21 insertions, 239 deletions
| diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index 562062c8d..d551c3f0b 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -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 @@ -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 diff --git a/internal/federation/dereferencing/media.go b/internal/federation/dereferencing/media.go deleted file mode 100644 index 15aa4bb08..000000000 --- a/internal/federation/dereferencing/media.go +++ /dev/null @@ -1,54 +0,0 @@ -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program.  If not, see <http://www.gnu.org/licenses/>. - -package dereferencing - -import ( -	"context" -	"fmt" -	"io" -	"net/url" - -	"github.com/superseriousbusiness/gotosocial/internal/media" -) - -func (d *Dereferencer) GetRemoteMedia(ctx context.Context, requestingUsername string, accountID string, remoteURL string, ai *media.AdditionalMediaInfo) (*media.ProcessingMedia, error) { -	if accountID == "" { -		return nil, fmt.Errorf("GetRemoteMedia: account ID was empty") -	} - -	t, err := d.transportController.NewTransportForUsername(ctx, requestingUsername) -	if err != nil { -		return nil, fmt.Errorf("GetRemoteMedia: error creating transport: %s", err) -	} - -	derefURI, err := url.Parse(remoteURL) -	if err != nil { -		return nil, fmt.Errorf("GetRemoteMedia: error parsing url: %s", err) -	} - -	dataFunc := func(innerCtx context.Context) (io.ReadCloser, int64, error) { -		return t.DereferenceMedia(innerCtx, derefURI) -	} - -	processingMedia, err := d.mediaManager.ProcessMedia(ctx, dataFunc, accountID, ai) -	if err != nil { -		return nil, fmt.Errorf("GetRemoteMedia: error processing attachment: %s", err) -	} - -	return processingMedia, nil -} diff --git a/internal/federation/dereferencing/media_test.go b/internal/federation/dereferencing/media_test.go deleted file mode 100644 index 0de3f294f..000000000 --- a/internal/federation/dereferencing/media_test.go +++ /dev/null @@ -1,161 +0,0 @@ -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program.  If not, see <http://www.gnu.org/licenses/>. - -package dereferencing_test - -import ( -	"context" -	"testing" -	"time" - -	"github.com/stretchr/testify/suite" -	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" -	"github.com/superseriousbusiness/gotosocial/internal/media" -) - -type AttachmentTestSuite struct { -	DereferencerStandardTestSuite -} - -func (suite *AttachmentTestSuite) TestDereferenceAttachmentBlocking() { -	ctx := context.Background() - -	fetchingAccount := suite.testAccounts["local_account_1"] - -	attachmentOwner := "01FENS9F666SEQ6TYQWEEY78GM" -	attachmentStatus := "01FENS9NTTVNEX1YZV7GB63MT8" -	attachmentContentType := "image/jpeg" -	attachmentURL := "https://s3-us-west-2.amazonaws.com/plushcity/media_attachments/files/106/867/380/219/163/828/original/88e8758c5f011439.jpg" -	attachmentDescription := "It's a cute plushie." -	attachmentBlurhash := "LtQ9yKi__4%g%MRjWCt7%hozM_az" - -	media, err := suite.dereferencer.GetRemoteMedia(ctx, fetchingAccount.Username, attachmentOwner, attachmentURL, &media.AdditionalMediaInfo{ -		StatusID:    &attachmentStatus, -		RemoteURL:   &attachmentURL, -		Description: &attachmentDescription, -		Blurhash:    &attachmentBlurhash, -	}) -	suite.NoError(err) - -	// make a blocking call to load the attachment from the in-process media -	attachment, err := media.LoadAttachment(ctx) -	suite.NoError(err) - -	suite.NotNil(attachment) - -	suite.Equal(attachmentOwner, attachment.AccountID) -	suite.Equal(attachmentStatus, attachment.StatusID) -	suite.Equal(attachmentURL, attachment.RemoteURL) -	suite.NotEmpty(attachment.URL) -	suite.NotEmpty(attachment.Blurhash) -	suite.NotEmpty(attachment.ID) -	suite.NotEmpty(attachment.CreatedAt) -	suite.NotEmpty(attachment.UpdatedAt) -	suite.EqualValues(1.3365462, attachment.FileMeta.Original.Aspect) -	suite.Equal(2071680, attachment.FileMeta.Original.Size) -	suite.Equal(1245, attachment.FileMeta.Original.Height) -	suite.Equal(1664, attachment.FileMeta.Original.Width) -	suite.Equal(attachmentBlurhash, attachment.Blurhash) -	suite.Equal(gtsmodel.ProcessingStatusProcessed, attachment.Processing) -	suite.NotEmpty(attachment.File.Path) -	suite.Equal(attachmentContentType, attachment.File.ContentType) -	suite.Equal(attachmentDescription, attachment.Description) - -	suite.NotEmpty(attachment.Thumbnail.Path) -	suite.NotEmpty(attachment.Type) - -	// attachment should also now be in the database -	dbAttachment, err := suite.db.GetAttachmentByID(context.Background(), attachment.ID) -	suite.NoError(err) -	suite.NotNil(dbAttachment) - -	suite.Equal(attachmentOwner, dbAttachment.AccountID) -	suite.Equal(attachmentStatus, dbAttachment.StatusID) -	suite.Equal(attachmentURL, dbAttachment.RemoteURL) -	suite.NotEmpty(dbAttachment.URL) -	suite.NotEmpty(dbAttachment.Blurhash) -	suite.NotEmpty(dbAttachment.ID) -	suite.NotEmpty(dbAttachment.CreatedAt) -	suite.NotEmpty(dbAttachment.UpdatedAt) -	suite.EqualValues(1.3365462, dbAttachment.FileMeta.Original.Aspect) -	suite.Equal(2071680, dbAttachment.FileMeta.Original.Size) -	suite.Equal(1245, dbAttachment.FileMeta.Original.Height) -	suite.Equal(1664, dbAttachment.FileMeta.Original.Width) -	suite.Equal(attachmentBlurhash, dbAttachment.Blurhash) -	suite.Equal(gtsmodel.ProcessingStatusProcessed, dbAttachment.Processing) -	suite.NotEmpty(dbAttachment.File.Path) -	suite.Equal(attachmentContentType, dbAttachment.File.ContentType) -	suite.Equal(attachmentDescription, dbAttachment.Description) - -	suite.NotEmpty(dbAttachment.Thumbnail.Path) -	suite.NotEmpty(dbAttachment.Type) -} - -func (suite *AttachmentTestSuite) TestDereferenceAttachmentAsync() { -	ctx := context.Background() - -	fetchingAccount := suite.testAccounts["local_account_1"] - -	attachmentOwner := "01FENS9F666SEQ6TYQWEEY78GM" -	attachmentStatus := "01FENS9NTTVNEX1YZV7GB63MT8" -	attachmentContentType := "image/jpeg" -	attachmentURL := "https://s3-us-west-2.amazonaws.com/plushcity/media_attachments/files/106/867/380/219/163/828/original/88e8758c5f011439.jpg" -	attachmentDescription := "It's a cute plushie." -	attachmentBlurhash := "LtQ9yKi__4%g%MRjWCt7%hozM_az" - -	processingMedia, err := suite.dereferencer.GetRemoteMedia(ctx, fetchingAccount.Username, attachmentOwner, attachmentURL, &media.AdditionalMediaInfo{ -		StatusID:    &attachmentStatus, -		RemoteURL:   &attachmentURL, -		Description: &attachmentDescription, -		Blurhash:    &attachmentBlurhash, -	}) -	suite.NoError(err) -	attachmentID := processingMedia.AttachmentID() - -	time.Sleep(time.Second * 3) - -	// now get the attachment from the database -	attachment, err := suite.db.GetAttachmentByID(ctx, attachmentID) -	suite.NoError(err) - -	suite.NotNil(attachment) - -	suite.Equal(attachmentOwner, attachment.AccountID) -	suite.Equal(attachmentStatus, attachment.StatusID) -	suite.Equal(attachmentURL, attachment.RemoteURL) -	suite.NotEmpty(attachment.URL) -	suite.NotEmpty(attachment.Blurhash) -	suite.NotEmpty(attachment.ID) -	suite.NotEmpty(attachment.CreatedAt) -	suite.NotEmpty(attachment.UpdatedAt) -	suite.EqualValues(1.3365462, attachment.FileMeta.Original.Aspect) -	suite.Equal(2071680, attachment.FileMeta.Original.Size) -	suite.Equal(1245, attachment.FileMeta.Original.Height) -	suite.Equal(1664, attachment.FileMeta.Original.Width) -	suite.Equal(attachmentBlurhash, attachment.Blurhash) -	suite.Equal(gtsmodel.ProcessingStatusProcessed, attachment.Processing) -	suite.NotEmpty(attachment.File.Path) -	suite.Equal(attachmentContentType, attachment.File.ContentType) -	suite.Equal(attachmentDescription, attachment.Description) - -	suite.NotEmpty(attachment.Thumbnail.Path) -	suite.NotEmpty(attachment.Type) -} - -func TestAttachmentTestSuite(t *testing.T) { -	suite.Run(t, new(AttachmentTestSuite)) -} diff --git a/internal/federation/dereferencing/status.go b/internal/federation/dereferencing/status.go index 1f09dedc0..032238bd5 100644 --- a/internal/federation/dereferencing/status.go +++ b/internal/federation/dereferencing/status.go @@ -789,7 +789,7 @@ func (d *Dereferencer) fetchStatusAttachments(ctx context.Context, tsport transp  	for i := range status.Attachments {  		attachment := status.Attachments[i] -		// Look for existing media attachment with remoet URL first. +		// Look for existing media attachment with remote URL first.  		existing, ok := existing.GetAttachmentByRemoteURL(attachment.RemoteURL)  		if ok && existing.ID != "" && *existing.Cached {  			status.Attachments[i] = existing @@ -804,25 +804,33 @@ func (d *Dereferencer) fetchStatusAttachments(ctx context.Context, tsport transp  			continue  		} -		// Start pre-processing remote media at remote URL. -		processing, err := d.mediaManager.PreProcessMedia(ctx, func(ctx context.Context) (io.ReadCloser, int64, error) { +		data := func(ctx context.Context) (io.ReadCloser, int64, error) {  			return tsport.DereferenceMedia(ctx, remoteURL) -		}, status.AccountID, &media.AdditionalMediaInfo{ +		} + +		ai := &media.AdditionalMediaInfo{  			StatusID:    &status.ID,  			RemoteURL:   &attachment.RemoteURL,  			Description: &attachment.Description,  			Blurhash:    &attachment.Blurhash, -		}) -		if err != nil { -			log.Errorf(ctx, "error processing attachment: %v", err) -			continue  		} +		// Start pre-processing remote media at remote URL. +		processing := d.mediaManager.PreProcessMedia(data, status.AccountID, ai) +  		// Force attachment loading *right now*.  		attachment, err = processing.LoadAttachment(ctx)  		if err != nil { -			log.Errorf(ctx, "error loading attachment: %v", err) -			continue +			if attachment == nil { +				// Totally failed to load; +				// bail on this attachment. +				log.Errorf(ctx, "error loading attachment: %v", err) +				continue +			} + +			// Partially loaded. Keep as +			// placeholder and try again later. +			log.Warnf(ctx, "partially loaded attachment: %v", err)  		}  		// Set the *new* attachment and ID. @@ -832,8 +840,7 @@ func (d *Dereferencer) fetchStatusAttachments(ctx context.Context, tsport transp  	for i := 0; i < len(status.AttachmentIDs); {  		if status.AttachmentIDs[i] == "" { -			// This is a failed attachment population, this may -			// be due to us not currently supporting a media type. +			// Remove totally failed attachment populations  			copy(status.Attachments[i:], status.Attachments[i+1:])  			copy(status.AttachmentIDs[i:], status.AttachmentIDs[i+1:])  			status.Attachments = status.Attachments[:len(status.Attachments)-1] | 
