| package services |
|
|
| import ( |
| "bytes" |
| "context" |
| "fmt" |
| "image" |
| "image/jpeg" |
| _ "image/png" |
| "io" |
| "log" |
| "mime/multipart" |
| "service-warungpos-go/config" |
|
|
| "github.com/cloudinary/cloudinary-go/v2" |
| "github.com/cloudinary/cloudinary-go/v2/api/uploader" |
| ) |
|
|
| |
| func UploadToCloudinary(fileHeader *multipart.FileHeader) (string, error) { |
| |
| file, err := fileHeader.Open() |
| if err != nil { |
| return "", fmt.Errorf("gagal membuka file: %v", err) |
| } |
| defer file.Close() |
|
|
| |
| contents, err := io.ReadAll(file) |
| if err != nil { |
| return "", fmt.Errorf("gagal membaca file: %v", err) |
| } |
|
|
| |
| compressedBytes, err := compressImage(contents) |
| if err != nil { |
| log.Printf("[CLOUDINARY] Gagal kompresi, menggunakan file asli: %v", err) |
| compressedBytes = contents |
| } |
|
|
| |
| cld, err := cloudinary.NewFromParams( |
| config.GlobalConfig.CloudinaryCloudName, |
| config.GlobalConfig.CloudinaryAPIKey, |
| config.GlobalConfig.CloudinaryAPISecret, |
| ) |
| if err != nil { |
| return "", fmt.Errorf("gagal inisialisasi Cloudinary: %v", err) |
| } |
|
|
| ctx := context.Background() |
|
|
| |
| resp, err := cld.Upload.Upload(ctx, bytes.NewReader(compressedBytes), uploader.UploadParams{ |
| Folder: "warungpos/products", |
| }) |
| if err != nil { |
| return "", fmt.Errorf("gagal upload ke Cloudinary: %v", err) |
| } |
|
|
| |
| |
| if resp.Error.Message != "" { |
| return "", fmt.Errorf("cloudinary error: %s", resp.Error.Message) |
| } |
|
|
| log.Printf("[CLOUDINARY] Upload sukses! URL: %s", resp.SecureURL) |
| return resp.SecureURL, nil |
| } |
|
|
| |
| func compressImage(imgBytes []byte) ([]byte, error) { |
| |
| img, _, err := image.Decode(bytes.NewReader(imgBytes)) |
| if err != nil { |
| return nil, err |
| } |
|
|
| |
| var buf bytes.Buffer |
| err = jpeg.Encode(&buf, img, &jpeg.Options{Quality: 75}) |
| if err != nil { |
| return nil, err |
| } |
|
|
| return buf.Bytes(), nil |
| } |
|
|