feat: image variants job and variants in the post API
- golem15_journal_image_variants (migration 202610280002): a thumbnail
per width of golem15.journal.image_widths (480, 800, 1200 by default,
never wider than the original) and its WebP copy, with the original's
size
- conga job golem15.journal.image_variants (three attempts), queued after
a featured image upload and after an admin save of a post whose images
lack a width; the upload request never encodes
- journal:image-variants [--all] backfills
- featured_images[].variants {width, height, url, webp_url, source_width,
source_height} on the post answers (additive key)
This commit is contained in:
67
console/image_variants.go
Normal file
67
console/image_variants.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package console
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.golem15.com/golem15/sm-journal-plugin/classes"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/bonfire"
|
||||
"gocloud.dev/blob"
|
||||
)
|
||||
|
||||
// ImageVariants is journal:image-variants: it writes the thumbnails and
|
||||
// WebP copies of the posts' featured images at golem15.journal.image_widths
|
||||
// in this process (the backfill of the golem15.journal.image_variants job).
|
||||
// Without --all it takes the images that lack a variant of some width.
|
||||
func ImageVariants(app *backpack.App) bonfire.Command {
|
||||
return bonfire.Command{
|
||||
Name: "journal:image-variants",
|
||||
Description: "Write the WebP and resized variants of featured images",
|
||||
Long: `Writes, for every post's featured image, a thumbnail at each width of
|
||||
golem15.journal.image_widths (480, 800 and 1200 by default) that is not
|
||||
wider than the original, and a WebP copy of each next to it, and records
|
||||
them in golem15_journal_image_variants. The Journal API lists them as
|
||||
featured_images[].variants and the journal layer serves them through
|
||||
<picture> with the original format as fallback.
|
||||
|
||||
New uploads get their variants from the golem15.journal.image_variants job,
|
||||
queued after the upload commits. This command is the backfill: without
|
||||
--all it takes the images that lack a variant of some width (for example
|
||||
after adding a width), with --all it checks every featured image. A
|
||||
variant that exists is never written again, so the command can run any
|
||||
number of times.`,
|
||||
Flags: []bonfire.Flag{
|
||||
{Name: "all", Description: "Check every featured image (default: only those missing a width)", Bare: true},
|
||||
},
|
||||
Examples: []bonfire.Example{
|
||||
{Command: "journal:image-variants", Description: "Write the variants images are missing"},
|
||||
{Command: "journal:image-variants --all", Description: "Check every featured image"},
|
||||
},
|
||||
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
||||
db := mustDB(app)
|
||||
if db == nil {
|
||||
return errors.New("journal: database is not configured")
|
||||
}
|
||||
bucket, ok := app.Lookup[*blob.Bucket]()
|
||||
if !ok || bucket == nil {
|
||||
return errors.New("journal: the uploads bucket is not configured")
|
||||
}
|
||||
ids, err := classes.FeaturedImageIDs(db.WithContext(ctx), appConfig(app), flagOn(in, "all"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
out.Info("Every featured image has its variants.")
|
||||
return nil
|
||||
}
|
||||
res, err := classes.GenerateImageVariants(ctx, db, bucket, classes.ImageWidths(appConfig(app)), ids)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.Success(fmt.Sprintf("Checked %d featured images, wrote %d variants, skipped %d.", res.Files, res.Written, res.Skipped))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user