2024-03-27 14:36:45 +00:00
|
|
|
package qrApi
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2024-03-27 15:00:59 +00:00
|
|
|
goqr "git.stuve.uni-ulm.de/stuve-it/stuve-it-backend/go-qr"
|
|
|
|
"git.stuve.uni-ulm.de/stuve-it/stuve-it-backend/logger"
|
2024-03-27 14:36:45 +00:00
|
|
|
"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 request data:
|
|
|
|
//
|
|
|
|
// {
|
|
|
|
// "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 `json:"data"`
|
|
|
|
ECC string `json:"ecc"`
|
|
|
|
Scale int `json:"scale"`
|
|
|
|
Border int `json:"border"`
|
|
|
|
ColorDark string `json:"color"`
|
|
|
|
ColorLight string `json:"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
|
|
|
|
return c.Stream(200, "image/svg+xml", io.Reader(&buffer))
|
|
|
|
}, apis.ActivityLogger(app))
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|