add migrator between avatar stores
This commit is contained in:
@@ -97,6 +97,8 @@ func (gf *GridFS) Remove(avatar string) error {
|
||||
})
|
||||
}
|
||||
|
||||
// List all avatars (ids) on gfs
|
||||
// note: id includes .image suffix
|
||||
func (gf *GridFS) List() (ids []string, err error) {
|
||||
|
||||
type gfsFile struct {
|
||||
|
||||
@@ -97,6 +97,8 @@ func (fs *LocalFS) Remove(avatar string) error {
|
||||
return os.Remove(avFile)
|
||||
}
|
||||
|
||||
// List all avatars (ids) on local file system
|
||||
// note: id includes .image suffix
|
||||
func (fs *LocalFS) List() (ids []string, err error) {
|
||||
err = filepath.Walk(fs.storePath,
|
||||
func(path string, info os.FileInfo, err error) error {
|
||||
|
||||
@@ -35,6 +35,28 @@ type Store interface {
|
||||
|
||||
}
|
||||
|
||||
// Migrate avatars between stores
|
||||
func Migrate(dst Store, src Store) (int, error) {
|
||||
ids, err := src.List()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for _, id := range ids {
|
||||
srcReader, _, err := src.Get(id)
|
||||
if err != nil {
|
||||
log.Printf("[WARN] can't get reader for avatar %s", id)
|
||||
continue
|
||||
}
|
||||
if _, err = dst.Put(id, srcReader); err != nil {
|
||||
log.Printf("[WARN] can't put avatar %s", id)
|
||||
}
|
||||
if err = srcReader.Close(); err != nil {
|
||||
log.Printf("[WARN] failed to close avatar %s", id)
|
||||
}
|
||||
}
|
||||
return len(ids), nil
|
||||
}
|
||||
|
||||
// resize an image of supported format (PNG, JPG, GIF) to the size of "limit" px of the biggest side
|
||||
// (width or height) preserving aspect ratio.
|
||||
// Returns original reader if resizing is not needed or failed.
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"image"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -63,3 +65,45 @@ func TestAvatarStore_resize(t *testing.T) {
|
||||
assert.Equalf(t, c.hr, bounds.Dy(), "file %s", c.file)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAvatarStore_Migrate(t *testing.T) {
|
||||
// prep localfs
|
||||
plocal := NewLocalFS("/tmp/avatars.test", 300)
|
||||
err := os.MkdirAll("/tmp/avatars.test", 0700)
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll("/tmp/avatars.test")
|
||||
|
||||
// prep gridfs
|
||||
pgfs, skip := prepGFStore(t)
|
||||
if skip {
|
||||
return
|
||||
}
|
||||
|
||||
// write to localfs
|
||||
_, err = plocal.Put("user1", strings.NewReader("some picture bin data 1"))
|
||||
require.Nil(t, err)
|
||||
_, err = plocal.Put("user2", strings.NewReader("some picture bin data 2"))
|
||||
require.Nil(t, err)
|
||||
_, err = plocal.Put("user3", strings.NewReader("some picture bin data 3"))
|
||||
require.Nil(t, err)
|
||||
|
||||
// migrate and check reported count
|
||||
count, err := Migrate(pgfs, plocal)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 3, count, "all 3 recs migrated")
|
||||
|
||||
// list avatars
|
||||
l, err := pgfs.List()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 3, len(l), "3 avatars listed in destination store")
|
||||
sort.Strings(l)
|
||||
assert.Equal(t, []string{"0b7f849446d3383546d15a480966084442cd2193.image", "a1881c06eec96db9901c7bbfe41c42a3f08e9cb4.image", "b3daa77b4c04a9551b8781d03191fe098f325e67.image"}, l)
|
||||
|
||||
// try to read one of migrated avatars
|
||||
r, size, err := pgfs.Get("0b7f849446d3383546d15a480966084442cd2193.image")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 23, size)
|
||||
data, err := ioutil.ReadAll(r)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "some picture bin data 3", string(data))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user