hugo-cms/services/sites/service.go

147 lines
3.5 KiB
Go
Raw Normal View History

2025-01-26 22:26:15 +00:00
package sites
import (
"context"
"errors"
"github.com/jackc/pgx/v5"
2025-01-27 10:48:40 +00:00
"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"
2025-01-26 22:26:15 +00:00
"strings"
"unicode"
)
type Service struct {
cfg config.Config
db *db.DB
themes *themes.Provider
2025-01-26 23:19:31 +00:00
sb *sitebuilder.Service
jobs *jobs.Service
2025-01-26 22:26:15 +00:00
}
func NewService(
cfg config.Config,
db *db.DB,
themes *themes.Provider,
2025-01-26 23:19:31 +00:00
sb *sitebuilder.Service,
jobs *jobs.Service,
2025-01-26 22:26:15 +00:00
) *Service {
return &Service{
2025-01-26 23:19:31 +00:00
cfg: cfg,
db: db,
themes: themes,
sb: sb,
jobs: jobs,
2025-01-26 22:26:15 +00:00
}
}
2025-01-26 23:19:31 +00:00
func (s *Service) GetSite(ctx context.Context, id int) (models.Site, error) {
return s.db.GetSite(ctx, int64(id))
}
2025-01-31 23:56:59 +00:00
func (s *Service) GetProdTargetOfSite(ctx context.Context, siteID int) (models.PublishTarget, error) {
return s.db.GetPublishTargetBySiteRole(ctx, int64(siteID), models.TargetRoleProduction)
}
2025-01-31 22:42:32 +00:00
func (s *Service) CreateSite(ctx context.Context, user models.User, name string) (models.Site, error) {
2025-01-26 22:26:15 +00:00
newSite := models.Site{
2025-01-31 22:42:32 +00:00
Name: normaliseName(name),
OwnerUserID: user.ID,
Title: name,
Theme: "bear",
2025-02-01 22:54:30 +00:00
//Theme: "yingyang",
2025-01-26 22:26:15 +00:00
}
2025-01-26 23:19:31 +00:00
_, ok := s.themes.Lookup(newSite.Theme)
2025-01-26 22:26:15 +00:00
if !ok {
return models.Site{}, errors.New("theme not found")
}
if err := s.db.InsertSite(ctx, &newSite); err != nil {
return models.Site{}, err
}
2025-01-26 23:19:31 +00:00
return newSite, s.jobs.Queue(ctx, s.sb.CreateNewSite(newSite))
2025-01-26 22:26:15 +00:00
}
2025-02-01 22:54:30 +00:00
func (s *Service) SaveSettings(ctx context.Context, site models.Site, newSettings NewSettings) error {
_, ok := s.themes.Lookup(newSettings.SiteTheme)
2025-02-01 22:54:30 +00:00
if !ok {
return errors.New("theme not found")
}
newSite := site
newSite.Title = newSettings.SiteTitle
2025-02-01 22:54:30 +00:00
newSite.Name = normaliseName(newSite.Title)
newSite.Theme = newSettings.SiteTheme
2025-02-01 22:54:30 +00:00
if err := s.db.UpdateSite(ctx, newSite); err != nil {
return err
}
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
}
2025-02-01 22:54:30 +00:00
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"`
2025-02-01 22:54:30 +00:00
}
2025-01-27 04:45:53 +00:00
func (s *Service) Rebuild(ctx context.Context, site models.Site) error {
if site.ID == 0 {
return errors.New("site id required")
}
2025-02-01 22:54:30 +00:00
return s.jobs.Queue(ctx, s.sb.RebuildSite(site, site))
}
func (s *Service) Themes() []models.ThemeMeta {
return s.themes.Themes()
2025-01-27 04:45:53 +00:00
}
2025-01-26 22:26:15 +00:00
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()
}