feat(12.2-01): add deferred bindings, guarded upload store and purge
- deferred_bindings migration set under summercms.deferred with backend_user_id - lagoon.DeferredBind/Unbind/Bindings/Forget/Slaves scoped by DeferredKey - lagoon.PurgeDeferred with SKIP LOCKED batches and after-commit blob deletes - attach.Store with the ported image guard, extension and MIME limits - attach.Relation, attach.HasRelations, attach.BlobKeys, File.ThumbKey - lagoon README and attachments docs
This commit is contained in:
@@ -126,6 +126,19 @@ var encodeImage = defaultEncodeImage
|
||||
|
||||
// Thumb returns the public URL of a lazily generated thumbnail. The second
|
||||
// call for the same dimensions hits the existing blob and does not resize.
|
||||
// It is PublicURL of ThumbKey; see ThumbKey for the generation rules.
|
||||
func (f *File) Thumb(ctx context.Context, bucket *blob.Bucket, w, h int, mode string) (string, error) {
|
||||
key, err := f.ThumbKey(ctx, bucket, w, h, mode)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return PublicURL(key), nil
|
||||
}
|
||||
|
||||
// ThumbKey returns the blob key of a lazily generated thumbnail, generating
|
||||
// it on first use, so a caller that must not emit a public URL (a protected
|
||||
// file) can stream the thumbnail itself. The second call for the same
|
||||
// dimensions hits the existing blob and does not resize.
|
||||
//
|
||||
// As WinterCMS's File::makeThumb does, an original that is missing from
|
||||
// the bucket, does not decode, or declares more than 4096 by 4096 pixels
|
||||
@@ -133,7 +146,7 @@ var encodeImage = defaultEncodeImage
|
||||
// thumbnail, and the failure is logged at warn level instead of returned:
|
||||
// one unusable upload never fails the listings that show it. An invalid
|
||||
// mode or size, a storage error and an encode failure are still errors.
|
||||
func (f *File) Thumb(ctx context.Context, bucket *blob.Bucket, w, h int, mode string) (string, error) {
|
||||
func (f *File) ThumbKey(ctx context.Context, bucket *blob.Bucket, w, h int, mode string) (string, error) {
|
||||
if f == nil {
|
||||
return "", fmt.Errorf("attach: file is nil")
|
||||
}
|
||||
@@ -162,7 +175,7 @@ func (f *File) Thumb(ctx context.Context, bucket *blob.Bucket, w, h int, mode st
|
||||
return "", fmt.Errorf("attach: thumb exists: %w", err)
|
||||
}
|
||||
if exists {
|
||||
return PublicURL(thumbKey), nil
|
||||
return thumbKey, nil
|
||||
}
|
||||
origKey := part + f.DiskName
|
||||
r, err := bucket.NewReader(ctx, origKey, nil)
|
||||
@@ -219,7 +232,7 @@ func (f *File) Thumb(ctx context.Context, bucket *blob.Bucket, w, h int, mode st
|
||||
}
|
||||
return "", closeErr
|
||||
}
|
||||
return PublicURL(thumbKey), nil
|
||||
return thumbKey, nil
|
||||
}
|
||||
|
||||
var errOriginalTooLarge = errors.New("original image is too large")
|
||||
@@ -239,12 +252,12 @@ var BrokenImagePNG = func() []byte {
|
||||
}()
|
||||
|
||||
// brokenThumb is the catch branch of WinterCMS's File::makeThumb: log the
|
||||
// reason, store BrokenImagePNG under the thumbnail key and return its URL.
|
||||
// reason, store BrokenImagePNG under the thumbnail key and return that key.
|
||||
func brokenThumb(ctx context.Context, bucket *blob.Bucket, f *File, thumbKey string, reason error) (string, error) {
|
||||
slog.Default().WarnContext(ctx, "attach: thumbnail original is unusable, storing the broken-image picture",
|
||||
slog.Uint64("file_id", uint64(f.ID)), slog.String("error", reason.Error()))
|
||||
if err := bucket.WriteAll(ctx, thumbKey, BrokenImagePNG, &blob.WriterOptions{ContentType: "image/png"}); err != nil {
|
||||
return "", fmt.Errorf("attach: broken-image thumb: %w", err)
|
||||
}
|
||||
return PublicURL(thumbKey), nil
|
||||
return thumbKey, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user