First Page

This commit is contained in:
Simon Martens
2025-02-10 20:44:34 +01:00
parent a39ac0d68e
commit deae787e2d
8 changed files with 292 additions and 4 deletions

36
; Normal file
View File

@@ -0,0 +1,36 @@
package main
import (
"log"
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
"github.com/Theodor-Springmann-Stiftung/musenalm/cmd"
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers"
_ "github.com/Theodor-Springmann-Stiftung/musenalm/migrations"
_ "github.com/Theodor-Springmann-Stiftung/musenalm/pages"
"github.com/pocketbase/pocketbase/plugins/migratecmd"
)
const (
DEV_CONFIG = "config.dev.json"
DEFAULT_CONFIG = "config.json"
)
func main() {
cfg := app.NewConfigProvider([]string{DEFAULT_CONFIG}, []string{DEV_CONFIG})
if err := cfg.Read(); err != nil {
helpers.Assert(err, "Error reading config")
}
app := app.New(*cfg.Config)
app.PB.RootCmd.AddCommand(cmd.AddResetPagesCommand(app.PB, &app))
migratecmd.MustRegister(app.PB, app.PB.RootCmd, migratecmd.Config{
Automigrate: false,
TemplateLang: migratecmd.TemplateLangGo,
})
if err := app.Serve(); err != nil {
log.Fatal(err)
}
}

9
app/pages.go Normal file
View File

@@ -0,0 +1,9 @@
package app
import "github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
var pages []pagemodels.IPage
func Register(page pagemodels.IPage) {
pages = append(pages, page)
}

View File

@@ -4,6 +4,9 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
"github.com/Theodor-Springmann-Stiftung/musenalm/views"
"github.com/mattn/go-sqlite3" "github.com/mattn/go-sqlite3"
"github.com/pocketbase/dbx" "github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase"
@@ -14,11 +17,12 @@ import (
type App struct { type App struct {
PB *pocketbase.PocketBase PB *pocketbase.PocketBase
MAConfig Config MAConfig Config
Pages []pagemodels.IPage
} }
const ( const (
TEST_SUPERUSER_MAIL = "test@test.de" TEST_SUPERUSER_MAIL = "demo@example.com"
TEST_SUPERUSER_PASS = "passwort" TEST_SUPERUSER_PASS = "password"
) )
func init() { func init() {
@@ -94,3 +98,35 @@ func (app *App) setupTestuser() {
return e.Next() return e.Next()
}) })
} }
func (app *App) Serve() error {
engine := templating.NewEngine(&views.LayoutFS, &views.RoutesFS)
app.PB.OnBootstrap().BindFunc(func(e *core.BootstrapEvent) error {
e.Next()
for _, page := range pages {
err := page.Up(e.App)
if err != nil {
page.Down(e.App)
continue
}
app.Pages = append(app.Pages, page)
}
return nil
})
app.PB.OnServe().BindFunc(func(e *core.ServeEvent) error {
for _, page := range app.Pages {
page.Setup(e.Router, e.App, engine)
}
return e.Next()
})
return app.PB.Start()
}
func (app *App) ResetPages() error {
for _, page := range pages {
page.Down(app.PB)
}
return nil
}

26
cmd/resetpages.go Normal file
View File

@@ -0,0 +1,26 @@
package cmd
import (
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
"github.com/spf13/cobra"
)
func AddResetPagesCommand(pb *pocketbase.PocketBase, app *app.App) *cobra.Command {
var resetPagesCmd = &cobra.Command{
Use: "resetpages",
Short: "Reset all pages",
Run: func(cmd *cobra.Command, args []string) {
pb.OnBootstrap().BindFunc(func(e *core.BootstrapEvent) error {
e.Next()
if err := app.ResetPages(); err != nil {
panic(err)
}
return nil
})
},
}
return resetPagesCmd
}

View File

