2025-01-26 20:39:19 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2025-01-27 10:45:54 +00:00
|
|
|
"bytes"
|
2025-01-26 20:39:19 +00:00
|
|
|
"context"
|
2025-01-31 22:42:32 +00:00
|
|
|
"flag"
|
|
|
|
"fmt"
|
2025-02-03 10:35:58 +00:00
|
|
|
"github.com/gofiber/fiber/v3"
|
|
|
|
"github.com/gofiber/fiber/v3/middleware/encryptcookie"
|
|
|
|
"github.com/gofiber/fiber/v3/middleware/static"
|
2025-01-26 23:19:31 +00:00
|
|
|
"github.com/gofiber/template/html/v2"
|
2025-01-27 10:45:54 +00:00
|
|
|
"github.com/yuin/goldmark"
|
|
|
|
"html/template"
|
2025-01-27 10:48:40 +00:00
|
|
|
"lmika.dev/lmika/hugo-cms/assets"
|
|
|
|
"lmika.dev/lmika/hugo-cms/config"
|
|
|
|
"lmika.dev/lmika/hugo-cms/handlers"
|
2025-02-03 11:23:48 +00:00
|
|
|
"lmika.dev/lmika/hugo-cms/providers/bus"
|
2025-01-27 10:48:40 +00:00
|
|
|
"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"
|
2025-02-16 00:43:22 +00:00
|
|
|
"lmika.dev/lmika/hugo-cms/services/pages"
|
2025-01-27 10:48:40 +00:00
|
|
|
"lmika.dev/lmika/hugo-cms/services/posts"
|
|
|
|
"lmika.dev/lmika/hugo-cms/services/sitebuilder"
|
|
|
|
"lmika.dev/lmika/hugo-cms/services/sites"
|
2025-01-31 22:42:32 +00:00
|
|
|
"lmika.dev/lmika/hugo-cms/services/users"
|
2025-01-27 10:48:40 +00:00
|
|
|
"lmika.dev/lmika/hugo-cms/templates"
|
2025-01-26 20:39:19 +00:00
|
|
|
"log"
|
2025-01-26 23:19:31 +00:00
|
|
|
"net/http"
|
2025-01-26 20:39:19 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
2025-01-31 22:42:32 +00:00
|
|
|
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 {
|
2025-02-03 10:35:58 +00:00
|
|
|
fmt.Println(encryptcookie.GenerateKey(32))
|
2025-01-31 22:42:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2025-01-26 22:26:15 +00:00
|
|
|
cfg, err := config.Load()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
dbp, err := db.New(cfg.DatabaseURL)
|
2025-01-26 20:39:19 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
defer dbp.Close()
|
|
|
|
|
2025-02-01 00:04:32 +00:00
|
|
|
log.Println("Connected to database")
|
|
|
|
if err := dbp.Migrate(context.Background()); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
log.Println("Database migrated")
|
|
|
|
|
2025-01-31 22:42:32 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2025-02-18 10:26:24 +00:00
|
|
|
hugoProvider, err := hugo.New(cfg.StagingDir(), cfg.BaseURL, cfg.PreviewDir(), cfg.ScratchDir())
|
2025-01-26 22:26:15 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
gitProvider := git.New()
|
|
|
|
themesProvider := themes.New()
|
2025-01-27 04:45:53 +00:00
|
|
|
netlifyProvider := netlify.New(cfg.NetlifyAuthToken)
|
2025-02-03 11:23:48 +00:00
|
|
|
bus := bus.New()
|
2025-01-26 22:26:15 +00:00
|
|
|
|
2025-01-26 23:19:31 +00:00
|
|
|
jobService := jobs.New()
|
2025-02-03 11:23:48 +00:00
|
|
|
siteBuilderService := sitebuilder.New(dbp, themesProvider, gitProvider, hugoProvider, netlifyProvider, bus)
|
2025-01-26 23:19:31 +00:00
|
|
|
|
|
|
|
siteService := sites.NewService(cfg, dbp, themesProvider, siteBuilderService, jobService)
|
2025-01-27 03:23:54 +00:00
|
|
|
postService := posts.New(dbp, siteBuilderService, jobService)
|
2025-02-16 00:43:22 +00:00
|
|
|
pageService := pages.New(dbp, siteBuilderService, jobService)
|
2025-01-26 23:19:31 +00:00
|
|
|
|
2025-01-31 23:56:59 +00:00
|
|
|
indexHandlers := handlers.IndexHandler{}
|
2025-02-03 11:23:48 +00:00
|
|
|
siteHandlers := handlers.Site{Site: siteService, Bus: bus}
|
2025-01-27 03:23:54 +00:00
|
|
|
postHandlers := handlers.Post{Post: postService}
|
2025-02-16 00:43:22 +00:00
|
|
|
pageHandlers := handlers.Pages{Svc: pageService}
|
2025-01-31 22:42:32 +00:00
|
|
|
authHandlers := handlers.AuthHandler{UserService: userService}
|
2025-01-26 22:26:15 +00:00
|
|
|
|
2025-01-26 23:19:31 +00:00
|
|
|
tmplEngine := html.NewFileSystem(http.FS(templates.FS), ".html")
|
2025-01-27 10:45:54 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2025-01-31 22:42:32 +00:00
|
|
|
if cfg.EncryptedCookieKey == "" {
|
|
|
|
log.Println("No encrypt cookie key defined. Generating random key")
|
2025-02-03 10:35:58 +00:00
|
|
|
cfg.EncryptedCookieKey = encryptcookie.GenerateKey(32)
|
2025-01-31 22:42:32 +00:00
|
|
|
}
|
|
|
|
|
2025-02-03 11:23:48 +00:00
|
|
|
bus.Start()
|
|
|
|
defer bus.Stop()
|
|
|
|
|
2025-01-26 23:19:31 +00:00
|
|
|
app := fiber.New(fiber.Config{
|
2025-01-31 22:42:32 +00:00
|
|
|
Views: tmplEngine,
|
|
|
|
PassLocalsToViews: true,
|
2025-01-26 23:19:31 +00:00
|
|
|
})
|
2025-01-31 22:42:32 +00:00
|
|
|
app.Use(encryptcookie.New(encryptcookie.Config{Key: cfg.EncryptedCookieKey}))
|
|
|
|
|
2025-02-03 10:35:58 +00:00
|
|
|
app.Use("/assets", static.New("", static.Config{
|
|
|
|
FS: assets.FS,
|
|
|
|
}))
|
2025-01-31 22:42:32 +00:00
|
|
|
|
|
|
|
app.Get("/auth/login", authHandlers.ShowLogin)
|
|
|
|
app.Post("/auth/login", authHandlers.Login)
|
|
|
|
app.Use(authHandlers.RequireAuth)
|
2025-01-26 23:19:31 +00:00
|
|
|
|
2025-01-31 23:56:59 +00:00
|
|
|
app.Get("/", indexHandlers.Index)
|
2025-01-31 22:42:32 +00:00
|
|
|
app.Post("/sites", siteHandlers.Create)
|
|
|
|
app.Get("/sites/:siteId", siteHandlers.Show)
|
2025-01-26 23:19:31 +00:00
|
|
|
|
2025-02-17 10:41:36 +00:00
|
|
|
app.Use("/preview", static.New(cfg.PreviewDir(), static.Config{
|
|
|
|
Browse: true,
|
|
|
|
}))
|
|
|
|
|
2025-02-03 10:35:58 +00:00
|
|
|
sr := app.Group("/sites/:siteId")
|
|
|
|
sr.Use(siteHandlers.WithSite())
|
|
|
|
sr.Post("/rebuild", siteHandlers.Rebuild)
|
2025-01-31 22:42:32 +00:00
|
|
|
|
2025-02-03 10:35:58 +00:00
|
|
|
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)
|
2025-02-01 22:54:30 +00:00
|
|
|
|
2025-02-16 00:43:22 +00:00
|
|
|
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)
|
|
|
|
|
2025-02-03 10:35:58 +00:00
|
|
|
sr.Get("/settings", siteHandlers.Settings)
|
|
|
|
sr.Post("/settings", siteHandlers.SaveSettings)
|
2025-02-03 11:23:48 +00:00
|
|
|
sr.Get("/sse", siteHandlers.SSE)
|
2025-01-27 04:45:53 +00:00
|
|
|
|
2025-01-26 23:19:31 +00:00
|
|
|
jobService.Start()
|
|
|
|
defer jobService.Stop()
|
|
|
|
|
|
|
|
if err := app.Listen(":3000"); err != nil {
|
|
|
|
log.Println(err)
|
2025-01-26 20:39:19 +00:00
|
|
|
}
|
2025-01-26 23:19:31 +00:00
|
|
|
|
|
|
|
log.Println("Shutting down...")
|
2025-01-26 20:39:19 +00:00
|
|
|
}
|