package equipment import ( "encoding/base64" "encoding/json" "jannex/admin-dashboard-backend/modules/config" "jannex/admin-dashboard-backend/modules/database" "jannex/admin-dashboard-backend/modules/equipment" "jannex/admin-dashboard-backend/modules/structs" "jannex/admin-dashboard-backend/modules/utils" "os" "strings" "github.com/gofiber/fiber/v2" "github.com/google/uuid" "github.com/rs/zerolog/log" ) func getImageType(data string) string { switch data { case "data:image/png;base64": return "png" default: return "jpeg" } } type Notes struct { Image string Description string } func CreateEquipmentDocumentation(c *fiber.Ctx) error { var body structs.ApiCreateEquipmentDocumentationRequest if err := c.BodyParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(err) } var bodyNotes []map[string]string err := json.Unmarshal(body.Notes, &bodyNotes) if err != nil { log.Error().Msgf("Failed to unmarshal json, err: %s", err) return c.SendStatus(fiber.StatusInternalServerError) } newEquipmentDocumentation := structs.EquipmentDocumentation{ Id: uuid.New().String(), StockItemId: body.StockItemId, Type: body.Type, Title: body.Title, } // TODO: only create folder if there is an image if err := os.Mkdir(config.Cfg.FolderPaths.PublicStatic+"/equipmentdocumentation/"+newEquipmentDocumentation.Id, os.ModePerm); err != nil { log.Error().Msgf("Failed to create folder, err: %s", err) return c.SendStatus(fiber.StatusInternalServerError) } var notes []Notes // loop throught bodyNotes and save image to static folder under random name for _, bodyNote := range bodyNotes { var newFileName string if bodyNote["image"] != "" { // image is sent as base64 string // decode it and save it to the static folder // encoded base64 image structure is: data:image/jpeg;base64,/9j/4AA... splittedImageData := strings.Split(bodyNote["image"], ",") decodedImage, err := base64.StdEncoding.DecodeString(splittedImageData[1]) if err != nil { log.Error().Msgf("Failed to decode base64 string, err: %s", err) return c.SendStatus(fiber.StatusInternalServerError) } newFileName = uuid.New().String() + "." + getImageType(splittedImageData[0]) err = os.WriteFile(config.Cfg.FolderPaths.PublicStatic+"/equipmentdocumentation/"+newEquipmentDocumentation.Id+"/"+newFileName, decodedImage, 0644) if err != nil { log.Error().Msgf("Failed to save image, err: %s", err) return c.SendStatus(fiber.StatusInternalServerError) } } notes = append(notes, Notes{ Image: newFileName, Description: bodyNote["description"], }) } marshaledNotes, err := json.Marshal(notes) if err != nil { log.Error().Msgf("Failed to marshal notes, err: %s", err) return c.SendStatus(fiber.StatusInternalServerError) } newEquipmentDocumentation.Notes = string(marshaledNotes) database.DB.Create(&newEquipmentDocumentation) return c.JSON(fiber.Map{"message": "ok"}) } func GetEquipmentDocumentation(c *fiber.Ctx) error { var body structs.ApiEquipmentParamsRequest if err := c.ParamsParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(err) } if errValidation := utils.ValidateStruct(body); errValidation != nil { log.Error().Msgf("Failed to validate body, err: %v", errValidation) return c.Status(fiber.StatusBadRequest).JSON(errValidation) } return equipment.GetEquipmentDocumentation(body.StockItemId, c) } // fetching the thumbnail from the invex server and sending it back to the client func GetEquipmentThumbnail(c *fiber.Ctx) error { //resp, err := http.Get(equipment.Base + "/media/part_images/part_152_image.thumbnail.png") a := fiber.AcquireAgent() a.Add("Authorization", "Token "+equipment.ApiToken) req := a.Request() req.Header.SetMethod(fiber.MethodGet) req.SetRequestURI(equipment.Base + "/media/part_images/" + c.Params("stockItemThumbnail")) if err := a.Parse(); err != nil { log.Error().Msgf("Failed to parse request, err: %s", err) return c.SendStatus(fiber.StatusInternalServerError) } code, body, errs := a.Bytes() log.Info().Msgf("code %d %s", code, errs) c.Set("Content-Type", "image/png") return c.Send(body) }