This repository has been archived by the owner on Mar 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 81
/
avatar.go
99 lines (81 loc) · 2.06 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
package handler
import (
"bytes"
"context"
"encoding/base64"
"fmt"
"image"
"image/jpeg"
"image/png"
"github.com/google/uuid"
"m3o.dev/platform/service/errors"
"github.com/o1egl/govatar"
pb "m3o.dev/services/avatar/proto"
imagePb "m3o.dev/services/image/proto"
)
type avatar struct {
imageSvc imagePb.ImageService
}
func NewAvatar(service imagePb.ImageService) *avatar {
return &avatar{
imageSvc: service,
}
}
// Generate is used to generate a avatar
func (e *avatar) Generate(ctx context.Context, req *pb.GenerateRequest, rsp *pb.GenerateResponse) error {
var gender govatar.Gender
// gender, default is `male`
if req.Gender == "male" {
gender = govatar.MALE
} else if req.Gender == "female" {
gender = govatar.FEMALE
} else {
gender = govatar.MALE
}
// generate avatar
var avatarImg image.Image
var err error
if req.Username == "" {
avatarImg, err = govatar.Generate(gender)
} else {
avatarImg, err = govatar.GenerateForUsername(gender, req.Username)
}
if err != nil {
return errors.InternalServerError("avatar.generate", "generate avatarImg error: %v", err)
}
// format avatar image, default is `jpeg`
format := req.Format
if format != "png" && format != "jpeg" {
format = "jpeg"
}
buf := bytes.NewBuffer(nil)
if format == "png" {
err = png.Encode(buf, avatarImg)
} else {
err = jpeg.Encode(buf, avatarImg, nil)
}
if err != nil {
return errors.InternalServerError("avatar.generate", "encode avatar image error: %v", err)
}
base64String := fmt.Sprintf("data:image/%s;base64,%s", format, base64.StdEncoding.EncodeToString(buf.Bytes()))
if !req.Upload {
rsp.Base64 = base64String
return nil
}
// upload to CDN
name := req.Username
if name == "" {
uid, _ := uuid.NewUUID()
name = uid.String()
}
uploadResp, err := e.imageSvc.Upload(ctx, &imagePb.UploadRequest{
Base64: base64String,
Name: fmt.Sprintf("%s.%s", name, format),
})
if err != nil {
return errors.InternalServerError("avatar.generate", "upload avatar image error: %v", err)
}
rsp.Base64 = base64String
rsp.Url = uploadResp.Url
return nil
}