Nicolai Ort c09c00ec68
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
feat(pdfs): Set download names for pdf generation responses
2024-12-12 18:24:07 +01:00

111 lines
2.9 KiB
Go

package handlers
import (
"log"
"slices"
"git.odit.services/lfk/document-server/models"
"github.com/gofiber/fiber/v2"
)
// GenerateCard godoc
//
// @Summary Generate runner cards
// @Description Generate cards based on the provided data
// @Tags pdfs
// @Accept json
// @Param data body models.CardRequest true "Card data"
// @Produce application/pdf
// @Security ApiKeyAuth
// @Router /v1/pdfs/cards [post]
func (h *DefaultHandler) GenerateCard(c *fiber.Ctx) error {
cardRequest := new(models.CardRequest)
if err := c.BodyParser(cardRequest); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": err.Error(),
})
}
if !slices.Contains([]string{"en", "de"}, cardRequest.Locale) {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid locale",
})
}
templateString, err := h.StaticService.GetTemplate(cardRequest.Locale, "card")
if err != nil {
log.Println(err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Template not found",
})
}
template, err := h.Templater.StringToTemplate(templateString)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": err.Error(),
})
}
genConfig := &models.CardTemplateOptions{
CardSegments: splitCardSegments(cardRequest.Cards),
EventName: h.Config.EventName,
CardSubtitle: h.Config.CardSubtitle,
BarcodeFormat: h.Config.CardBarcodeFormat,
BarcodePrefix: h.Config.CardBarcodePrefix,
}
result, err := h.Templater.Execute(template, genConfig)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": err.Error(),
})
}
c.Set(fiber.HeaderContentType, "text/html")
pdf, err := h.Converter.ToPdf(result, "a4", false)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": err.Error(),
})
}
c.Set(fiber.HeaderContentType, "application/pdf")
c.Set(fiber.HeaderContentDisposition, "attachment; filename=runner-cards.pdf")
return c.Send(pdf)
}
func invertCardArrayItemPairs(cards []models.Card) []models.Card {
inverted := make([]models.Card, 0)
for i := 0; i < len(cards); i += 2 {
if i+1 < len(cards) {
inverted = append(inverted, cards[i+1])
}
inverted = append(inverted, cards[i])
}
return inverted
}
func splitCardSegments(cards []models.Card) []models.CardTemplateSegment {
cardSegments := make([]models.CardTemplateSegment, 0)
const currentCards = 0
for i := 0; i < len(cards); i += 10 {
segmentLength := 10
if len(cards)-i < 10 {
segmentLength = len(cards) - i
}
segment := cards[i : i+segmentLength]
if segmentLength%2 != 0 {
segment = append(segment, models.Card{
ID: 0,
Enabled: false,
Runner: models.Runner{},
Code: "",
})
}
cardSegments = append(cardSegments, models.CardTemplateSegment{
Cards: segment,
CardsSwapped: invertCardArrayItemPairs(segment),
})
}
return cardSegments
}