package handlers import ( "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 { logger := h.Logger.Named("GenerateCard") cardRequest := new(models.CardRequest) if err := c.BodyParser(cardRequest); err != nil { logger.Errorw("Invalid request", "error", err) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": err.Error(), }) } if !slices.Contains([]string{"en", "de"}, cardRequest.Locale) { logger.Errorw("Invalid locale", "locale", cardRequest.Locale) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid locale", }) } logger = logger.With("locale", cardRequest.Locale) templateString, err := h.StaticService.GetTemplate(cardRequest.Locale, "card") if err != nil { logger.Errorw("Template not found", "error", err) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Template not found", }) } template, err := h.Templater.StringToTemplate(templateString) if err != nil { logger.Errorw("Error parsing template", "error", err) 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, } logger.Info("Generating card html") result, err := h.Templater.Execute(template, genConfig) if err != nil { logger.Errorw("Error executing template", "error", err) return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": err.Error(), }) } logger.Info("Generated card html") c.Set(fiber.HeaderContentType, "text/html") logger.Info("Converting html to pdf") pdf, err := h.Converter.ToPdf(result, "a4", false) if err != nil { logger.Errorw("Error converting html to pdf", "error", err) return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": err.Error(), }) } logger.Info("Converted html to pdf") 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 }