package publisher import ( "context" "io" "log" "os" "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" "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" ) type Publisher struct { db *db.Provider up *uploadfiles.Provider } func New(db *db.Provider, up *uploadfiles.Provider) *Publisher { return &Publisher{ db: db, up: up, } } func (p *Publisher) Publish(ctx context.Context, site models.Site) error { targets, err := p.db.SelectPublishTargetsOfSite(ctx, site.ID) if err != nil { return err } // Fetch all content of site posts, err := p.db.SelectPostsOfSite(ctx, site.ID, false) if err != nil { return err } // Fetch all uploads of site uploads, err := p.db.SelectUploadsOfSite(ctx, site.ID) if err != nil { return err } for _, target := range targets { if !target.Enabled { continue } pubSite := pubmodel.Site{ Site: site, Posts: posts, BaseURL: target.BaseURL, Uploads: uploads, OpenUpload: func(u models.Upload) (io.ReadCloser, error) { return p.up.OpenUpload(site, u) }, } 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, }) 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 } for _, p := range pubSite.Posts { if err := exporter.WritePost(p); err != nil { return err } } return nil case "localfs": log.Printf("Building site at %s", target.TargetRef) return sb.BuildSite(target.TargetRef) 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 }() } return errors.New("unknown target type") }