Files

65 lines
1.8 KiB
Go

package storage
import (
"context"
"fmt"
"io"
"net/url"
"strings"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/sundynix/pets-be/internal/config"
)
type Storage struct {
client *minio.Client
bucket string
baseURL string
}
func New(cfg config.MinIOConfig) (*Storage, error) {
endpoint, secure := cfg.Endpoint, cfg.UseSSL
if strings.Contains(endpoint, "://") {
parsed, err := url.Parse(endpoint)
if err != nil || parsed.Host == "" || (parsed.Scheme != "http" && parsed.Scheme != "https") || parsed.Path != "" {
return nil, fmt.Errorf("invalid minio endpoint %q", cfg.Endpoint)
}
endpoint, secure = parsed.Host, parsed.Scheme == "https"
}
client, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(cfg.AccessKey, cfg.SecretKey, ""),
Secure: secure,
})
if err != nil {
return nil, fmt.Errorf("init minio: %w", err)
}
scheme := "http"
if secure {
scheme = "https"
}
s := &Storage{client: client, bucket: cfg.Bucket, baseURL: scheme + "://" + endpoint}
return s, nil
}
func (s *Storage) Bucket() string { return s.bucket }
func (s *Storage) Put(ctx context.Context, key string, reader io.Reader, size int64, contentType string) error {
_, err := s.client.PutObject(ctx, s.bucket, key, reader, size, minio.PutObjectOptions{ContentType: contentType})
return err
}
func (s *Storage) Remove(ctx context.Context, key string) error {
return s.client.RemoveObject(ctx, s.bucket, key, minio.RemoveObjectOptions{})
}
// PublicURL builds the URL stored on the file row; other models only store file IDs.
func (s *Storage) PublicURL(key string) string {
parts := strings.Split(key, "/")
for i, part := range parts {
parts[i] = url.PathEscape(part)
}
return s.baseURL + "/" + url.PathEscape(s.bucket) + "/" + strings.Join(parts, "/")
}