Move Spaces FromEnv into blob; Upload takes Object; drop logSpaces.

This commit is contained in:
2026-08-21 23:48:18 -07:00
parent 3eb75cfd80
commit a36bc723cc
4 changed files with 45 additions and 39 deletions
+29 -8
View File
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
"os"
"strings"
"github.com/aws/aws-sdk-go-v2/aws"
@@ -15,7 +16,15 @@ import (
// Uploader stores public avatar objects.
type Uploader interface {
Enabled() bool
Upload(ctx context.Context, key string, body io.Reader, contentType string, size int64) (publicURL string, err error)
Upload(ctx context.Context, obj Object) (publicURL string, err error)
}
// Object is a file to upload to object storage.
type Object struct {
Key string
Body io.Reader
ContentType string
Size int64
}
// Disabled is a no-op uploader used when Spaces is not configured.
@@ -38,10 +47,22 @@ type spaces struct {
func (Disabled) Enabled() bool { return false }
func (Disabled) Upload(context.Context, string, io.Reader, string, int64) (string, error) {
func (Disabled) Upload(context.Context, Object) (string, error) {
return "", fmt.Errorf("avatar uploads are not configured")
}
// FromEnv builds an Uploader from SPACES_* environment variables.
func FromEnv() Uploader {
return NewSpaces(SpacesConfig{
Key: os.Getenv("SPACES_KEY"),
Secret: os.Getenv("SPACES_SECRET"),
Region: os.Getenv("SPACES_REGION"),
Bucket: os.Getenv("SPACES_BUCKET"),
Endpoint: os.Getenv("SPACES_ENDPOINT"),
CDNBase: os.Getenv("SPACES_CDN_BASE"),
})
}
// NewSpaces returns an Uploader when required env is present; otherwise Disabled.
func NewSpaces(cfg SpacesConfig) Uploader {
cfg.Key = strings.TrimSpace(cfg.Key)
@@ -63,17 +84,17 @@ func NewSpaces(cfg SpacesConfig) Uploader {
func (s *spaces) Enabled() bool { return true }
func (s *spaces) Upload(ctx context.Context, key string, body io.Reader, contentType string, size int64) (string, error) {
key = strings.TrimPrefix(key, "/")
func (s *spaces) Upload(ctx context.Context, obj Object) (string, error) {
key := strings.TrimPrefix(obj.Key, "/")
input := &s3.PutObjectInput{
Bucket: aws.String(s.cfg.Bucket),
Key: aws.String(key),
Body: body,
ContentType: aws.String(contentType),
Body: obj.Body,
ContentType: aws.String(obj.ContentType),
ACL: types.ObjectCannedACLPublicRead,
}
if size > 0 {
input.ContentLength = aws.Int64(size)
if obj.Size > 0 {
input.ContentLength = aws.Int64(obj.Size)
}
if _, err := s.client.PutObject(ctx, input); err != nil {
return "", err