mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-10-31 22:40:01 +00:00
[feature] Allow webp emoji uploads / derefs (#2484)
This commit is contained in:
parent
d5e3996a18
commit
72d0f46b0b
6 changed files with 66 additions and 8 deletions
|
@ -45,6 +45,7 @@
|
||||||
var SupportedEmojiMIMETypes = []string{
|
var SupportedEmojiMIMETypes = []string{
|
||||||
mimeImageGif,
|
mimeImageGif,
|
||||||
mimeImagePng,
|
mimeImagePng,
|
||||||
|
mimeImageWebp,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
|
|
|
@ -303,6 +303,67 @@ func (suite *ManagerTestSuite) TestEmojiProcessBlockingNoFileSizeGiven() {
|
||||||
suite.Equal(processedStaticBytesExpected, processedStaticBytes)
|
suite.Equal(processedStaticBytesExpected, processedStaticBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *ManagerTestSuite) TestEmojiWebpProcess() {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
data := func(_ context.Context) (io.ReadCloser, int64, error) {
|
||||||
|
// load bytes from a test image
|
||||||
|
b, err := os.ReadFile("./test/nb-flag-original.webp")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return io.NopCloser(bytes.NewBuffer(b)), int64(len(b)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
emojiID := "01GDQ9G782X42BAMFASKP64343"
|
||||||
|
emojiURI := "http://localhost:8080/emoji/01GDQ9G782X42BAMFASKP64343"
|
||||||
|
|
||||||
|
processingEmoji, err := suite.manager.ProcessEmoji(ctx, data, "nb-flag", emojiID, emojiURI, nil, false)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
// do a blocking call to fetch the emoji
|
||||||
|
emoji, err := processingEmoji.LoadEmoji(ctx)
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotNil(emoji)
|
||||||
|
|
||||||
|
// make sure it's got the stuff set on it that we expect
|
||||||
|
suite.Equal(emojiID, emoji.ID)
|
||||||
|
|
||||||
|
// file meta should be correctly derived from the image
|
||||||
|
suite.Equal("image/webp", emoji.ImageContentType)
|
||||||
|
suite.Equal("image/png", emoji.ImageStaticContentType)
|
||||||
|
suite.Equal(294, emoji.ImageFileSize)
|
||||||
|
|
||||||
|
// now make sure the emoji is in the database
|
||||||
|
dbEmoji, err := suite.db.GetEmojiByID(ctx, emojiID)
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotNil(dbEmoji)
|
||||||
|
|
||||||
|
// make sure the processed emoji file is in storage
|
||||||
|
processedFullBytes, err := suite.storage.Get(ctx, emoji.ImagePath)
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotEmpty(processedFullBytes)
|
||||||
|
|
||||||
|
// load the processed bytes from our test folder, to compare
|
||||||
|
processedFullBytesExpected, err := os.ReadFile("./test/nb-flag-original.webp")
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotEmpty(processedFullBytesExpected)
|
||||||
|
|
||||||
|
// the bytes in storage should be what we expected
|
||||||
|
suite.Equal(processedFullBytesExpected, processedFullBytes)
|
||||||
|
|
||||||
|
// now do the same for the thumbnail and make sure it's what we expected
|
||||||
|
processedStaticBytes, err := suite.storage.Get(ctx, emoji.ImageStaticPath)
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotEmpty(processedStaticBytes)
|
||||||
|
|
||||||
|
processedStaticBytesExpected, err := os.ReadFile("./test/nb-flag-static.png")
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotEmpty(processedStaticBytesExpected)
|
||||||
|
|
||||||
|
suite.Equal(processedStaticBytesExpected, processedStaticBytes)
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *ManagerTestSuite) TestSimpleJpegProcessBlocking() {
|
func (suite *ManagerTestSuite) TestSimpleJpegProcessBlocking() {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"codeberg.org/gruf/go-bytesize"
|
"codeberg.org/gruf/go-bytesize"
|
||||||
"codeberg.org/gruf/go-errors/v2"
|
"codeberg.org/gruf/go-errors/v2"
|
||||||
|
@ -57,7 +58,6 @@ func (p *ProcessingEmoji) EmojiID() string {
|
||||||
func (p *ProcessingEmoji) LoadEmoji(ctx context.Context) (*gtsmodel.Emoji, error) {
|
func (p *ProcessingEmoji) LoadEmoji(ctx context.Context) (*gtsmodel.Emoji, error) {
|
||||||
// Attempt to load synchronously.
|
// Attempt to load synchronously.
|
||||||
emoji, done, err := p.load(ctx)
|
emoji, done, err := p.load(ctx)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// No issue, return media.
|
// No issue, return media.
|
||||||
return emoji, nil
|
return emoji, nil
|
||||||
|
@ -209,12 +209,8 @@ func (p *ProcessingEmoji) store(ctx context.Context) error {
|
||||||
return gtserror.Newf("error parsing file type: %w", err)
|
return gtserror.Newf("error parsing file type: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch info.Extension {
|
// Ensure supported emoji img type.
|
||||||
// only supported emoji types
|
if !slices.Contains(SupportedEmojiMIMETypes, info.MIME.Value) {
|
||||||
case "gif", "png":
|
|
||||||
|
|
||||||
// unhandled
|
|
||||||
default:
|
|
||||||
return gtserror.Newf("unsupported emoji filetype: %s", info.Extension)
|
return gtserror.Newf("unsupported emoji filetype: %s", info.Extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
internal/media/test/nb-flag-original.webp
Normal file
BIN
internal/media/test/nb-flag-original.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 294 B |
BIN
internal/media/test/nb-flag-static.png
Normal file
BIN
internal/media/test/nb-flag-static.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 878 B |
|
@ -93,7 +93,7 @@ module.exports = function NewEmojiForm() {
|
||||||
<form onSubmit={submitForm} className="form-flex">
|
<form onSubmit={submitForm} className="form-flex">
|
||||||
<FileInput
|
<FileInput
|
||||||
field={image}
|
field={image}
|
||||||
accept="image/png,image/gif"
|
accept="image/png,image/gif,image/webp"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|
Loading…
Reference in a new issue