mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-11 19:04:35 +00:00
* 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
99 lines
2.1 KiB
Go
99 lines
2.1 KiB
Go
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
|
|
}
|