package publisher import ( "context" "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" ) type Publisher struct { db *db.Provider } func New(db *db.Provider) *Publisher { return &Publisher{ db: db, } } func (p *Publisher) Publish(ctx context.Context, siteID int64) error { // Fetch site, ensure user is owner site, err := p.db.SelectSiteByID(ctx, siteID) if err != nil { return err } user, ok := models.GetUser(ctx) if !ok { return models.UserRequiredError } else if user.ID != site.OwnerID { return models.PermissionError } targets, err := p.db.SelectPublishTargetsOfSite(ctx, siteID) if err != nil { return err } // Fetch all content of site posts, err := p.db.SelectPostsOfSite(ctx, siteID) if err != nil { return err } for _, target := range targets { pubSite := pubmodel.Site{ Site: site, Posts: posts, BaseURL: target.BaseURL, } 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 "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") }