@@ -4,8 +4,10 @@ import (
"log" "log"
"github.com/Theodor-Springmann-Stiftung/musenalm/app" "github.com/Theodor-Springmann-Stiftung/musenalm/app"
"github.com/Theodor-Springmann-Stiftung/musenalm/cmd"
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers" "github.com/Theodor-Springmann-Stiftung/musenalm/helpers"
_ "github.com/Theodor-Springmann-Stiftung/musenalm/migrations" _ "github.com/Theodor-Springmann-Stiftung/musenalm/migrations"
_ "github.com/Theodor-Springmann-Stiftung/musenalm/pages"
"github.com/pocketbase/pocketbase/plugins/migratecmd" "github.com/pocketbase/pocketbase/plugins/migratecmd"
) )
@@ -15,20 +17,20 @@ const (
) )
func main() { func main() {
cfg := app.NewConfigProvider([]string{DEFAULT_CONFIG}, []string{DEV_CONFIG}) cfg := app.NewConfigProvider([]string{DEFAULT_CONFIG}, []string{DEV_CONFIG})
if err := cfg.Read(); err != nil { if err := cfg.Read(); err != nil {
helpers.Assert(err, "Error reading config") helpers.Assert(err, "Error reading config")
} }
app := app.New(*cfg.Config) app := app.New(*cfg.Config)
app.PB.RootCmd.AddCommand(cmd.AddResetPagesCommand(app.PB, &app))
migratecmd.MustRegister(app.PB, app.PB.RootCmd, migratecmd.Config{ migratecmd.MustRegister(app.PB, app.PB.RootCmd, migratecmd.Config{
Automigrate: false, Automigrate: false,
TemplateLang: migratecmd.TemplateLangGo, TemplateLang: migratecmd.TemplateLangGo,
}) })
if err := app.PB.Start(); err != nil { if err := app.Serve(); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }

70
pagemodels/page.go Normal file
View File

@@ -0,0 +1,70 @@
package pagemodels
import (
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/router"
)
const (
PAGE_DB_PREFIX = "page_"
)
type IPage interface {
Up(app core.App) error
Down(app core.App) error
// TODO: pass the cache here
Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error
}
type Page struct {
// WARNING: this is not thread safe, just set this once in setup
Tables []string
Name string
}
func (p *Page) TableExists(app core.App, name string) bool {
coll, _ := app.FindCollectionByNameOrId(p.generateName(name))
if coll != nil {
p.Tables = append(p.Tables, coll.Name)
}
return coll != nil
}
func (p *Page) CreateTable(app core.App, collection *core.Collection) error {
collection.Name = p.generateName(collection.Name)
err := app.Save(collection)
if err != nil {
app.Logger().Error("Error creating table", "error", err, "collection", collection, "name", p.Name)
return err
}
p.Tables = append(p.Tables, collection.Name)
return nil
}
func (p *Page) DropTable(app core.App, name string) error {
coll, _ := app.FindCollectionByNameOrId(p.generateName(name))
if coll != nil {
err := app.Delete(coll)
if err != nil {
app.Logger().Error("Error deleting table", "error", err, "collection", coll, "name", p.Name)
return err
}
}
return nil
}
func (p *Page) DropTables(app core.App) error {
for _, table := range p.Tables {
err := p.DropTable(app, table)
if err != nil {
return err
}
}
return nil
}
func (p *Page) generateName(name string) string {
return PAGE_DB_PREFIX + p.Name + "_" + name
}

108
pages/index.go Normal file
View File

@@ -0,0 +1,108 @@
package pages
import (
"net/http"
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/router"
"github.com/pocketbase/pocketbase/tools/types"
)
const INDEX_NAME = "index"
const BILDER_T_NAME = "bilder"
const TEXTE_T_NAME = "texte"
var bilder_fields = core.NewFieldsList(
&core.TextField{Name: "Titel", Required: true, Presentable: true},
&core.EditorField{Name: "Beschreibung", Required: false, Presentable: false},
&core.FileField{
Name: "Bilder",
Required: false,
MaxSize: 100 * 1024 * 1024,
MaxSelect: 1000,
MimeTypes: dbmodels.MUSENALM_MIME_TYPES,
Thumbs: []string{"0x300", "0x500", "0x1000", "300x0", "500x0", "1000x0"},
}, // 100 MB a file
&core.FileField{
Name: "Vorschau",
Required: false,
MaxSize: 100 * 1024 * 1024,
MaxSelect: 1000,
MimeTypes: dbmodels.MUSENALM_MIME_TYPES,
Thumbs: []string{"0x300", "0x500", "0x1000", "300x0", "500x0", "1000x0"},
}, // 100 MB a file
)
var texte_fields = core.NewFieldsList(
&core.TextField{Name: "Titel", Required: true, Presentable: true},
&core.EditorField{Name: "Abs1", Required: false, Presentable: false},
&core.EditorField{Name: "Abs2", Required: false, Presentable: false},
)
func init() {
ip := &IndexPage{
Page: pagemodels.Page{
Name: INDEX_NAME,
},
}
app.Register(ip)
}
type IndexPage struct {
pagemodels.Page
}
func (p *IndexPage) Up(app core.App) error {
if !p.TableExists(app, BILDER_T_NAME) {
err := p.CreateTable(app, p.bilderCollection())
if err != nil {
return err
}
}
if !p.TableExists(app, TEXTE_T_NAME) {
err := p.CreateTable(app, p.texteCollection())
if err != nil {
return err
}
}
return nil
}
func (p *IndexPage) Down(app core.App) error {
err := p.DropTable(app, BILDER_T_NAME)
if err != nil {
return err
}
err = p.DropTable(app, TEXTE_T_NAME)
if err != nil {
return err
}
return nil
}
func (p *IndexPage) bilderCollection() *core.Collection {
c := core.NewBaseCollection(BILDER_T_NAME)
c.ListRule = types.Pointer("")
c.ViewRule = types.Pointer("")
c.Fields = bilder_fields
return c
}
func (p *IndexPage) texteCollection() *core.Collection {
c := core.NewBaseCollection(TEXTE_T_NAME)
c.ListRule = types.Pointer("")
c.ViewRule = types.Pointer("")
c.Fields = texte_fields
return c
}
func (p *IndexPage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error {
router.GET("/{$}", func(e *core.RequestEvent) error {
return e.String(http.StatusOK, "Hello, World!")
})
return nil
}

1
pages/start.go Normal file
View File

@@ -0,0 +1 @@
package pages