diff --git a/internal/interfaces/mediaStorage.go b/internal/interfaces/mediaStorage.go new file mode 100644 index 0000000..ff185ed --- /dev/null +++ b/internal/interfaces/mediaStorage.go @@ -0,0 +1,15 @@ +package interfaces + +import ( + "context" + "io" + "net/url" + "time" +) + +type MediaStorage interface { + СreateBucketIfNotExists(bucketName string) error + Upload(ctx context.Context, bucket, object string, reader io.Reader, size int64) error + Get(ctx context.Context, bucket, object string, expires time.Duration, params url.Values) (*url.URL, error) + Delete(ctx context.Context, bucket, object string) error +} diff --git a/internal/mediaStorage/handler.go b/internal/mediaStorage/handler.go new file mode 100644 index 0000000..90732d0 --- /dev/null +++ b/internal/mediaStorage/handler.go @@ -0,0 +1,35 @@ +package mediaStorage + +import ( + "fmt" + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" + log "github.com/sirupsen/logrus" +) + +type Handler struct { + *Service +} + +type Deps struct { + Host string + Port string + User string + Password string +} + +func NewHandler(deps Deps) *Handler { + endpoint := fmt.Sprintf("%s:%s", deps.Host, deps.Port) + minioClient, err := minio.New(endpoint, &minio.Options{ + Creds: credentials.NewStaticV4(deps.User, deps.Password, ""), + Secure: false, + }) + + if err != nil { + log.WithError(err).Fatal("Media storage | Failed to create minio client") + } + + return &Handler{ + newService(minioClient), + } +} diff --git a/internal/mediaStorage/service.go b/internal/mediaStorage/service.go new file mode 100644 index 0000000..1ae0e2b --- /dev/null +++ b/internal/mediaStorage/service.go @@ -0,0 +1,52 @@ +package mediaStorage + +import ( + "context" + "errors" + "fmt" + "github.com/minio/minio-go/v7" + log "github.com/sirupsen/logrus" + "io" + "net/url" + "time" +) + +type Service struct { + client *minio.Client +} + +func newService(client *minio.Client) *Service { + return &Service{ + client: client, + } +} + +func (s *Service) СreateBucketIfNotExists(bucketName string) error { + ctx := context.Background() + err := s.client.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{}) + if err != nil { + var minioErr minio.ErrorResponse + if errors.As(err, &minioErr) { + if minioErr.Code == "BucketAlreadyExists" || minioErr.Code == "BucketAlreadyOwnedByYou" { + log.Infof("Media storage | Bucket %s already exists, skipping creation", bucketName) + return nil + } + } + return fmt.Errorf("failed to create bucket: %w", err) + } + log.Infof("Media storage | Bucket %s created successfully", bucketName) + return nil +} + +func (s *Service) Upload(ctx context.Context, bucket, object string, reader io.Reader, size int64) error { + _, err := s.client.PutObject(ctx, bucket, object, reader, size, minio.PutObjectOptions{ContentType: "image/jpeg"}) + return err +} + +func (s *Service) Get(ctx context.Context, bucket, object string, expires time.Duration, params url.Values) (*url.URL, error) { + return s.client.PresignedGetObject(ctx, bucket, object, expires, params) +} + +func (s *Service) Delete(ctx context.Context, bucket, object string) error { + return s.client.RemoveObject(ctx, bucket, object, minio.RemoveObjectOptions{}) +}