summaryrefslogtreecommitdiff
path: root/internal/media
diff options
context:
space:
mode:
Diffstat (limited to 'internal/media')
-rw-r--r--internal/media/ffmpeg/pool.go31
-rw-r--r--internal/media/manager.go171
-rw-r--r--internal/media/manager_test.go8
-rw-r--r--internal/media/processingemoji.go57
-rw-r--r--internal/media/processingmedia.go36
5 files changed, 124 insertions, 179 deletions
diff --git a/internal/media/ffmpeg/pool.go b/internal/media/ffmpeg/pool.go
index 9f6446be3..e63b10e69 100644
--- a/internal/media/ffmpeg/pool.go
+++ b/internal/media/ffmpeg/pool.go
@@ -34,14 +34,33 @@ type wasmInstancePool struct {
}
func (p *wasmInstancePool) Init(ctx context.Context, sz int) error {
+ // Initialize for first time
+ // to preload module into the
+ // wazero compilation cache.
+ inst, err := p.inst.New(ctx)
+ if err != nil {
+ return err
+ }
+
+ // Clamp to 1.
+ if sz <= 0 {
+ sz = 1
+ }
+
+ // Allocate new pool instance channel.
p.pool = make(chan *wasm.Instance, sz)
- for i := 0; i < sz; i++ {
- inst, err := p.inst.New(ctx)
- if err != nil {
- return err
- }
- p.pool <- inst
+
+ // Store only one
+ // open instance
+ // at init time.
+ p.pool <- inst
+
+ // Fill reminaing with closed
+ // instances for later opening.
+ for i := 0; i < sz-1; i++ {
+ p.pool <- new(wasm.Instance)
}
+
return nil
}
diff --git a/internal/media/manager.go b/internal/media/manager.go
index 82b066edc..13bcebe79 100644
--- a/internal/media/manager.go
+++ b/internal/media/manager.go
@@ -102,74 +102,19 @@ func (m *Manager) CreateMedia(
) {
now := time.Now()
- // Generate new ID.
- id := id.NewULID()
-
- // Placeholder URL for attachment.
- url := uris.URIForAttachment(
- accountID,
- string(TypeAttachment),
- string(SizeOriginal),
- id,
- "unknown",
- )
-
- // Placeholder storage path for attachment.
- path := uris.StoragePathForAttachment(
- accountID,
- string(TypeAttachment),
- string(SizeOriginal),
- id,
- "unknown",
- )
-
- // Calculate attachment thumbnail file path
- thumbPath := uris.StoragePathForAttachment(
- accountID,
- string(TypeAttachment),
- string(SizeSmall),
- id,
-
- // Always encode attachment
- // thumbnails as jpeg.
- "jpeg",
- )
-
- // Calculate attachment thumbnail URL.
- thumbURL := uris.URIForAttachment(
- accountID,
- string(TypeAttachment),
- string(SizeSmall),
- id,
-
- // Always encode attachment
- // thumbnails as jpeg.
- "jpeg",
- )
-
// Populate initial fields on the new media,
// leaving out fields with values we don't know
// yet. These will be overwritten as we go.
attachment := &gtsmodel.MediaAttachment{
- ID: id,
- CreatedAt: now,
- UpdatedAt: now,
- URL: url,
- Type: gtsmodel.FileTypeUnknown,
+ ID: id.NewULID(),
AccountID: accountID,
+ Type: gtsmodel.FileTypeUnknown,
Processing: gtsmodel.ProcessingStatusReceived,
- File: gtsmodel.File{
- ContentType: "application/octet-stream",
- Path: path,
- },
- Thumbnail: gtsmodel.Thumbnail{
- ContentType: "image/jpeg",
- Path: thumbPath,
- URL: thumbURL,
- },
- Avatar: util.Ptr(false),
- Header: util.Ptr(false),
- Cached: util.Ptr(false),
+ Avatar: util.Ptr(false),
+ Header: util.Ptr(false),
+ Cached: util.Ptr(false),
+ CreatedAt: now,
+ UpdatedAt: now,
}
// Check if we were provided additional info
@@ -252,56 +197,23 @@ func (m *Manager) CreateEmoji(
// Generate new ID.
id := id.NewULID()
- // Fetch the local instance account for emoji path generation.
- instanceAcc, err := m.state.DB.GetInstanceAccount(ctx, "")
- if err != nil {
- return nil, gtserror.Newf("error fetching instance account: %w", err)
- }
-
if domain == "" && info.URI == nil {
// Generate URI for local emoji.
uri := uris.URIForEmoji(id)
info.URI = &uri
}
- // Generate static URL for attachment.
- staticURL := uris.URIForAttachment(
- instanceAcc.ID,
- string(TypeEmoji),
- string(SizeStatic),
- id,
-
- // All static emojis
- // are encoded as png.
- "png",
- )
-
- // Generate static image path for attachment.
- staticPath := uris.StoragePathForAttachment(
- instanceAcc.ID,
- string(TypeEmoji),
- string(SizeStatic),
- id,
-
- // All static emojis
- // are encoded as png.
- "png",
- )
-
// Populate initial fields on the new emoji,
// leaving out fields with values we don't know
// yet. These will be overwritten as we go.
emoji := &gtsmodel.Emoji{
- ID: id,
- Shortcode: shortcode,
- Domain: domain,
- ImageStaticURL: staticURL,
- ImageStaticPath: staticPath,
- ImageStaticContentType: "image/png",
- Disabled: util.Ptr(false),
- VisibleInPicker: util.Ptr(true),
- CreatedAt: now,
- UpdatedAt: now,
+ ID: id,
+ Shortcode: shortcode,
+ Domain: domain,
+ Disabled: util.Ptr(false),
+ VisibleInPicker: util.Ptr(true),
+ CreatedAt: now,
+ UpdatedAt: now,
}
// Finally, create new emoji.
@@ -327,12 +239,6 @@ func (m *Manager) RefreshEmoji(
*ProcessingEmoji,
error,
) {
- // Fetch the local instance account for emoji path generation.
- instanceAcc, err := m.state.DB.GetInstanceAccount(ctx, "")
- if err != nil {
- return nil, gtserror.Newf("error fetching instance account: %w", err)
- }
-
// Create references to old emoji image
// paths before they get updated with new
// path ID. These are required for later
@@ -380,38 +286,6 @@ func (m *Manager) RefreshEmoji(
return rct, nil
}
- // Use a new ID to create a new path
- // for the new images, to get around
- // needing to do cache invalidation.
- newPathID, err := id.NewRandomULID()
- if err != nil {
- return nil, gtserror.Newf("error generating newPathID for emoji refresh: %s", err)
- }
-
- // Generate new static URL for emoji.
- emoji.ImageStaticURL = uris.URIForAttachment(
- instanceAcc.ID,
- string(TypeEmoji),
- string(SizeStatic),
- newPathID,
-
- // All static emojis
- // are encoded as png.
- "png",
- )
-
- // Generate new static image storage path for emoji.
- emoji.ImageStaticPath = uris.StoragePathForAttachment(
- instanceAcc.ID,
- string(TypeEmoji),
- string(SizeStatic),
- newPathID,
-
- // All static emojis
- // are encoded as png.
- "png",
- )
-
// Finally, create new emoji in database.
processingEmoji, err := m.createEmoji(ctx,
func(ctx context.Context, emoji *gtsmodel.Emoji) error {
@@ -425,8 +299,8 @@ func (m *Manager) RefreshEmoji(
return nil, err
}
- // Set the refreshed path ID used.
- processingEmoji.newPathID = newPathID
+ // Generate a new path ID to use instead.
+ processingEmoji.newPathID = id.NewULID()
return processingEmoji, nil
}
@@ -441,6 +315,12 @@ func (m *Manager) createEmoji(
*ProcessingEmoji,
error,
) {
+ // Fetch the local instance account for emoji path generation.
+ instanceAcc, err := m.state.DB.GetInstanceAccount(ctx, "")
+ if err != nil {
+ return nil, gtserror.Newf("error fetching instance account: %w", err)
+ }
+
// Check if we have additional info to add to the emoji,
// and overwrite some of the emoji fields if so.
if info.URI != nil {
@@ -475,9 +355,10 @@ func (m *Manager) createEmoji(
// Return wrapped emoji for later processing.
processingEmoji := &ProcessingEmoji{
- emoji: emoji,
- dataFn: data,
- mgr: m,
+ instAccID: instanceAcc.ID,
+ emoji: emoji,
+ dataFn: data,
+ mgr: m,
}
return processingEmoji, nil
diff --git a/internal/media/manager_test.go b/internal/media/manager_test.go
index 24e0ddd1e..c908b2994 100644
--- a/internal/media/manager_test.go
+++ b/internal/media/manager_test.go
@@ -358,11 +358,10 @@ func (suite *ManagerTestSuite) TestPDFProcess() {
suite.Equal(processing.ID(), attachment.ID)
suite.Equal(accountID, attachment.AccountID)
- // file meta should be correctly derived from the image
suite.Zero(attachment.FileMeta)
- suite.Equal("application/octet-stream", attachment.File.ContentType)
- suite.Equal("image/jpeg", attachment.Thumbnail.ContentType)
- suite.Empty(attachment.Blurhash)
+ suite.Zero(attachment.File.ContentType)
+ suite.Zero(attachment.Thumbnail.ContentType)
+ suite.Zero(attachment.Blurhash)
// now make sure the attachment is in the database
dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID)
@@ -376,7 +375,6 @@ func (suite *ManagerTestSuite) TestPDFProcess() {
stored, err := suite.storage.Has(ctx, attachment.File.Path)
suite.NoError(err)
suite.False(stored)
-
stored, err = suite.storage.Has(ctx, attachment.Thumbnail.Path)
suite.NoError(err)
suite.False(stored)
diff --git a/internal/media/processingemoji.go b/internal/media/processingemoji.go
index 996a3aa03..f4265759b 100644
--- a/internal/media/processingemoji.go
+++ b/internal/media/processingemoji.go
@@ -26,7 +26,6 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/log"
- "github.com/superseriousbusiness/gotosocial/internal/regexes"
"github.com/superseriousbusiness/gotosocial/internal/storage"
"github.com/superseriousbusiness/gotosocial/internal/uris"
"github.com/superseriousbusiness/gotosocial/internal/util"
@@ -36,6 +35,7 @@ import (
// various functions for retrieving data from the process.
type ProcessingEmoji struct {
emoji *gtsmodel.Emoji // processing emoji details
+ instAccID string // instance account ID
newPathID string // new emoji path ID to use when being refreshed
dataFn DataFunc // load-data function, returns media stream
done bool // done is set when process finishes with non ctx canceled type error
@@ -191,21 +191,24 @@ func (p *ProcessingEmoji) store(ctx context.Context) error {
pathID = p.emoji.ID
}
- // Determine instance account ID from generated image static path.
- instanceAccID, ok := getInstanceAccountID(p.emoji.ImageStaticPath)
- if !ok {
- return gtserror.Newf("invalid emoji static path; no instance account id: %s", p.emoji.ImageStaticPath)
- }
-
- // Calculate final media attachment file path.
+ // Calculate final emoji media file path.
p.emoji.ImagePath = uris.StoragePathForAttachment(
- instanceAccID,
+ p.instAccID,
string(TypeEmoji),
string(SizeOriginal),
pathID,
ext,
)
+ // Calculate final emoji static media file path.
+ p.emoji.ImageStaticPath = uris.StoragePathForAttachment(
+ p.instAccID,
+ string(TypeEmoji),
+ string(SizeStatic),
+ pathID,
+ "png",
+ )
+
// Copy temporary file into storage at path.
filesz, err := p.mgr.state.Storage.PutFile(ctx,
p.emoji.ImagePath,
@@ -228,19 +231,31 @@ func (p *ProcessingEmoji) store(ctx context.Context) error {
p.emoji.ImageFileSize = int(filesz)
p.emoji.ImageStaticFileSize = int(staticsz)
- // Fill in remaining emoji data now it's stored.
+ // Generate an emoji media static URL.
p.emoji.ImageURL = uris.URIForAttachment(
- instanceAccID,
+ p.instAccID,
string(TypeEmoji),
string(SizeOriginal),
pathID,
ext,
)
+ // Generate an emoji image static URL.
+ p.emoji.ImageStaticURL = uris.URIForAttachment(
+ p.instAccID,
+ string(TypeEmoji),
+ string(SizeStatic),
+ pathID,
+ "png",
+ )
+
// Get mimetype for the file container
// type, falling back to generic data.
p.emoji.ImageContentType = getMimeType(ext)
+ // Set the known emoji static content type.
+ p.emoji.ImageStaticContentType = "image/png"
+
// We can now consider this cached.
p.emoji.Cached = util.Ptr(true)
@@ -268,16 +283,16 @@ func (p *ProcessingEmoji) cleanup(ctx context.Context) {
}
}
+ // Unset processor-calculated fields.
+ p.emoji.ImageStaticContentType = ""
+ p.emoji.ImageStaticFileSize = 0
+ p.emoji.ImageStaticPath = ""
+ p.emoji.ImageStaticURL = ""
+ p.emoji.ImageContentType = ""
+ p.emoji.ImageFileSize = 0
+ p.emoji.ImagePath = ""
+ p.emoji.ImageURL = ""
+
// Ensure marked as not cached.
p.emoji.Cached = util.Ptr(false)
}
-
-// getInstanceAccountID determines the instance account ID from
-// emoji static image storage path. returns false on failure.
-func getInstanceAccountID(staticPath string) (string, bool) {
- matches := regexes.FilePath.FindStringSubmatch(staticPath)
- if len(matches) < 2 {
- return "", false
- }
- return matches[1], true
-}
diff --git a/internal/media/processingmedia.go b/internal/media/processingmedia.go
index e5af46a2f..393f7d715 100644
--- a/internal/media/processingmedia.go
+++ b/internal/media/processingmedia.go
@@ -248,6 +248,15 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
return gtserror.Newf("error generating thumb blurhash: %w", err)
}
}
+
+ // Calculate final media attachment thumbnail path.
+ p.media.Thumbnail.Path = uris.StoragePathForAttachment(
+ p.media.AccountID,
+ string(TypeAttachment),
+ string(SizeSmall),
+ p.media.ID,
+ "jpeg",
+ )
}
// Calculate final media attachment file path.
@@ -285,8 +294,7 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
p.media.Thumbnail.FileSize = int(thumbsz)
}
- // Fill in correct attachment
- // data now we've parsed it.
+ // Generate a media attachment URL.
p.media.URL = uris.URIForAttachment(
p.media.AccountID,
string(TypeAttachment),
@@ -295,10 +303,22 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
ext,
)
+ // Generate a media attachment thumbnail URL.
+ p.media.Thumbnail.URL = uris.URIForAttachment(
+ p.media.AccountID,
+ string(TypeAttachment),
+ string(SizeSmall),
+ p.media.ID,
+ "jpeg",
+ )
+
// Get mimetype for the file container
// type, falling back to generic data.
p.media.File.ContentType = getMimeType(ext)
+ // Set the known thumbnail content type.
+ p.media.Thumbnail.ContentType = "image/jpeg"
+
// We can now consider this cached.
p.media.Cached = util.Ptr(true)
@@ -329,6 +349,18 @@ func (p *ProcessingMedia) cleanup(ctx context.Context) {
}
}
+ // Unset all processor-calculated media fields.
+ p.media.FileMeta.Original = gtsmodel.Original{}
+ p.media.FileMeta.Small = gtsmodel.Small{}
+ p.media.File.ContentType = ""
+ p.media.File.FileSize = 0
+ p.media.File.Path = ""
+ p.media.Thumbnail.FileSize = 0
+ p.media.Thumbnail.ContentType = ""
+ p.media.Thumbnail.Path = ""
+ p.media.Thumbnail.URL = ""
+ p.media.URL = ""
+
// Also ensure marked as unknown and finished
// processing so gets inserted as placeholder URL.
p.media.Processing = gtsmodel.ProcessingStatusProcessed