stuve-it-backend/qrApi/main.go

111 lines
3.0 KiB
Go

package qrApi
import (
"bytes"
goqr "git.stuve.uni-ulm.de/stuve-it/stuve-it-backend/goqr"
"git.stuve.uni-ulm.de/stuve-it/stuve-it-backend/logger"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
"io"
)
// InitQRApi initializes ar code api endpoint
//
// this endpoint can be used to create qr codes
// GET /api/qr/v1
//
// the endpoint expects the following query params:
//
// "data": "what to be encoded",
// "ecc": "error correction level ('L', 'M' (default), 'Q', 'H')",
// "scale": "scale of qr code (default 1), must be greater than 0",
// "border": "border of qr code (default 1), must be equal or greater than 0, one is equal to one qr-code 'pixel'"
// "color": "color of qr code (default #000000)"
// "colorBackground": "background color of qr code (default #FFFFFF)",
//
// if the user is authenticated successfully the endpoint returns and apis.RecordAuthResponse
func InitQRApi(app *pocketbase.PocketBase, e *core.ServeEvent) error {
// add endpoint to app
logger.LogInfoF("Adding QR API Endpoint")
e.Router.GET("/api/qr/v1", func(c echo.Context) error {
// get data from request
data := struct {
Data string `query:"data"`
ECC string `query:"ecc"`
Scale int `query:"scale"`
Border int `query:"border"`
ColorDark string `query:"color"`
ColorLight string `query:"colorBackground"`
}{}
if err := c.Bind(&data); err != nil {
return apis.NewBadRequestError("Failed to read request data", err)
}
// get correct error correction level
var errCorLvl goqr.Ecc
switch data.ECC {
case "L":
errCorLvl = goqr.Low
case "M":
errCorLvl = goqr.Medium
case "Q":
errCorLvl = goqr.Quartile
case "H":
errCorLvl = goqr.High
default:
errCorLvl = goqr.Medium
}
// encode data to qr code
qrCode, err := goqr.EncodeText(data.Data, errCorLvl)
if err != nil {
return apis.NewBadRequestError("Failed to encode data to qr code", err)
}
// set default scale and border
scale := data.Scale
border := data.Border
if scale == 0 {
scale = 1
}
if border == 0 {
border = 1
}
config := goqr.NewQrCodeImgConfig(scale, border)
// create new buffer and writer
var buffer bytes.Buffer
writer := io.Writer(&buffer)
// set default colors
colorLight := data.ColorLight
colorDark := data.ColorDark
if colorLight == "" {
colorLight = "#FFFFFF"
}
if colorDark == "" {
colorDark = "#000000"
}
// write qr code to buffer
err = qrCode.WriteAsSVG(config, writer, colorLight, colorDark)
// return error if writing qr code to buffer fails
if err != nil {
logger.LogErrorF("Failed to write QR Code: %e", err)
return apis.NewBadRequestError("Failed to write QR Code", err)
}
// return qr code as svg
c.Response().Header().Set("Content-disposition", "attachment; filename=QR.svg")
return c.Stream(200, "image/svg+xml", io.Reader(&buffer))
}, apis.ActivityLogger(app))
return nil
}