65 lines
1.8 KiB
Go
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, "/")
|
|
}
|