weiro/services/publisher/service.go

129 lines
2.9 KiB
Go
Raw Permalink Normal View History

2026-02-19 11:29:44 +00:00
package publisher
import (
"context"
"io"
2026-03-05 11:04:24 +00:00
"iter"
2026-02-19 11:29:44 +00:00
"log"
2026-02-20 06:39:58 +00:00
"os"
2026-02-19 11:29:44 +00:00
2026-02-20 06:39:58 +00:00
"emperror.dev/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/netlify/open-api/v2/go/porcelain"
netlify_ctx "github.com/netlify/open-api/v2/go/porcelain/context"
2026-02-19 11:29:44 +00:00
"lmika.dev/lmika/weiro/layouts/simplecss"
"lmika.dev/lmika/weiro/models"
"lmika.dev/lmika/weiro/models/pubmodel"
"lmika.dev/lmika/weiro/providers/db"
"lmika.dev/lmika/weiro/providers/sitebuilder"
"lmika.dev/lmika/weiro/providers/siteexporter"
"lmika.dev/lmika/weiro/providers/uploadfiles"
2026-02-19 11:29:44 +00:00
)
type Publisher struct {
db *db.Provider
up *uploadfiles.Provider
2026-02-19 11:29:44 +00:00
}
func New(db *db.Provider, up *uploadfiles.Provider) *Publisher {
2026-02-19 11:29:44 +00:00
return &Publisher{
db: db,
up: up,
2026-02-19 11:29:44 +00:00
}
}
func (p *Publisher) Publish(ctx context.Context, site models.Site) error {
targets, err := p.db.SelectPublishTargetsOfSite(ctx, site.ID)
2026-02-19 11:29:44 +00:00
if err != nil {
return err
}
// Fetch all uploads of site
uploads, err := p.db.SelectUploadsOfSite(ctx, site.ID)
if err != nil {
return err
}
2026-02-19 11:29:44 +00:00
for _, target := range targets {
if !target.Enabled {
continue
}
2026-02-19 11:29:44 +00:00
pubSite := pubmodel.Site{
2026-03-05 11:04:24 +00:00
Site: site,
PostIter: func(ctx context.Context) iter.Seq[models.Maybe[*models.Post]] {
return p.postIter(ctx, site.ID)
},
2026-02-19 11:29:44 +00:00
BaseURL: target.BaseURL,
Uploads: uploads,
OpenUpload: func(u models.Upload) (io.ReadCloser, error) {
return p.up.OpenUpload(site, u)
},
2026-02-19 11:29:44 +00:00
}
if err := p.publishSite(ctx, pubSite, target); err != nil {
return err
}
}
return nil
}
func (p *Publisher) publishSite(ctx context.Context, pubSite pubmodel.Site, target models.SitePublishTarget) error {
sb, err := sitebuilder.New(pubSite, sitebuilder.Options{
BasePosts: "/posts",
TemplatesFS: simplecss.FS,
2026-03-05 11:04:24 +00:00
FeedItems: 30,
2026-02-19 11:29:44 +00:00
})
if err != nil {
return err
}
switch target.TargetType {
case "export":
exporter := siteexporter.New(pubSite.Site, target.BaseURL, target.TargetRef)
if err := exporter.WriteSiteYAML(); err != nil {
return err
}
2026-03-05 11:04:24 +00:00
for mp := range pubSite.PostIter(ctx) {
p, err := mp.Get()
if err != nil {
return err
}
if err := exporter.WritePost(p); err != nil {
return err
}
}
return nil
2026-02-20 06:39:58 +00:00
case "localfs":
2026-02-19 11:29:44 +00:00
log.Printf("Building site at %s", target.TargetRef)
return sb.BuildSite(target.TargetRef)
2026-02-20 06:39:58 +00:00
case "netlify":
return func() error {
tmpDir, err := os.MkdirTemp("", "weiro-publish")
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
if err := sb.BuildSite(tmpDir); err != nil {
return err
}
ctx = netlify_ctx.WithAuthInfo(ctx, runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
return r.SetHeaderParam("Authorization", "Bearer "+target.TargetKey)
}))
client := porcelain.Default
_, err = client.DeploySite(ctx, porcelain.DeployOptions{
SiteID: target.TargetRef,
Dir: tmpDir,
})
return err
}()
2026-02-19 11:29:44 +00:00
}
2026-02-20 06:39:58 +00:00
return errors.New("unknown target type")
2026-02-19 11:29:44 +00:00
}