128 lines
3 KiB
Go
128 lines
3 KiB
Go
package sites
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"github.com/jackc/pgx/v5"
|
|
"lmika.dev/lmika/hugo-cms/config"
|
|
"lmika.dev/lmika/hugo-cms/models"
|
|
"lmika.dev/lmika/hugo-cms/providers/db"
|
|
"lmika.dev/lmika/hugo-cms/providers/themes"
|
|
"lmika.dev/lmika/hugo-cms/services/jobs"
|
|
"lmika.dev/lmika/hugo-cms/services/sitebuilder"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
type Service struct {
|
|
cfg config.Config
|
|
db *db.DB
|
|
themes *themes.Provider
|
|
sb *sitebuilder.Service
|
|
jobs *jobs.Service
|
|
}
|
|
|
|
func NewService(
|
|
cfg config.Config,
|
|
db *db.DB,
|
|
themes *themes.Provider,
|
|
sb *sitebuilder.Service,
|
|
jobs *jobs.Service,
|
|
) *Service {
|
|
return &Service{
|
|
cfg: cfg,
|
|
db: db,
|
|
themes: themes,
|
|
sb: sb,
|
|
jobs: jobs,
|
|
}
|
|
}
|
|
|
|
func (s *Service) GetSite(ctx context.Context, id int) (models.Site, error) {
|
|
return s.db.GetSite(ctx, int64(id))
|
|
}
|
|
|
|
func (s *Service) GetProdTargetOfSite(ctx context.Context, siteID int) (models.PublishTarget, error) {
|
|
return s.db.GetPublishTargetBySiteRole(ctx, int64(siteID), models.TargetRoleProduction)
|
|
}
|
|
|
|
func (s *Service) SaveSettings(ctx context.Context, site models.Site, newSettings NewSettings) error {
|
|
_, ok := s.themes.Lookup(newSettings.SiteTheme)
|
|
if !ok {
|
|
return errors.New("theme not found")
|
|
}
|
|
|
|
newSite := site
|
|
newSite.Title = newSettings.SiteTitle
|
|
newSite.Name = normaliseName(newSite.Title)
|
|
newSite.Theme = newSettings.SiteTheme
|
|
|
|
if err := s.db.UpdateSite(ctx, newSite); err != nil {
|
|
return err
|
|
}
|
|
|
|
if newSettings.TargetRef != "" && newSettings.TargetURL != "" {
|
|
pubTarget, err := s.db.GetPublishTargetBySiteRole(ctx, newSite.ID, models.TargetRoleProduction)
|
|
if err == nil {
|
|
pubTarget.TargetRef = newSettings.TargetRef
|
|
pubTarget.URL = newSettings.TargetURL
|
|
if err := s.db.UpdatePublishTarget(ctx, pubTarget); err != nil {
|
|
return err
|
|
}
|
|
} else if errors.Is(err, pgx.ErrNoRows) {
|
|
pubTarget = models.PublishTarget{
|
|
SiteID: newSite.ID,
|
|
Role: models.TargetRoleProduction,
|
|
Type: models.TargetTypeNetlify,
|
|
URL: newSettings.TargetURL,
|
|
TargetRef: newSettings.TargetRef,
|
|
}
|
|
if err := s.db.InsertPublishTarget(ctx, &pubTarget); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return s.jobs.Queue(ctx, s.sb.RebuildSite(site, newSite))
|
|
}
|
|
|
|
type NewSettings struct {
|
|
SiteTitle string `form:"site_title"`
|
|
SiteTheme string `form:"site_theme"`
|
|
|
|
TargetURL string `form:"target_url"`
|
|
TargetRef string `form:"target_ref"`
|
|
}
|
|
|
|
func (s *Service) Rebuild(ctx context.Context, site models.Site) error {
|
|
if site.ID == 0 {
|
|
return errors.New("site id required")
|
|
}
|
|
|
|
return s.jobs.Queue(ctx, s.sb.RebuildSite(site, site))
|
|
}
|
|
|
|
func (s *Service) Themes() []models.ThemeMeta {
|
|
return s.themes.Themes()
|
|
}
|
|
|
|
func normaliseName(name string) string {
|
|
var sb strings.Builder
|
|
|
|
seenDash := false
|
|
for _, r := range strings.TrimSpace(name) {
|
|
if unicode.IsLetter(r) || unicode.IsNumber(r) {
|
|
sb.WriteRune(unicode.ToLower(r))
|
|
seenDash = false
|
|
} else if r == '_' || r == '-' || r == '.' || unicode.IsSpace(r) {
|
|
if !seenDash {
|
|
sb.WriteRune('-')
|
|
}
|
|
seenDash = true
|
|
}
|
|
}
|
|
return sb.String()
|
|
}
|