Add photo content-hash dedup and local↔S3 library sync.
Uploads skip per-gallery duplicates, checksums can be backfilled, and STORAGE_BACKEND plus sync tooling make switching storage backends safe.
This commit is contained in:
@@ -7,6 +7,7 @@ package storage
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
@@ -17,16 +18,30 @@ import (
|
||||
// callers then stream the object through the API instead.
|
||||
var ErrNoPresign = errors.New("presigned URLs not supported")
|
||||
|
||||
// ErrNotExist is what Stat reports for a missing object on either backend.
|
||||
var ErrNotExist = errors.New("object does not exist")
|
||||
|
||||
type Storage interface {
|
||||
Put(ctx context.Context, key string, r io.Reader, size int64, contentType string) error
|
||||
Open(ctx context.Context, key string) (io.ReadCloser, int64, error)
|
||||
// Stat returns the object's size without reading it, or ErrNotExist.
|
||||
Stat(ctx context.Context, key string) (int64, error)
|
||||
Delete(ctx context.Context, key string) error
|
||||
PresignGet(ctx context.Context, key, downloadFilename, contentType string, expiry time.Duration) (string, error)
|
||||
}
|
||||
|
||||
// New builds the backend that serves requests (see config.S3Enabled).
|
||||
func New(cfg config.Config) (Storage, error) {
|
||||
if cfg.S3Enabled() {
|
||||
return newS3(cfg)
|
||||
return NewS3(cfg)
|
||||
}
|
||||
return newLocal(cfg.StoragePath)
|
||||
return NewLocal(cfg.StoragePath)
|
||||
}
|
||||
|
||||
// Name describes a backend for log lines.
|
||||
func Name(cfg config.Config, s Storage) string {
|
||||
if _, ok := s.(*s3Store); ok {
|
||||
return fmt.Sprintf("S3 bucket %s at %s", cfg.S3Bucket, cfg.S3Endpoint)
|
||||
}
|
||||
return fmt.Sprintf("local disk at %s", cfg.StoragePath)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user