forked from leeif/pluto
/
avatar.go
133 lines (118 loc) · 3.16 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package avatar
import (
"bytes"
"crypto/rand"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
b64 "encoding/base64"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/MuShare/pluto/config"
perror "github.com/MuShare/pluto/datatype/pluto_error"
)
var validAvatarType = []string{"jpeg", "jpg", "png"}
func randToken(len int) string {
b := make([]byte, len)
rand.Read(b)
return fmt.Sprintf("%x", b)
}
type AvatarGen struct {
}
type AvatarReader struct {
Reader io.ReadCloser
Ext string
OriginURL string
}
func (ag *AvatarGen) GenFromBase64String(avatar string) (*AvatarReader, *perror.PlutoError) {
b, err := b64.StdEncoding.DecodeString(avatar)
if err != nil {
return nil, perror.ServerError.Wrapper(fmt.Errorf("input is not in base64 format"))
}
ar := &AvatarReader{}
ar.Reader = ioutil.NopCloser(bytes.NewReader(b))
ct := http.DetectContentType(b)
for _, vat := range validAvatarType {
if strings.Contains(ct, vat) {
ar.Ext = vat
break
}
}
if ar.Ext == "" {
return nil, perror.InvalidAvatarFormat
}
ar.OriginURL = ""
return ar, nil
}
func (ag *AvatarGen) GenFromGravatar() (*AvatarReader, *perror.PlutoError) {
ar := &AvatarReader{}
originURL := fmt.Sprintf("https://www.gravatar.com/avatar/%s?f=y&d=identicon", randToken(8))
resp, err := http.Get(originURL)
if err != nil {
return nil, perror.ServerError.Wrapper(err)
}
ar.Reader = resp.Body
ar.OriginURL = originURL
contentType := resp.Header.Get("Content-type")
if contentType == "image/png" {
ar.Ext = "png"
} else if contentType == "image/jpg" {
ar.Ext = "jpg"
} else {
return nil, perror.ServerError.Wrapper(errors.New("Not support type of avatar " + contentType))
}
return ar, nil
}
func (as *AvatarSaver) SaveAvatarImageInOSS(reader *AvatarReader) (string, *perror.PlutoError) {
if as.AccessKeyID == "" ||
as.AccessKeySecret == "" ||
as.Bucket == "" ||
as.EndPoint == "" {
return "", perror.ServerError.Wrapper(errors.New("aliyun config is not enough"))
}
client, err := oss.New(as.EndPoint, as.AccessKeyID, as.AccessKeySecret)
if err != nil {
return "", perror.ServerError.Wrapper(err)
}
bucket, err := client.Bucket(as.Bucket)
if err != nil {
return "", perror.ServerError.Wrapper(err)
}
if reader.Ext == "" {
reader.Ext = "jpg"
}
osskey := fmt.Sprintf("avatar/%s.%s", randToken(8), reader.Ext)
err = bucket.PutObject(osskey, reader.Reader)
if err != nil {
return "", perror.ServerError.Wrapper(err)
}
url := ""
if as.CDN == "" {
url = fmt.Sprintf("https://%s.%s/%s", as.Bucket, as.EndPoint, osskey)
} else {
url = fmt.Sprintf("%s/%s", as.CDN, osskey)
}
return url, nil
}
func (as *AvatarSaver) SaveAvatarImageInLocal(file io.ReadCloser) (string, error) {
return "", nil
}
type AvatarSaver struct {
Bucket string
EndPoint string
AccessKeyID string
AccessKeySecret string
CDN string
}
func NewAvatarSaver(config *config.Config) *AvatarSaver {
as := &AvatarSaver{
Bucket: *config.Avatar.Bucket,
EndPoint: *config.Avatar.EndPoint,
AccessKeyID: *config.Avatar.AccessKeyID,
AccessKeySecret: *config.Avatar.AccessKeySecret,
CDN: *config.Avatar.CDN,
}
return as
}