Files

103 lines
2.4 KiB
Go
Raw Permalink Normal View History

package objectstorage
import (
"context"
"fmt"
"net/url"
"path/filepath"
"strings"
"time"
"img_infinite_canvas/internal/domain/design"
"github.com/google/uuid"
)
type MemoryStorage struct {
bucket string
publicBase string
expiresIn int64
}
func NewMemoryStorage(bucket string, publicBase string, expiresIn int64) *MemoryStorage {
if bucket == "" {
bucket = "memory-assets"
}
if expiresIn <= 0 {
expiresIn = 900
}
return &MemoryStorage{
bucket: bucket,
publicBase: strings.TrimRight(publicBase, "/"),
expiresIn: expiresIn,
}
}
func (s *MemoryStorage) CreateUpload(ctx context.Context, req design.AssetUploadRequest) (design.AssetUpload, error) {
if err := ctx.Err(); err != nil {
return design.AssetUpload{}, err
}
objectKey := objectKey(req.FileName)
publicURL := fmt.Sprintf("/memory-assets/%s", escapeObjectPath(objectKey))
if s.publicBase != "" {
publicURL = publicObjectURL(s.publicBase, objectKey)
}
return design.AssetUpload{
Driver: "memory",
Bucket: s.bucket,
ObjectKey: objectKey,
UploadURL: publicURL + "?upload=1",
PublicURL: publicURL,
Headers: map[string]string{
"Content-Type": req.ContentType,
},
ExpiresIn: s.expiresIn,
}, nil
}
func (s *MemoryStorage) PutObject(ctx context.Context, req design.AssetObjectRequest) (design.AssetObject, error) {
if err := ctx.Err(); err != nil {
return design.AssetObject{}, err
}
objectKey := objectKey(req.FileName)
publicURL := fmt.Sprintf("/memory-assets/%s", escapeObjectPath(objectKey))
if s.publicBase != "" {
publicURL = publicObjectURL(s.publicBase, objectKey)
}
return design.AssetObject{
Driver: "memory",
Bucket: s.bucket,
ObjectKey: objectKey,
PublicURL: publicURL,
}, nil
}
func (s *MemoryStorage) DeleteObject(ctx context.Context, publicURL string) error {
return ctx.Err()
}
func objectKey(fileName string) string {
ext := filepath.Ext(fileName)
return time.Now().UTC().Format("2006/01/02") + "/" + uuid.NewString() + ext
}
func publicObjectURL(publicBase string, objectKey string) string {
publicBase = strings.TrimRight(publicBase, "/")
if publicBase == "" {
return ""
}
return publicBase + "/" + escapeObjectPath(objectKey)
}
func escapeObjectPath(objectKey string) string {
parts := strings.Split(objectKey, "/")
for index, part := range parts {
parts[index] = url.PathEscape(part)
}
return strings.Join(parts, "/")
}