chore: custom error
This commit is contained in:
@@ -3,10 +3,20 @@ package images
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/valkey-io/valkey-go"
|
||||
)
|
||||
|
||||
var ErrNotAnImage = errors.New("not an image")
|
||||
@@ -24,7 +34,7 @@ func (s *Service) getMime(path string) (mimeType string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) GetImage(ctx context.Context, uid string) (img io.Reader, mimeType string, err error) {
|
||||
func (s *Service) getImage(uid string) (file []byte, mimeType string, err error) {
|
||||
path, err := PathFromUID(uid)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("could not get path: %w", err)
|
||||
@@ -40,10 +50,69 @@ func (s *Service) GetImage(ctx context.Context, uid string) (img io.Reader, mime
|
||||
return
|
||||
}
|
||||
|
||||
file, err := s.fs.Read(path)
|
||||
file, err = s.fs.Read(path)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("image file could not be fetched")
|
||||
}
|
||||
|
||||
return bytes.NewBuffer(file), mimeType, err
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) GetImage(ctx context.Context, uid string, options Options) (img io.Reader, mimeType string, err error) {
|
||||
rawImage, mimeType, err := s.getImage(uid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
hash, err := hash(rawImage, options)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if imgBytes, err := s.cache.Do(ctx, s.cache.B().Get().Key("img:"+hash).Build()).AsBytes(); err == nil {
|
||||
return bytes.NewBuffer(imgBytes), mimeType, err
|
||||
}
|
||||
|
||||
decImage, _, err := image.Decode(bytes.NewBuffer(rawImage))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
decImage = scale(decImage, options)
|
||||
outBuff := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||
|
||||
if options.Quality == 0 {
|
||||
options.Quality = 80
|
||||
}
|
||||
|
||||
err = jpeg.Encode(outBuff, decImage, &jpeg.Options{Quality: options.Quality})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.cache.Do(ctx, s.cache.B().Set().Key("img:"+hash).Value(valkey.BinaryString(outBuff.Bytes())).Ex(time.Hour*48).Build()).Error(); err == nil {
|
||||
return outBuff, "image/jpeg", err
|
||||
}
|
||||
|
||||
return outBuff, "image/jpeg", err
|
||||
}
|
||||
|
||||
func hash(bytes []byte, options Options) (hash string, err error) {
|
||||
h := fnv.New128()
|
||||
|
||||
if _, err = h.Write(bytes); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Write(h, binary.LittleEndian, int64(options.Height)); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Write(h, binary.LittleEndian, int64(options.Width)); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Write(h, binary.LittleEndian, int64(options.Quality)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
res := h.Sum(make([]byte, 0, 128/8))
|
||||
|
||||
return base64.RawStdEncoding.EncodeToString(res), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user