diff options
Diffstat (limited to 'utils/storage')
| -rw-r--r-- | utils/storage/minio.go | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/utils/storage/minio.go b/utils/storage/minio.go new file mode 100644 index 0000000..0d6e364 --- /dev/null +++ b/utils/storage/minio.go @@ -0,0 +1,170 @@ +package storage + +import ( + "bytes" + "context" + "fmt" + "io" + "lain/config" + "path/filepath" + "time" + + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" +) + +var minioClient *minio.Client + +func InitMinIO() error { + client, err := minio.New(config.MinIO.Endpoint, &minio.Options{ + Creds: credentials.NewStaticV4(config.MinIO.AccessKey, config.MinIO.SecretKey, ""), + Secure: config.MinIO.UseSSL, + }) + if err != nil { + return fmt.Errorf("failed to create minio client: %w", err) + } + + ctx := context.Background() + exists, err := client.BucketExists(ctx, config.MinIO.BucketName) + if err != nil { + return fmt.Errorf("failed to check bucket existence: %w", err) + } + + if !exists { + err = client.MakeBucket(ctx, config.MinIO.BucketName, minio.MakeBucketOptions{}) + if err != nil { + return fmt.Errorf("failed to create bucket: %w", err) + } + } + + minioClient = client + return nil +} + +func UploadAttachment(userEmail string, emailID uint, filename string, data []byte, contentType string) (string, error) { + if minioClient == nil { + return "", fmt.Errorf("minio client not initialized") + } + + path := fmt.Sprintf("attachments/%s/%d/%s", userEmail, emailID, filename) + + ctx := context.Background() + + _, err := minioClient.PutObject( + ctx, + config.MinIO.BucketName, + path, + bytes.NewReader(data), + int64(len(data)), + minio.PutObjectOptions{ + ContentType: contentType, + }, + ) + + if err != nil { + return "", fmt.Errorf("failed to upload attachment: %w", err) + } + + return path, nil +} + +func DownloadAttachment(path string) ([]byte, error) { + if minioClient == nil { + return nil, fmt.Errorf("minio client not initialized") + } + + ctx := context.Background() + + object, err := minioClient.GetObject(ctx, config.MinIO.BucketName, path, minio.GetObjectOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to get attachment object: %w", err) + } + defer object.Close() + + data, err := io.ReadAll(object) + if err != nil { + return nil, fmt.Errorf("failed to read attachment data: %w", err) + } + + return data, nil +} + +func DeleteAttachment(path string) error { + if minioClient == nil { + return fmt.Errorf("minio client not initialized") + } + + ctx := context.Background() + + err := minioClient.RemoveObject(ctx, config.MinIO.BucketName, path, minio.RemoveObjectOptions{}) + if err != nil { + return fmt.Errorf("failed to delete attachment: %w", err) + } + + return nil +} + +func DeleteAttachmentsByEmail(userEmail string, emailID uint) error { + if minioClient == nil { + return fmt.Errorf("minio client not initialized") + } + + ctx := context.Background() + prefix := fmt.Sprintf("attachments/%s/%d/", userEmail, emailID) + + objectCh := minioClient.ListObjects(ctx, config.MinIO.BucketName, minio.ListObjectsOptions{ + Prefix: prefix, + Recursive: true, + }) + + for object := range objectCh { + if object.Err != nil { + return fmt.Errorf("failed to list attachments: %w", object.Err) + } + + err := minioClient.RemoveObject(ctx, config.MinIO.BucketName, object.Key, minio.RemoveObjectOptions{}) + if err != nil { + return fmt.Errorf("failed to delete attachment %s: %w", object.Key, err) + } + } + + return nil +} + +func GetAttachmentURL(path string, expiryDuration time.Duration) (string, error) { + if minioClient == nil { + return "", fmt.Errorf("minio client not initialized") + } + + ctx := context.Background() + + url, err := minioClient.PresignedGetObject(ctx, config.MinIO.BucketName, path, expiryDuration, nil) + if err != nil { + return "", fmt.Errorf("failed to generate presigned url: %w", err) + } + + return url.String(), nil +} + +func GetAttachmentFilename(path string) string { + return filepath.Base(path) +} + +func AttachmentExists(path string) (bool, error) { + if minioClient == nil { + return false, fmt.Errorf("minio client not initialized") + } + + ctx := context.Background() + + _, err := minioClient.StatObject(ctx, config.MinIO.BucketName, path, minio.StatObjectOptions{}) + if err != nil { + errResponse := minio.ToErrorResponse(err) + if errResponse.Code == "NoSuchKey" { + return false, nil + } + return false, fmt.Errorf("failed to check attachment existence: %w", err) + } + + return true, nil +} |
