mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-17 05:14:52 +00:00
Pr/avatar (#319)
* feat: add avatar api close #310 * chore: add description line * fix: typo * chore: reformat the json string to make it more readable and fix few bad indents * fix: minimum go version * feat: upload to Micro's CDN * chore: delete redundant blank line * chore: update README.md
This commit is contained in:
98
avatar/handler/avatar.go
Normal file
98
avatar/handler/avatar.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/micro/micro/v3/service/errors"
|
||||
"github.com/o1egl/govatar"
|
||||
|
||||
pb "github.com/micro/services/avatar/proto"
|
||||
imagePb "github.com/micro/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.Url = uploadResp.Url
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user