Files
sm-seo-plugin/commands.go

87 lines
2.8 KiB
Go

package seo
import (
"context"
"fmt"
"strings"
"git.golem15.com/golem15/sm-seo-plugin/classes"
"git.golem15.com/golem15/summercms/modules/bonfire"
"git.golem15.com/golem15/summercms/modules/lagoon"
"git.golem15.com/golem15/summercms/modules/pact"
"gorm.io/gorm"
)
// Commands registers seo:generate-entries.
func (p *Plugin) Commands() []bonfire.Command {
return []bonfire.Command{{
Name: "seo:generate-entries",
Description: "Queue the job that creates missing SEO entries",
Long: `Queues the entry generation job on the background queue. The job walks the
published records of every content type registered in signpost (or of the
one named by --type), creates the missing SEO entry of each locale with its
current address and refreshes the address and the effective title and
description of existing entries. Values set in the SEO tab are never
changed. A worker (summer serve or queue:work) runs the job.`,
Flags: []bonfire.Flag{
{Name: "type", Description: "Content type key (signpost menu item type) to limit the run to"},
},
Examples: []bonfire.Example{
{Command: "seo:generate-entries", Description: "Queue generation for every content type"},
{Command: "seo:generate-entries --type journal-post", Description: "Queue generation for one content type"},
},
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
typeKey, _ := in.Flag("type")
typeKey = strings.TrimSpace(typeKey)
svc := p.Service()
if svc == nil {
return classes.ErrNotBooted
}
if typeKey != "" {
if reg := svc.Registry(); reg != nil {
if _, ok := reg.ContentType(typeKey); !ok {
return fmt.Errorf("Content type %q is not registered", typeKey)
}
}
}
db, done, err := p.commandDB(ctx)
if err != nil {
return err
}
defer done()
id, err := svc.EnqueueGenerate(ctx, db, typeKey)
if err != nil {
return err
}
out.Success(fmt.Sprintf("Queued SEO entry generation (job #%d).", id))
return nil
},
}}
}
// commandDB returns the app database, opening database.dsn when the binary
// published none for console commands. done closes a pool it opened.
func (p *Plugin) commandDB(ctx context.Context) (*gorm.DB, func(), error) {
app := p.app
if app == nil {
return nil, nil, classes.ErrNotBooted
}
if db, ok := app.Lookup[*gorm.DB](); ok && db != nil {
return db, func() {}, nil
}
if lagoon.DSN(app.Config) == "" {
return nil, nil, fmt.Errorf("golem15.seo: database is not configured (set SUMMER_DATABASE__DSN)")
}
sqlDB, gdb, err := lagoon.OpenFromApp(ctx, app)
if err != nil {
return nil, nil, err
}
if err := lagoon.Publish(app, sqlDB, gdb); err != nil {
_ = sqlDB.Close()
return nil, nil, err
}
return gdb, func() { _ = sqlDB.Close() }, nil
}
var _ pact.HasCommands = (*Plugin)(nil)