package main import ( "bytes" "context" "flag" "fmt" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/encryptcookie" "github.com/gofiber/fiber/v3/middleware/static" "github.com/gofiber/template/html/v2" "github.com/yuin/goldmark" "html/template" "lmika.dev/lmika/hugo-cms/assets" "lmika.dev/lmika/hugo-cms/config" "lmika.dev/lmika/hugo-cms/handlers" "lmika.dev/lmika/hugo-cms/providers/bus" "lmika.dev/lmika/hugo-cms/providers/db" "lmika.dev/lmika/hugo-cms/providers/git" "lmika.dev/lmika/hugo-cms/providers/hugo" "lmika.dev/lmika/hugo-cms/providers/netlify" "lmika.dev/lmika/hugo-cms/providers/themes" "lmika.dev/lmika/hugo-cms/services/jobs" "lmika.dev/lmika/hugo-cms/services/pages" "lmika.dev/lmika/hugo-cms/services/posts" "lmika.dev/lmika/hugo-cms/services/sitebuilder" "lmika.dev/lmika/hugo-cms/services/sites" "lmika.dev/lmika/hugo-cms/services/users" "lmika.dev/lmika/hugo-cms/templates" "log" "net/http" ) func main() { flagGenKey := flag.Bool("gen-key", false, "Generate a new key") flagUser := flag.String("user", "", "add new user") flagPassword := flag.String("password", "", "add new password") flag.Parse() if *flagGenKey { fmt.Println(encryptcookie.GenerateKey(32)) return } cfg, err := config.Load() if err != nil { log.Fatal(err) } dbp, err := db.New(cfg.DatabaseURL) if err != nil { log.Fatal(err) } defer dbp.Close() log.Println("Connected to database") if err := dbp.Migrate(context.Background()); err != nil { log.Fatal(err) } log.Println("Database migrated") userService := users.NewService(dbp) if *flagUser != "" { if _, err := userService.AddUser(context.Background(), users.NewUser{ Email: *flagUser, Password: *flagPassword, }); err != nil { log.Fatal(err) } log.Println("User added") return } hugoProvider, err := hugo.New(cfg.StagingDir(), cfg.BaseURL, cfg.PreviewDir(), cfg.ScratchDir()) if err != nil { log.Fatal(err) } gitProvider := git.New() themesProvider := themes.New() netlifyProvider := netlify.New(cfg.NetlifyAuthToken) bus := bus.New() jobService := jobs.New() siteBuilderService := sitebuilder.New(dbp, themesProvider, gitProvider, hugoProvider, netlifyProvider, bus) siteService := sites.NewService(cfg, dbp, themesProvider, siteBuilderService, jobService) postService := posts.New(dbp, siteBuilderService, jobService) pageService := pages.New(dbp, siteBuilderService, jobService) indexHandlers := handlers.IndexHandler{} siteHandlers := handlers.Site{Site: siteService, Bus: bus} postHandlers := handlers.Post{Post: postService} pageHandlers := handlers.Pages{Svc: pageService} authHandlers := handlers.AuthHandler{UserService: userService} tmplEngine := html.NewFileSystem(http.FS(templates.FS), ".html") tmplEngine.Funcmap["markdown"] = func(s string) (template.HTML, error) { var buf bytes.Buffer if err := goldmark.Convert([]byte(s), &buf); err != nil { return "", err } return template.HTML(buf.String()), nil } if cfg.EncryptedCookieKey == "" { log.Println("No encrypt cookie key defined. Generating random key") cfg.EncryptedCookieKey = encryptcookie.GenerateKey(32) } bus.Start() defer bus.Stop() app := fiber.New(fiber.Config{ Views: tmplEngine, PassLocalsToViews: true, }) app.Use(encryptcookie.New(encryptcookie.Config{Key: cfg.EncryptedCookieKey})) app.Use("/assets", static.New("", static.Config{ FS: assets.FS, })) app.Get("/auth/login", authHandlers.ShowLogin) app.Post("/auth/login", authHandlers.Login) app.Use(authHandlers.RequireAuth) app.Get("/", indexHandlers.Index) app.Post("/sites", siteHandlers.Create) app.Get("/sites/:siteId", siteHandlers.Show) app.Use("/preview", static.New(cfg.PreviewDir(), static.Config{ Browse: true, })) sr := app.Group("/sites/:siteId") sr.Use(siteHandlers.WithSite()) sr.Post("/rebuild", siteHandlers.Rebuild) sr.Get("/posts", postHandlers.Posts) sr.Get("/posts/new", postHandlers.New) sr.Post("/posts", postHandlers.Create) sr.Get("/posts/:postId", postHandlers.Edit) sr.Post("/posts/:postId", postHandlers.Update) sr.Delete("/posts/:postId", postHandlers.Delete) sr.Get("/pages", pageHandlers.Index) sr.Get("/pages/new", pageHandlers.New) sr.Post("/pages", pageHandlers.Create) sr.Get("/pages/:pageId", pageHandlers.Edit) sr.Post("/pages/:pageId", pageHandlers.Update) sr.Delete("/pages/:pageId", pageHandlers.Delete) sr.Get("/settings", siteHandlers.Settings) sr.Post("/settings", siteHandlers.SaveSettings) sr.Get("/sse", siteHandlers.SSE) jobService.Start() defer jobService.Stop() if err := app.Listen(":3000"); err != nil { log.Println(err) } log.Println("Shutting down...") }