Skip to content

Commit

Permalink
feat: add open with stat (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
Houtmann committed Sep 20, 2023
1 parent 5c0b5ea commit 31806d0
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 35 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ require (
github.com/thoas/go-funk v0.9.3
github.com/thoas/stats v0.0.0-20160726120248-152b5d051953
github.com/ulule/gokvstores v0.1.1-0.20221229151109-3bd12fb72ebe
github.com/ulule/gostorages v0.2.5-0.20230314124119-11134a4bce61
github.com/ulule/gostorages v0.2.5-0.20230920134537-c63293fd790c
github.com/urfave/cli v1.22.10
golang.org/x/image v0.6.0
google.golang.org/protobuf v1.31.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,14 @@ github.com/ulule/gokvstores v0.1.1-0.20221229151109-3bd12fb72ebe h1:ayWYvm5FWr78
github.com/ulule/gokvstores v0.1.1-0.20221229151109-3bd12fb72ebe/go.mod h1:2buRSW9ZL73BFOkRwBSOVcPJG/JQxcbZPs8fo0TD5X0=
github.com/ulule/gostorages v0.2.5-0.20230314124119-11134a4bce61 h1:Twadj4iaibm+nUX5PvElLeq5YsechTLpITZb/p27ywI=
github.com/ulule/gostorages v0.2.5-0.20230314124119-11134a4bce61/go.mod h1:7yGiGHJ9mE+He6sB42cJaRE4zcselRo4g2GBd8NGEMU=
github.com/ulule/gostorages v0.2.5-0.20230707071807-ba19d4693f53 h1:uzC+DOzybak6pNOK7u0UdTomOEu2wPuCxkLad9WNs44=
github.com/ulule/gostorages v0.2.5-0.20230707071807-ba19d4693f53/go.mod h1:7yGiGHJ9mE+He6sB42cJaRE4zcselRo4g2GBd8NGEMU=
github.com/ulule/gostorages v0.2.5-0.20230707072626-d429b21ca9b4 h1:PTBZrQv/VKCYBZQdbBj5ug+wvJZ+HuYLjAhzzu5PnB4=
github.com/ulule/gostorages v0.2.5-0.20230707072626-d429b21ca9b4/go.mod h1:7yGiGHJ9mE+He6sB42cJaRE4zcselRo4g2GBd8NGEMU=
github.com/ulule/gostorages v0.2.5-0.20230710095702-bfbe5260f605 h1:PYD0HGywjlJ+WxFivejD2zyVRD0rRclPmCHx+HdBbXQ=
github.com/ulule/gostorages v0.2.5-0.20230710095702-bfbe5260f605/go.mod h1:7yGiGHJ9mE+He6sB42cJaRE4zcselRo4g2GBd8NGEMU=
github.com/ulule/gostorages v0.2.5-0.20230920134537-c63293fd790c h1:bNM3RCu+JUVpPW3yZ7aWb/CIpW5DO8z0PGuqAquCnTE=
github.com/ulule/gostorages v0.2.5-0.20230920134537-c63293fd790c/go.mod h1:nMhvJt6g5Ulmp3Y1M159+xvsaF3EPwdWdvBnjYAWK3o=
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
9 changes: 2 additions & 7 deletions image/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,11 @@ func FromURL(ctx context.Context, u *url.URL, userAgent string) (*ImageFile, err
}

// FromStorage retrieves an ImageFile from storage
func FromStorage(ctx context.Context, storage storagepkg.Storage, filepath string) (*ImageFile, error) {
func FromStorage(ctx context.Context, storage *storagepkg.Storage, filepath string) (*ImageFile, error) {
var file *ImageFile
var err error

f, err := storage.Open(ctx, filepath)
if err != nil {
return nil, errors.WithStack(err)
}

stat, err := storage.Stat(ctx, filepath)
f, stat, err := storage.OpenWithStat(ctx, filepath)
if err != nil {
return nil, errors.WithStack(err)
}
Expand Down
2 changes: 1 addition & 1 deletion image/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type ImageFile struct {
Key string
Processed []byte
Source []byte
Storage storage.Storage
Storage *storage.Storage
}

func (i *ImageFile) URL() string {
Expand Down
3 changes: 2 additions & 1 deletion middleware/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package middleware

import (
"fmt"

"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus"
)

func MetricsMiddlewares(c *gin.Context) {
func Metrics(c *gin.Context) {
c.Next()
customMetrics.histogram.WithLabelValues(
c.Request.Method,
Expand Down
4 changes: 2 additions & 2 deletions server/middleware.go → middleware/recover.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package server
package middleware

import (
"net/http"

"github.com/gin-gonic/gin"
)

func recoverMiddleware(c *gin.Context) {
func Recover(c *gin.Context) {
defer func() {
// We must abort if there has been a recover, otherwise the
// remaining handlers would be called. If everything went fine,
Expand Down
7 changes: 4 additions & 3 deletions picfit.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package picfit

import (
"context"
"github.com/thoas/picfit/constants"
"log/slog"

"github.com/thoas/picfit/constants"

"github.com/thoas/picfit/config"
"github.com/thoas/picfit/engine"
"github.com/thoas/picfit/logger"
Expand Down Expand Up @@ -39,9 +40,9 @@ func NewProcessor(ctx context.Context, cfg *config.Config) (*Processor, error) {
Logger: log,

config: cfg,
destinationStorage: *destinationStorage,
destinationStorage: destinationStorage,
engine: e,
sourceStorage: *sourceStorage,
sourceStorage: sourceStorage,
store: s,
}, nil
}
9 changes: 5 additions & 4 deletions processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ type Processor struct {
Logger *slog.Logger

config *config.Config
destinationStorage storage.Storage
destinationStorage *storage.Storage
engine *engine.Engine
sourceStorage storage.Storage
sourceStorage *storage.Storage
store store.Store
}

Expand All @@ -46,8 +46,9 @@ func (p *Processor) Upload(ctx context.Context, payload *payload.Multipart) (*im
return nil, err
}

if err := p.sourceStorage.Save(ctx, fh, payload.Data.Filename); err != nil {
return nil, errors.Wrapf(err, "unable to save data on storage as: %s", payload.Data.Filename)
filepath := payload.Data.Filename
if err := p.sourceStorage.Save(ctx, fh, filepath); err != nil {
return nil, errors.Wrapf(err, "unable to save data on storage as: %s", filepath)
}
if err := fh.Close(); err != nil {
return nil, errors.WithStack(err)
Expand Down
16 changes: 9 additions & 7 deletions processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ func TestUploadHandler(t *testing.T) {

assert.Equal(t, 200, res.Code)

assert.True(t, suite.Processor.FileExists(context.Background(), "avatar.png"))
exists := suite.Processor.FileExists(context.Background(), "avatar.png")
assert.True(t, exists)

file, err := suite.Processor.OpenFile(context.Background(), "avatar.png")
assert.NoError(t, err)
Expand All @@ -237,7 +238,8 @@ func TestDeleteHandler(t *testing.T) {
// copy 5 images to src storage
for i := 0; i < 5; i++ {
fn := fmt.Sprintf("image%d.jpg", i+1)
err = os.WriteFile(filepath.Join(tmpSrcStorage, fn), img, 0644)
filepath := filepath.Join(tmpSrcStorage, fn)
err = os.WriteFile(filepath, img, 0644)
assert.Nil(t, err)
}

Expand Down Expand Up @@ -285,7 +287,7 @@ func TestDeleteHandler(t *testing.T) {

res := httptest.NewRecorder()
server.ServeHTTP(res, req)
assert.Equal(t, res.Code, 200)
assert.Equal(t, 200, res.Code)
}

checkDirCount(tmpDstStorage, 5, "after resize requests")
Expand All @@ -299,7 +301,7 @@ func TestDeleteHandler(t *testing.T) {

res := httptest.NewRecorder()
server.ServeHTTP(res, req)
assert.Equal(t, res.Code, 200)
assert.Equal(t, 200, res.Code)
}

checkDirCount(tmpSrcStorage, 5, "after resize requests")
Expand All @@ -312,7 +314,7 @@ func TestDeleteHandler(t *testing.T) {

res := httptest.NewRecorder()
server.ServeHTTP(res, req)
assert.Equal(t, res.Code, 200)
assert.Equal(t, 200, res.Code)

checkDirCount(tmpSrcStorage, 4, "after 1st delete request")
checkDirCount(tmpDstStorage, 2, "after 1st delete request")
Expand All @@ -324,7 +326,7 @@ func TestDeleteHandler(t *testing.T) {

res = httptest.NewRecorder()
server.ServeHTTP(res, req)
assert.Equal(t, res.Code, 404)
assert.Equal(t, 404, res.Code)

checkDirCount(tmpSrcStorage, 4, "after 2nd delete request")
checkDirCount(tmpDstStorage, 2, "after 2nd delete request")
Expand All @@ -339,7 +341,7 @@ func TestDeleteHandler(t *testing.T) {

res = httptest.NewRecorder()
server.ServeHTTP(res, req)
assert.Equal(t, res.Code, 200)
assert.Equal(t, 200, res.Code)

checkDirCount(tmpSrcStorage, 3, "after 3rd delete request")
checkDirCount(tmpDstStorage, 0, "after 3rd delete request")
Expand Down
4 changes: 2 additions & 2 deletions server/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ func (s *HTTPServer) Init() error {
if s.config.Debug {
router.Use(gin.Recovery())
} else {
router.Use(recoverMiddleware)
router.Use(middleware.Recover)
}

router.Use(middleware.NewLogger(s.config, s.processor.Logger))
router.Use(middleware.MetricsMiddlewares)
router.Use(middleware.Metrics)

if s.config.Sentry != nil {
if err := sentry.Init(sentry.ClientOptions{
Expand Down
4 changes: 4 additions & 0 deletions storage/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ func (s *DummyStorage) Open(ctx context.Context, filepath string) (io.ReadCloser
func (s DummyStorage) Stat(ctx context.Context, path string) (*gostorages.Stat, error) {
return &gostorages.Stat{}, nil
}

func (s DummyStorage) OpenWithStat(ctx context.Context, path string) (io.ReadCloser, *gostorages.Stat, error) {
return nil, &gostorages.Stat{}, nil
}
40 changes: 33 additions & 7 deletions storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package storage
import (
"context"
"fmt"
"io"
"log/slog"
"path"
"strings"
Expand All @@ -27,8 +28,8 @@ const (

// Storage wraps gostorages.Storage.
type Storage struct {
gostorages.Storage
cfg StorageConfig
storage gostorages.Storage
cfg StorageConfig
}

// URL returns the filepath prefixed with BaseURL from storage.
Expand All @@ -43,13 +44,38 @@ func (s *Storage) URL(filepath string) string {

// Path returns the filepath prefixed with Location from storage.
func (s *Storage) Path(filepath string) string {
if _, ok := s.storage.(*fsstorage.Storage); ok {
return filepath
}

return path.Join(s.cfg.Location, filepath)
}

func (s *Storage) Save(ctx context.Context, content io.Reader, path string) error {
filepath := s.Path(path)
return s.storage.Save(ctx, content, filepath)
}

func (s *Storage) Stat(ctx context.Context, path string) (*gostorages.Stat, error) {
return s.storage.Stat(ctx, s.Path(path))
}

func (s *Storage) Open(ctx context.Context, path string) (io.ReadCloser, error) {
return s.storage.Open(ctx, s.Path(path))
}

func (s *Storage) OpenWithStat(ctx context.Context, path string) (io.ReadCloser, *gostorages.Stat, error) {
return s.storage.OpenWithStat(ctx, s.Path(path))

}
func (s *Storage) Delete(ctx context.Context, path string) error {
return s.storage.Delete(ctx, s.Path(path))
}

// New return destination and source storages from config
func New(ctx context.Context, log *slog.Logger, cfg *Config) (*Storage, *Storage, error) {
if cfg == nil {
storage := &Storage{Storage: &DummyStorage{}}
storage := &Storage{storage: &DummyStorage{}}

log.InfoContext(ctx, "Source storage configured",
slog.String("type", "dummy"))
Expand Down Expand Up @@ -78,10 +104,10 @@ func New(ctx context.Context, log *slog.Logger, cfg *Config) (*Storage, *Storage
slog.String("type", cfg.Source.Type))

return &Storage{
Storage: sourceStorage,
storage: sourceStorage,
cfg: *cfg.Source,
}, &Storage{
Storage: sourceStorage,
storage: sourceStorage,
cfg: *cfg.Source,
}, nil
}
Expand All @@ -95,10 +121,10 @@ func New(ctx context.Context, log *slog.Logger, cfg *Config) (*Storage, *Storage
slog.String("type", cfg.Destination.Type))

return &Storage{
Storage: sourceStorage,
storage: sourceStorage,
cfg: *cfg.Source,
}, &Storage{
Storage: destinationStorage,
storage: destinationStorage,
cfg: *cfg.Destination,
}, nil
}
Expand Down

0 comments on commit 31806d0

Please sign in to comment.