Added Fiber and layouts
This commit is contained in:
parent
f8e7ea482b
commit
63b19a249a
|
@ -7,6 +7,7 @@ package dbq
|
|||
type Site struct {
|
||||
ID int64
|
||||
Name string
|
||||
Title string
|
||||
Url string
|
||||
Theme string
|
||||
Props []byte
|
||||
|
|
|
@ -9,8 +9,26 @@ import (
|
|||
"context"
|
||||
)
|
||||
|
||||
const getSiteWithID = `-- name: GetSiteWithID :one
|
||||
SELECT id, name, title, url, theme, props FROM site WHERE id = $1 LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSiteWithID(ctx context.Context, id int64) (Site, error) {
|
||||
row := q.db.QueryRow(ctx, getSiteWithID, id)
|
||||
var i Site
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Title,
|
||||
&i.Url,
|
||||
&i.Theme,
|
||||
&i.Props,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listSites = `-- name: ListSites :one
|
||||
SELECT id, name, url, theme, props FROM site
|
||||
SELECT id, name, title, url, theme, props FROM site
|
||||
`
|
||||
|
||||
func (q *Queries) ListSites(ctx context.Context) (Site, error) {
|
||||
|
@ -19,6 +37,7 @@ func (q *Queries) ListSites(ctx context.Context) (Site, error) {
|
|||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Title,
|
||||
&i.Url,
|
||||
&i.Theme,
|
||||
&i.Props,
|
||||
|
@ -29,15 +48,17 @@ func (q *Queries) ListSites(ctx context.Context) (Site, error) {
|
|||
const newSite = `-- name: NewSite :one
|
||||
INSERT INTO site (
|
||||
name,
|
||||
title,
|
||||
url,
|
||||
theme,
|
||||
props
|
||||
) VALUES ($1, $2, $3, $4)
|
||||
) VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id
|
||||
`
|
||||
|
||||
type NewSiteParams struct {
|
||||
Name string
|
||||
Title string
|
||||
Url string
|
||||
Theme string
|
||||
Props []byte
|
||||
|
@ -46,6 +67,7 @@ type NewSiteParams struct {
|
|||
func (q *Queries) NewSite(ctx context.Context, arg NewSiteParams) (int64, error) {
|
||||
row := q.db.QueryRow(ctx, newSite,
|
||||
arg.Name,
|
||||
arg.Title,
|
||||
arg.Url,
|
||||
arg.Theme,
|
||||
arg.Props,
|
||||
|
|
25
go.mod
25
go.mod
|
@ -8,14 +8,37 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gofiber/fiber/v2 v2.52.6 // indirect
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4 // indirect
|
||||
github.com/gofiber/schema v1.2.0 // indirect
|
||||
github.com/gofiber/template v1.8.3 // indirect
|
||||
github.com/gofiber/template/html/v2 v2.1.3 // indirect
|
||||
github.com/gofiber/utils v1.1.0 // indirect
|
||||
github.com/gofiber/utils/v2 v2.0.0-beta.7 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/tinylib/msgp v1.2.5 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.58.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
)
|
||||
|
|
50
go.sum
50
go.sum
|
@ -1,7 +1,27 @@
|
|||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
||||
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4/go.mod h1:/WFUoHRkZEsGHyy2+fYcdqi109IVOFbVwxv1n1RU+kk=
|
||||
github.com/gofiber/schema v1.2.0 h1:j+ZRrNnUa/0ZuWrn/6kAtAufEr4jCJ+JuTURAMxNSZg=
|
||||
github.com/gofiber/schema v1.2.0/go.mod h1:YYwj01w3hVfaNjhtJzaqetymL56VW642YS3qZPhuE6c=
|
||||
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
||||
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
|
||||
github.com/gofiber/template/html/v2 v2.1.3 h1:n1LYBtmr9C0V/k/3qBblXyMxV5B0o/gpb6dFLp8ea+o=
|
||||
github.com/gofiber/template/html/v2 v2.1.3/go.mod h1:U5Fxgc5KpyujU9OqKzy6Kn6Qup6Tm7zdsISR+VpnHRE=
|
||||
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
|
||||
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
|
||||
github.com/gofiber/utils/v2 v2.0.0-beta.7 h1:NnHFrRHvhrufPABdWajcKZejz9HnCWmT/asoxRsiEbQ=
|
||||
github.com/gofiber/utils/v2 v2.0.0-beta.7/go.mod h1:J/M03s+HMdZdvhAeyh76xT72IfVqBzuz/OJkrMa7cwU=
|
||||
github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
|
||||
github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
|
@ -17,16 +37,46 @@ github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
|||
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
|
||||
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.58.0 h1:GGB2dWxSbEprU9j0iMJHgdKYJVDyjrOwF9RE59PbRuE=
|
||||
github.com/valyala/fasthttp v1.58.0/go.mod h1:SYXvHHaFp7QZHGKSHmoMipInhrI5StHrhDTYVEjK/Kw=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
38
handlers/site.go
Normal file
38
handlers/site.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"lmika.dev/lmika/hugo-crm/services/sites"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Site struct {
|
||||
Site *sites.Service
|
||||
}
|
||||
|
||||
func (s *Site) Create() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
site, err := s.Site.CreateSite(c.UserContext(), "New Site "+time.Now().Format("2006-01-02 15:04:05"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Redirect(fmt.Sprintf("/sites/%v", site.ID))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Site) Show() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("siteId")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
site, err := s.Site.GetSite(c.UserContext(), id)
|
||||
|
||||
return c.Render("sites/index", fiber.Map{
|
||||
"site": site,
|
||||
}, "layouts/main")
|
||||
}
|
||||
}
|
36
main.go
36
main.go
|
@ -2,14 +2,20 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/template/html/v2"
|
||||
"lmika.dev/lmika/hugo-crm/config"
|
||||
"lmika.dev/lmika/hugo-crm/handlers"
|
||||
"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"
|
||||
"lmika.dev/lmika/hugo-crm/services/jobs"
|
||||
"lmika.dev/lmika/hugo-crm/services/sitebuilder"
|
||||
"lmika.dev/lmika/hugo-crm/services/sites"
|
||||
"lmika.dev/lmika/hugo-crm/templates"
|
||||
"log"
|
||||
"time"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -31,7 +37,12 @@ func main() {
|
|||
gitProvider := git.New()
|
||||
themesProvider := themes.New()
|
||||
|
||||
siteService := sites.NewService(cfg, dbp, themesProvider, gitProvider, hugoProvider)
|
||||
jobService := jobs.New()
|
||||
siteBuilderService := sitebuilder.New(themesProvider, gitProvider, hugoProvider)
|
||||
|
||||
siteService := sites.NewService(cfg, dbp, themesProvider, siteBuilderService, jobService)
|
||||
|
||||
siteHandlers := handlers.Site{Site: siteService}
|
||||
|
||||
log.Println("Connected to database")
|
||||
if err := dbp.Migrate(context.Background()); err != nil {
|
||||
|
@ -40,7 +51,24 @@ func main() {
|
|||
|
||||
log.Println("Database migrated")
|
||||
|
||||
if _, err := siteService.CreateSite(context.Background(), "Test site "+time.Now().Format("2006-01-02T15:04:05")); err != nil {
|
||||
log.Fatal(err)
|
||||
tmplEngine := html.NewFileSystem(http.FS(templates.FS), ".html")
|
||||
app := fiber.New(fiber.Config{
|
||||
Views: tmplEngine,
|
||||
})
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.Render("index", fiber.Map{}, "layouts/main")
|
||||
})
|
||||
|
||||
app.Post("/sites", siteHandlers.Create())
|
||||
app.Get("/sites/:siteId", siteHandlers.Show())
|
||||
|
||||
jobService.Start()
|
||||
defer jobService.Stop()
|
||||
|
||||
if err := app.Listen(":3000"); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
log.Println("Shutting down...")
|
||||
}
|
||||
|
|
7
models/job.go
Normal file
7
models/job.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package models
|
||||
|
||||
import "context"
|
||||
|
||||
type Job struct {
|
||||
Do func(ctx context.Context) error
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
func (db *DB) InsertSite(ctx context.Context, site *models.Site) error {
|
||||
id, err := db.q.NewSite(ctx, dbq.NewSiteParams{
|
||||
Name: site.Name,
|
||||
Title: site.Title,
|
||||
Url: site.URL,
|
||||
Theme: site.Theme,
|
||||
Props: []byte("{}"),
|
||||
|
@ -19,3 +20,17 @@ func (db *DB) InsertSite(ctx context.Context, site *models.Site) error {
|
|||
site.ID = id
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *DB) GetSite(ctx context.Context, id int64) (models.Site, error) {
|
||||
site, err := db.q.GetSiteWithID(ctx, id)
|
||||
if err != nil {
|
||||
return models.Site{}, err
|
||||
}
|
||||
|
||||
return models.Site{
|
||||
ID: site.ID,
|
||||
Name: site.Name,
|
||||
Title: site.Title,
|
||||
Theme: site.Theme,
|
||||
}, nil
|
||||
}
|
||||
|
|
38
services/jobs/services.go
Normal file
38
services/jobs/services.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package jobs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"lmika.dev/lmika/hugo-crm/models"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
queue chan models.Job
|
||||
}
|
||||
|
||||
func New() *Service {
|
||||
return &Service{
|
||||
queue: make(chan models.Job, 50),
|
||||
}
|
||||
}
|
||||
|
||||
func (j *Service) Start() {
|
||||
go func() {
|
||||
for j := range j.queue {
|
||||
if err := j.Do(context.Background()); err != nil {
|
||||
log.Printf("job failed %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (j *Service) Stop() {
|
||||
q := j.queue
|
||||
j.queue = nil
|
||||
close(q)
|
||||
}
|
||||
|
||||
func (j *Service) Queue(ctx context.Context, job models.Job) error {
|
||||
j.queue <- job
|
||||
return nil
|
||||
}
|
57
services/sitebuilder/service.go
Normal file
57
services/sitebuilder/service.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package sitebuilder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"lmika.dev/lmika/hugo-crm/models"
|
||||
"lmika.dev/lmika/hugo-crm/providers/git"
|
||||
"lmika.dev/lmika/hugo-crm/providers/hugo"
|
||||
"lmika.dev/lmika/hugo-crm/providers/themes"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
themes *themes.Provider
|
||||
git *git.Provider
|
||||
hugo *hugo.Provider
|
||||
}
|
||||
|
||||
func New(
|
||||
themes *themes.Provider,
|
||||
git *git.Provider,
|
||||
hugo *hugo.Provider,
|
||||
) *Service {
|
||||
return &Service{
|
||||
themes: themes,
|
||||
git: git,
|
||||
hugo: hugo,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) CreateNewSite(site models.Site) models.Job {
|
||||
return models.Job{
|
||||
Do: func(ctx context.Context) error {
|
||||
themeMeta, ok := s.themes.Lookup(site.Theme)
|
||||
if !ok {
|
||||
return errors.New("theme not found")
|
||||
}
|
||||
|
||||
// Build the site
|
||||
log.Printf(" .. build")
|
||||
if err := s.hugo.NewSite(ctx, site); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Setup the theme
|
||||
log.Printf(" .. theme")
|
||||
if err := s.git.Clone(ctx, themeMeta.URL, s.hugo.SiteStagingDir(site, hugo.ThemeSiteDir)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.hugo.ReconfigureSite(ctx, site); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
|
@ -6,10 +6,9 @@ import (
|
|||
"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"
|
||||
"lmika.dev/lmika/hugo-crm/services/jobs"
|
||||
"lmika.dev/lmika/hugo-crm/services/sitebuilder"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
@ -18,25 +17,30 @@ type Service struct {
|
|||
cfg config.Config
|
||||
db *db.DB
|
||||
themes *themes.Provider
|
||||
git *git.Provider
|
||||
hugo *hugo.Provider
|
||||
sb *sitebuilder.Service
|
||||
jobs *jobs.Service
|
||||
}
|
||||
|
||||
func NewService(
|
||||
cfg config.Config,
|
||||
db *db.DB,
|
||||
themes *themes.Provider,
|
||||
git *git.Provider,
|
||||
hugo *hugo.Provider,
|
||||
sb *sitebuilder.Service,
|
||||
jobs *jobs.Service,
|
||||
) *Service {
|
||||
return &Service{
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
git: git,
|
||||
hugo: hugo,
|
||||
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) CreateSite(ctx context.Context, name string) (models.Site, error) {
|
||||
newSite := models.Site{
|
||||
Name: normaliseName(name),
|
||||
|
@ -44,7 +48,7 @@ func (s *Service) CreateSite(ctx context.Context, name string) (models.Site, err
|
|||
Theme: "bear",
|
||||
}
|
||||
|
||||
themeMeta, ok := s.themes.Lookup(newSite.Theme)
|
||||
_, ok := s.themes.Lookup(newSite.Theme)
|
||||
if !ok {
|
||||
return models.Site{}, errors.New("theme not found")
|
||||
}
|
||||
|
@ -53,23 +57,7 @@ func (s *Service) CreateSite(ctx context.Context, name string) (models.Site, err
|
|||
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
|
||||
return newSite, s.jobs.Queue(ctx, s.sb.CreateNewSite(newSite))
|
||||
}
|
||||
|
||||
func normaliseName(name string) string {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
-- name: ListSites :one
|
||||
SELECT * FROM site;
|
||||
|
||||
-- name: GetSiteWithID :one
|
||||
SELECT * FROM site WHERE id = $1 LIMIT 1;
|
||||
|
||||
-- name: NewSite :one
|
||||
INSERT INTO site (
|
||||
name,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
CREATE TABLE site (
|
||||
id BIGSERIAL NOT NULL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
title TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
theme TEXT NOT NULL,
|
||||
props JSON NOT NULL
|
||||
|
|
8
templates/fs.go
Normal file
8
templates/fs.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package templates
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed *.html
|
||||
//go:embed layouts/*.html
|
||||
//go:embed sites/*.html
|
||||
var FS embed.FS
|
5
templates/index.html
Normal file
5
templates/index.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
<h1>Thing</h1>
|
||||
|
||||
<form method="post" action="/sites">
|
||||
<input type="submit" value="Create Site">
|
||||
</form>
|
9
templates/layouts/main.html
Normal file
9
templates/layouts/main.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>TEMP</title>
|
||||
</head>
|
||||
<body>
|
||||
{{embed}}
|
||||
</body>
|
||||
</html>
|
1
templates/sites/index.html
Normal file
1
templates/sites/index.html
Normal file
|
@ -0,0 +1 @@
|
|||
<h1>Site {{.site.Title}}</h1>
|
Loading…
Reference in a new issue