-
-
Notifications
You must be signed in to change notification settings - Fork 367
/
avatar.go
85 lines (69 loc) · 2.4 KB
/
avatar.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package cmd
import (
"fmt"
"path"
log "github.com/go-pkgz/lgr"
bolt "go.etcd.io/bbolt"
"github.com/go-pkgz/auth/avatar"
)
// AvatarCommand set of flags and command for avatar migration
// it converts all avatars from src.type to dst.type.
// Note: it is possible to run migration for the same types (src = dst) in order to resize all avatars.
type AvatarCommand struct {
AvatarSrc AvatarGroup `group:"src" namespace:"src"`
AvatarDst AvatarGroup `group:"dst" namespace:"dst"`
migrator AvatarMigrator
CommonOpts
}
// AvatarMigrator defines interface for migration
type AvatarMigrator interface {
Migrate(avatar.Store, avatar.Store) (int, error)
}
type avatarMigrator struct{}
// Migrate from one avatar store to another. Can be used to convert between stores
func (a avatarMigrator) Migrate(dst, src avatar.Store) (int, error) {
return avatar.Migrate(dst, src)
}
// Execute runs with AvatarCommand parameters, entry point for "avatar" command
func (ac *AvatarCommand) Execute(_ []string) error {
log.Printf("[INFO] migrate avatars from %s to %s", ac.AvatarSrc.Type, ac.AvatarDst.Type)
src, err := ac.makeAvatarStore(ac.AvatarSrc)
if err != nil {
return fmt.Errorf("can't make avatart store for %s: %w", ac.AvatarSrc.Type, err)
}
dst, err := ac.makeAvatarStore(ac.AvatarDst)
if err != nil {
return fmt.Errorf("can't make avatart store for %s: %w", ac.AvatarDst.Type, err)
}
if ac.migrator == nil {
ac.migrator = avatarMigrator{}
}
count, err := ac.migrator.Migrate(dst, src)
if err != nil {
return err
}
if err = dst.Close(); err != nil {
log.Printf("[WARN] failed to close dst store %s", ac.AvatarDst.Type)
}
if err = src.Close(); err != nil {
log.Printf("[WARN] failed to close src store %s", ac.AvatarSrc.Type)
}
log.Printf("[INFO] completed, migrated avatars = %d", count)
return nil
}
func (ac *AvatarCommand) makeAvatarStore(gr AvatarGroup) (avatar.Store, error) {
log.Printf("[DEBUG] make avatar store, type=%s", gr.Type)
switch gr.Type {
case "fs":
if err := makeDirs(gr.FS.Path); err != nil {
return nil, fmt.Errorf("failed to create avatar store: %w", err)
}
return avatar.NewLocalFS(gr.FS.Path), nil
case "bolt":
if err := makeDirs(path.Dir(gr.Bolt.File)); err != nil {
return nil, fmt.Errorf("failed to create avatar store: %w", err)
}
return avatar.NewBoltDB(gr.Bolt.File, bolt.Options{})
}
return nil, fmt.Errorf("unsupported avatar store type %s", gr.Type)
}