package sites import ( "context" "errors" "lmika.dev/lmika/hugo-crm/config" "lmika.dev/lmika/hugo-crm/models" "lmika.dev/lmika/hugo-crm/providers/db" "lmika.dev/lmika/hugo-crm/providers/git" "lmika.dev/lmika/hugo-crm/providers/hugo" "lmika.dev/lmika/hugo-crm/providers/themes" "log" "strings" "unicode" ) type Service struct { cfg config.Config db *db.DB themes *themes.Provider git *git.Provider hugo *hugo.Provider } func NewService( cfg config.Config, db *db.DB, themes *themes.Provider, git *git.Provider, hugo *hugo.Provider, ) *Service { return &Service{ cfg: cfg, db: db, git: git, hugo: hugo, } } func (s *Service) CreateSite(ctx context.Context, name string) (models.Site, error) { newSite := models.Site{ Name: normaliseName(name), Title: name, Theme: "bear", } themeMeta, ok := s.themes.Lookup(newSite.Theme) if !ok { return models.Site{}, errors.New("theme not found") } if err := s.db.InsertSite(ctx, &newSite); err != nil { return models.Site{}, err } // Build the site log.Printf(" .. build") if err := s.hugo.NewSite(ctx, newSite); err != nil { return models.Site{}, err } // Setup the theme log.Printf(" .. theme") if err := s.git.Clone(ctx, themeMeta.URL, s.hugo.SiteStagingDir(newSite, hugo.ThemeSiteDir)); err != nil { return models.Site{}, err } if err := s.hugo.ReconfigureSite(ctx, newSite); err != nil { return models.Site{}, err } return newSite, nil } 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() }