work on emojis

This commit is contained in:
tsmethurst 2021-04-14 18:16:58 +02:00
commit 32629a378d
31 changed files with 605 additions and 67 deletions

View file

@ -33,15 +33,23 @@ import (
)
const (
// Key for small/thumbnail versions of media
MediaSmall = "small"
// Key for original/fullsize versions of media and emoji
MediaOriginal = "original"
// Key for static (non-animated) versions of emoji
MediaStatic = "static"
// Key for media attachments
MediaAttachment = "attachment"
// Key for profile header
MediaHeader = "header"
// Key for profile avatar
MediaAvatar = "avatar"
// Key for emoji type
MediaEmoji = "emoji"
emojiMaxBytes = 51200
// Maximum permitted bytes of an emoji upload (50kb)
EmojiMaxBytes = 51200
)
// MediaHandler provides an interface for parsing, storing, and retrieving media objects like photos, videos, and gifs.
@ -55,6 +63,11 @@ type MediaHandler interface {
// puts it in whatever storage backend we're using, sets the relevant fields in the database for the new media,
// and then returns information to the caller about the attachment.
ProcessLocalAttachment(attachment []byte, accountID string) (*gtsmodel.MediaAttachment, error)
// ProcessLocalEmoji takes a new emoji and a shortcode, cleans it up, puts it in storage, and creates a new
// *gts.Emoji for it, then returns it to the caller. It's the caller's responsibility to put the returned struct
// in the database.
ProcessLocalEmoji(emojiBytes []byte, shortcode string) (*gtsmodel.Emoji, error)
}
type mediaHandler struct {
@ -165,8 +178,8 @@ func (mh *mediaHandler) ProcessLocalEmoji(emojiBytes []byte, shortcode string) (
if len(emojiBytes) == 0 {
return nil, errors.New("emoji was of size 0")
}
if len(emojiBytes) > emojiMaxBytes {
return nil, fmt.Errorf("emoji size %d bytes exceeded max emoji size of %d bytes", len(emojiBytes), emojiMaxBytes)
if len(emojiBytes) > EmojiMaxBytes {
return nil, fmt.Errorf("emoji size %d bytes exceeded max emoji size of %d bytes", len(emojiBytes), EmojiMaxBytes)
}
// clean any exif data from image/png type but leave gifs alone
@ -227,7 +240,7 @@ func (mh *mediaHandler) ProcessLocalEmoji(emojiBytes []byte, shortcode string) (
}
// store the static
if err := mh.storage.StoreFileAt(emojiPath, static.image); err != nil {
if err := mh.storage.StoreFileAt(emojiStaticPath, static.image); err != nil {
return nil, fmt.Errorf("storage error: %s", err)
}

View file

@ -115,6 +115,11 @@ func (suite *MediaTestSuite) SetupTest() {
logrus.Panicf("db connection error: %s", err)
}
}
err := suite.db.CreateInstanceAccount()
if err != nil {
logrus.Panic(err)
}
}
// TearDownTest drops tables to make sure there's no data in the db
@ -151,6 +156,15 @@ func (suite *MediaTestSuite) TestSetHeaderOrAvatarForAccountID() {
//TODO: add more checks here, cba right now!
}
func (suite *MediaTestSuite) TestProcessLocalEmoji() {
f, err := ioutil.ReadFile("./test/rainbow-original.png")
assert.NoError(suite.T(), err)
emoji, err := suite.mediaHandler.ProcessLocalEmoji(f, "rainbow")
assert.NoError(suite.T(), err)
suite.log.Debugf("%+v", emoji)
}
// TODO: add tests for sad path, gif, png....
func TestMediaTestSuite(t *testing.T) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -248,6 +248,7 @@ func deriveThumbnail(b []byte, contentType string, x uint, y uint) (*imageAndMet
}, nil
}
// deriveStaticEmojji takes a given gif or png of an emoji, decodes it, and re-encodes it as a static png.
func deriveStaticEmoji(b []byte, contentType string) (*imageAndMeta, error) {
var i image.Image
var err error