Files
services/qr/handler/qr.go
2021-09-20 11:15:52 +01:00

93 lines
2.4 KiB
Go

package handler
import (
"bytes"
"context"
"encoding/json"
"fmt"
"time"
"github.com/google/uuid"
"github.com/micro/micro/v3/service/config"
"github.com/micro/micro/v3/service/errors"
log "github.com/micro/micro/v3/service/logger"
"github.com/micro/micro/v3/service/store"
"github.com/micro/services/pkg/tenant"
qr "github.com/micro/services/qr/proto"
"github.com/skip2/go-qrcode"
)
const (
prefixByTenant = "qrByTenant"
defaultCodeSize = 256
)
type QrCode struct {
Filename string `json:"filename"`
Created int64 `json:"created"`
Text string `json:"text"`
}
type Qr struct {
cdnPrefix string
}
func New() *Qr {
v, err := config.Get("micro.qr.cdnprefix")
if err != nil {
log.Fatalf("Failed to get CDN prefix %s", err)
}
pref := v.String("")
if len(pref) == 0 {
log.Fatalf("Failed to get CDN prefix")
}
return &Qr{cdnPrefix: pref}
}
func (q *Qr) Generate(ctx context.Context, request *qr.GenerateRequest, response *qr.GenerateResponse) error {
if len(request.Text) == 0 {
return errors.BadRequest("qr.generate", "Missing parameter text")
}
ten, ok := tenant.FromContext(ctx)
if !ok {
log.Errorf("Error retrieving tenant")
return errors.Unauthorized("qr.generate", "Unauthorized")
}
size := defaultCodeSize
if request.Size > 0 {
size = int(request.Size)
}
qrc, err := qrcode.Encode(request.Text, qrcode.Medium, size)
if err != nil {
log.Errorf("Error generating QR code %s", err)
return errors.InternalServerError("qr.generate", "Error while generating QR code")
}
nsPrefix := "micro/qr/" + ten
fileName := fmt.Sprintf("%s.png", uuid.New().String())
if err := store.DefaultBlobStore.Write(
fileName, bytes.NewBuffer(qrc),
store.BlobContentType("image/png"),
store.BlobPublic(true),
store.BlobNamespace(nsPrefix)); err != nil {
log.Errorf("Error saving QR code to blob store %s", err)
return errors.InternalServerError("qr.generate", "Error while generating QR code")
}
// store record of it
rec := QrCode{
Filename: fileName,
Created: time.Now().Unix(),
Text: request.Text,
}
b, _ := json.Marshal(&rec)
if err := store.Write(&store.Record{
Key: fmt.Sprintf("%s/%s/%s", prefixByTenant, nsPrefix, fileName),
Value: b,
}); err != nil {
log.Errorf("Error saving QR code record %s", err)
return errors.InternalServerError("qr.generate", "Error while generating QR code")
}
response.Qr = fmt.Sprintf("%s/%s/%s", q.cdnPrefix, nsPrefix, rec.Filename)
return nil
}