parent
e6d6ba4041
commit
c6dc9cd110
@ -6,34 +6,43 @@ import (
|
|||||||
"git.tijl.dev/tijl/tijl.dev/internal/assets"
|
"git.tijl.dev/tijl/tijl.dev/internal/assets"
|
||||||
"git.tijl.dev/tijl/tijl.dev/internal/config"
|
"git.tijl.dev/tijl/tijl.dev/internal/config"
|
||||||
"git.tijl.dev/tijl/tijl.dev/internal/i18n"
|
"git.tijl.dev/tijl/tijl.dev/internal/i18n"
|
||||||
|
"git.tijl.dev/tijl/tijl.dev/modules/logger"
|
||||||
"git.tijl.dev/tijl/tijl.dev/static"
|
"git.tijl.dev/tijl/tijl.dev/static"
|
||||||
"git.tijl.dev/tijl/tijl.dev/views"
|
"git.tijl.dev/tijl/tijl.dev/views"
|
||||||
|
"github.com/gofiber/contrib/fiberzerolog"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||||
"github.com/gofiber/template/html/v2"
|
"github.com/gofiber/template/html/v2"
|
||||||
"github.com/mikhail-bigun/fiberlogrus"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
|
|
||||||
|
// Load config
|
||||||
config.Load()
|
config.Load()
|
||||||
|
|
||||||
|
// Load assets
|
||||||
assets.Load()
|
assets.Load()
|
||||||
|
// Load translations
|
||||||
i18n.Load()
|
i18n.Load()
|
||||||
|
|
||||||
engine := html.NewFileSystem(http.FS(views.Embed), ".html")
|
// Todo load db, migrations and plugins
|
||||||
|
|
||||||
|
// Init templating engine
|
||||||
|
engine := html.NewFileSystem(http.FS(views.Embed), ".html")
|
||||||
engine.AddFunc("icon", assets.Svg)
|
engine.AddFunc("icon", assets.Svg)
|
||||||
|
|
||||||
|
// Init fiber
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
Views: engine,
|
Views: engine,
|
||||||
DisableStartupMessage: true,
|
DisableStartupMessage: true,
|
||||||
})
|
})
|
||||||
|
app.Use(fiberzerolog.New(fiberzerolog.Config{
|
||||||
|
Logger: &log.Logger,
|
||||||
|
}))
|
||||||
|
|
||||||
app.Use(fiberlogrus.New())
|
/*
|
||||||
|
Routes
|
||||||
|
*/
|
||||||
app.Get("/", func(c *fiber.Ctx) error {
|
app.Get("/", func(c *fiber.Ctx) error {
|
||||||
data := getCommon(c)
|
data := getCommon(c)
|
||||||
data["Title"] = i18n.Translate(c, "home")
|
data["Title"] = i18n.Translate(c, "home")
|
||||||
@ -70,18 +79,24 @@ func main() {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Static routes
|
||||||
app.Use("/static", filesystem.New(filesystem.Config{
|
app.Use("/static", filesystem.New(filesystem.Config{
|
||||||
Root: http.FS(static.Embed),
|
Root: http.FS(static.Embed),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// 404
|
||||||
app.Use(func(c *fiber.Ctx) error {
|
app.Use(func(c *fiber.Ctx) error {
|
||||||
data := getCommon(c)
|
data := getCommon(c)
|
||||||
return c.Render("404", data, "layouts/base")
|
return c.Render("404", data, "layouts/base")
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
// Listen web server
|
||||||
|
if err := app.Listen(":3000"); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Fiber app error")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Common functions for in templating
|
||||||
func getCommon(c *fiber.Ctx) fiber.Map {
|
func getCommon(c *fiber.Ctx) fiber.Map {
|
||||||
return fiber.Map{
|
return fiber.Map{
|
||||||
"Path": c.Path(),
|
"Path": c.Path(),
|
||||||
|
3
go.mod
3
go.mod
@ -7,13 +7,16 @@ require (
|
|||||||
github.com/gofiber/fiber/v2 v2.52.5
|
github.com/gofiber/fiber/v2 v2.52.5
|
||||||
github.com/gofiber/template/html/v2 v2.1.2
|
github.com/gofiber/template/html/v2 v2.1.2
|
||||||
github.com/mikhail-bigun/fiberlogrus v0.1.3
|
github.com/mikhail-bigun/fiberlogrus v0.1.3
|
||||||
|
github.com/rs/zerolog v1.33.0
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
|
github.com/sqlc-dev/pqtype v0.3.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||||
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
||||||
|
github.com/gofiber/contrib/fiberzerolog v1.0.2 // indirect
|
||||||
github.com/gofiber/template v1.8.3 // indirect
|
github.com/gofiber/template v1.8.3 // indirect
|
||||||
github.com/gofiber/utils v1.1.0 // indirect
|
github.com/gofiber/utils v1.1.0 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
12
go.sum
12
go.sum
@ -2,11 +2,15 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1
|
|||||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||||
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
|
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
|
||||||
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
|
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
|
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
github.com/gofiber/contrib/fiberzerolog v1.0.2 h1:LMa/luarQVeINoRwZLHtLQYepLPDIwUNB5OmdZKk+s8=
|
||||||
|
github.com/gofiber/contrib/fiberzerolog v1.0.2/go.mod h1:aTPsgArSgxRWcUeJ/K6PiICz3mbQENR1QOR426QwOoQ=
|
||||||
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
|
||||||
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||||
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
||||||
@ -24,19 +28,26 @@ github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib
|
|||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
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-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mikhail-bigun/fiberlogrus v0.1.3 h1:2aVtFSfMr/T8J2p4228TwV6txvUEOQxKlu5LpcKyym0=
|
github.com/mikhail-bigun/fiberlogrus v0.1.3 h1:2aVtFSfMr/T8J2p4228TwV6txvUEOQxKlu5LpcKyym0=
|
||||||
github.com/mikhail-bigun/fiberlogrus v0.1.3/go.mod h1:Tt0FrmLd2maF8VSHsx1pfiWNRTrjyBrKfDA2JW5hvmY=
|
github.com/mikhail-bigun/fiberlogrus v0.1.3/go.mod h1:Tt0FrmLd2maF8VSHsx1pfiWNRTrjyBrKfDA2JW5hvmY=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
|
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||||
|
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
|
github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk=
|
||||||
|
github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
@ -54,6 +65,7 @@ golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
|
|||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
"git.tijl.dev/tijl/tijl.dev/modules/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var SVGData map[string]string
|
var SVGData map[string]string
|
||||||
@ -18,13 +18,13 @@ func loadSVGs() {
|
|||||||
|
|
||||||
files, err := filepath.Glob(filepath.Join(dir, "*.svg"))
|
files, err := filepath.Glob(filepath.Join(dir, "*.svg"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error loading SVG files: %v", err)
|
log.Fatal().Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
data, err := os.ReadFile(file)
|
data, err := os.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Error reading SVG file %s: %v", file, err)
|
log.Fatal().Err(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
filename := filepath.Base(file)
|
filename := filepath.Base(file)
|
||||||
@ -32,7 +32,7 @@ func loadSVGs() {
|
|||||||
SVGData[key] = string(data)
|
SVGData[key] = string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("Loaded SVG files")
|
log.Debug().Msg("Loaded SVG files")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Svg(name string) template.HTML {
|
func Svg(name string) template.HTML {
|
||||||
|
@ -3,7 +3,7 @@ package config
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "git.tijl.dev/tijl/tijl.dev/modules/logger"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,15 +17,15 @@ func Load() {
|
|||||||
|
|
||||||
indexFile, err := os.ReadFile(configPath)
|
indexFile, err := os.ReadFile(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal().Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = yaml.Unmarshal(indexFile, &Config)
|
err = yaml.Unmarshal(indexFile, &Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal().Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("loaded config")
|
log.Debug().Msg("loaded config")
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConfigType struct {
|
type ConfigType struct {
|
||||||
|
@ -2,11 +2,11 @@ package i18n
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "git.tijl.dev/tijl/tijl.dev/modules/logger"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var translations map[string]map[string]string
|
var translations map[string]map[string]string
|
||||||
@ -19,7 +19,7 @@ func Load() {
|
|||||||
dir := "locales"
|
dir := "locales"
|
||||||
files, err := filepath.Glob(filepath.Join(dir, "*.json"))
|
files, err := filepath.Glob(filepath.Join(dir, "*.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error loading language files: %v", err)
|
log.Fatal().Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
@ -28,20 +28,20 @@ func Load() {
|
|||||||
|
|
||||||
file, err := os.Open(file)
|
file, err := os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error opening translation file %s: %v", file, err)
|
log.Error().Err(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
var messages map[string]string
|
var messages map[string]string
|
||||||
if err := json.NewDecoder(file).Decode(&messages); err != nil {
|
if err := json.NewDecoder(file).Decode(&messages); err != nil {
|
||||||
log.Errorf("Error decoding translation file %s: %v", file, err)
|
log.Error().Err(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
translations[lang] = messages
|
translations[lang] = messages
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("Loaded translations")
|
log.Debug().Msg("Loaded translations")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Translate(c *fiber.Ctx, key string) string {
|
func Translate(c *fiber.Ctx, key string) string {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package oidc
|
package oidc
|
||||||
|
|
||||||
import "github.com/coreos/go-oidc/v3/oidc"
|
|
||||||
|
|
||||||
func Setup() {
|
func Setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
justfile
5
justfile
@ -7,8 +7,11 @@ npm-build-css:
|
|||||||
npm-build:
|
npm-build:
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
|
generate-sqlc:
|
||||||
|
sqlc generate
|
||||||
|
|
||||||
go-build:
|
go-build:
|
||||||
go build -o tijl.dev cmd/server/main.go
|
go build -o tijl.dev cmd/server/main.go
|
||||||
|
|
||||||
build: npm-build-css npm-build go-build
|
build: npm-build-css npm-build generate-sqlc go-build
|
||||||
|
|
||||||
|
30
migrations/00000001_init.up.sql
Normal file
30
migrations/00000001_init.up.sql
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
CREATE TABLE users (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
uid VARCHAR UNIQUE NOT NULL, -- username as unique identifier
|
||||||
|
email VARCHAR UNIQUE,
|
||||||
|
full_name VARCHAR,
|
||||||
|
displayname VARCHAR,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE sessions (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id INTEGER NOT NULL,
|
||||||
|
title VARCHAR,
|
||||||
|
token VARCHAR NOT NULL UNIQUE,
|
||||||
|
password VARCHAR,
|
||||||
|
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
expires TIMESTAMP,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE session_ips (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
session_id INTEGER NOT NULL,
|
||||||
|
ip_address INET NOT NULL,
|
||||||
|
access_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
FOREIGN KEY (session_id) REFERENCES sessions (id)
|
||||||
|
);
|
||||||
|
|
3
migrations/0000001_init.down.sql
Normal file
3
migrations/0000001_init.down.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
DROP TABLE IF EXISTS session_ips;
|
||||||
|
DROP TABLE IF EXISTS sessions;
|
||||||
|
DROP TABLE IF EXISTS users;
|
6
migrations/migrations.go
Normal file
6
migrations/migrations.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package migrations
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed *
|
||||||
|
var Embed embed.FS
|
31
modules/db/db.go
Normal file
31
modules/db/db.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DBTX interface {
|
||||||
|
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
|
||||||
|
PrepareContext(context.Context, string) (*sql.Stmt, error)
|
||||||
|
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
|
||||||
|
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db DBTX) *Queries {
|
||||||
|
return &Queries{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Queries struct {
|
||||||
|
db DBTX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
|
||||||
|
return &Queries{
|
||||||
|
db: tx,
|
||||||
|
}
|
||||||
|
}
|
40
modules/db/models.go
Normal file
40
modules/db/models.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/sqlc-dev/pqtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Session struct {
|
||||||
|
ID int32
|
||||||
|
UserID int32
|
||||||
|
Title sql.NullString
|
||||||
|
Token string
|
||||||
|
Password sql.NullString
|
||||||
|
LastActivity sql.NullTime
|
||||||
|
Expires sql.NullTime
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type SessionIp struct {
|
||||||
|
ID int32
|
||||||
|
SessionID int32
|
||||||
|
IpAddress pqtype.Inet
|
||||||
|
AccessTime sql.NullTime
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID int32
|
||||||
|
Uid string
|
||||||
|
Email sql.NullString
|
||||||
|
FullName sql.NullString
|
||||||
|
Displayname sql.NullString
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt sql.NullTime
|
||||||
|
}
|
18
modules/db/sessions.sql
Normal file
18
modules/db/sessions.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-- name: GetSesssion :one
|
||||||
|
SELECT * FROM sessions WHERE token = $1;
|
||||||
|
|
||||||
|
-- name: GetSessions :many
|
||||||
|
SELECT * FROM sessions WHERE user_id = $1 ORDER BY $2;
|
||||||
|
|
||||||
|
-- name: GetActiveSessions :many
|
||||||
|
SELECT * FROM sessions WHERE user_id = $1 AND (expires > CURRENT_TIMESTAMP OR expires IS NULL) ORDER BY $2;
|
||||||
|
|
||||||
|
-- name: CreateSession :exec
|
||||||
|
INSERT INTO sessions (user_id, title, token) VALUES ($1, $2, $3);
|
||||||
|
|
||||||
|
-- name: QuickUpdateSession :exec
|
||||||
|
UPDATE sessions SET last_activity = GETDATE() WHERE id = $1;
|
||||||
|
|
||||||
|
-- name: ExpireSession :exec
|
||||||
|
UPDATE sessions SET expires = 1 WHERE id = $1;
|
||||||
|
|
146
modules/db/sessions.sql.go
Normal file
146
modules/db/sessions.sql.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
// source: sessions.sql
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
const createSession = `-- name: CreateSession :exec
|
||||||
|
INSERT INTO sessions (user_id, title, token) VALUES ($1, $2, $3)
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateSessionParams struct {
|
||||||
|
UserID int32
|
||||||
|
Title sql.NullString
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateSession(ctx context.Context, arg CreateSessionParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, createSession, arg.UserID, arg.Title, arg.Token)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const expireSession = `-- name: ExpireSession :exec
|
||||||
|
UPDATE sessions SET expires = 1 WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) ExpireSession(ctx context.Context, id int32) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, expireSession, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getActiveSessions = `-- name: GetActiveSessions :many
|
||||||
|
SELECT id, user_id, title, token, password, last_activity, expires, created_at FROM sessions WHERE user_id = $1 AND (expires > CURRENT_TIMESTAMP OR expires IS NULL) ORDER BY $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetActiveSessionsParams struct {
|
||||||
|
UserID int32
|
||||||
|
Column2 interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetActiveSessions(ctx context.Context, arg GetActiveSessionsParams) ([]Session, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, getActiveSessions, arg.UserID, arg.Column2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []Session
|
||||||
|
for rows.Next() {
|
||||||
|
var i Session
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Title,
|
||||||
|
&i.Token,
|
||||||
|
&i.Password,
|
||||||
|
&i.LastActivity,
|
||||||
|
&i.Expires,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSessions = `-- name: GetSessions :many
|
||||||
|
SELECT id, user_id, title, token, password, last_activity, expires, created_at FROM sessions WHERE user_id = $1 ORDER BY $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetSessionsParams struct {
|
||||||
|
UserID int32
|
||||||
|
Column2 interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetSessions(ctx context.Context, arg GetSessionsParams) ([]Session, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, getSessions, arg.UserID, arg.Column2)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []Session
|
||||||
|
for rows.Next() {
|
||||||
|
var i Session
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Title,
|
||||||
|
&i.Token,
|
||||||
|
&i.Password,
|
||||||
|
&i.LastActivity,
|
||||||
|
&i.Expires,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSesssion = `-- name: GetSesssion :one
|
||||||
|
SELECT id, user_id, title, token, password, last_activity, expires, created_at FROM sessions WHERE token = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetSesssion(ctx context.Context, token string) (Session, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, getSesssion, token)
|
||||||
|
var i Session
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Title,
|
||||||
|
&i.Token,
|
||||||
|
&i.Password,
|
||||||
|
&i.LastActivity,
|
||||||
|
&i.Expires,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const quickUpdateSession = `-- name: QuickUpdateSession :exec
|
||||||
|
UPDATE sessions SET last_activity = GETDATE() WHERE id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) QuickUpdateSession(ctx context.Context, id int32) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, quickUpdateSession, id)
|
||||||
|
return err
|
||||||
|
}
|
25
modules/db/users.sql
Normal file
25
modules/db/users.sql
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
-- name: GetUser :one
|
||||||
|
SELECT * FROM users WHERE uid = $1 LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetUserUid :one
|
||||||
|
SELECT uid FROM users WHERE id = $1 LIMIT 1;
|
||||||
|
|
||||||
|
-- name: GetUserById :one
|
||||||
|
SELECT * FROM users WHERE id = $1 LIMIT 1;
|
||||||
|
|
||||||
|
-- name: DeleteUser :exec
|
||||||
|
DELETE FROM users WHERE uid = $1;
|
||||||
|
|
||||||
|
-- name: CreateUser :exec
|
||||||
|
INSERT INTO users (uid, email, full_name, displayname)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
RETURNING id;
|
||||||
|
|
||||||
|
-- name: UpdateUserData :exec
|
||||||
|
UPDATE users
|
||||||
|
SET email = COALESCE($2, email),
|
||||||
|
full_name = COALESCE($3, full_name),
|
||||||
|
displayname = COALESCE($4, displayname),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE uid = $1;
|
||||||
|
|
118
modules/db/users.sql.go
Normal file
118
modules/db/users.sql.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
// source: users.sql
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
const createUser = `-- name: CreateUser :exec
|
||||||
|
INSERT INTO users (uid, email, full_name, displayname)
|
||||||
|
VALUES ($1, $2, $3, $4)
|
||||||
|
RETURNING id
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateUserParams struct {
|
||||||
|
Uid string
|
||||||
|
Email sql.NullString
|
||||||
|
FullName sql.NullString
|
||||||
|
Displayname sql.NullString
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, createUser,
|
||||||
|
arg.Uid,
|
||||||
|
arg.Email,
|
||||||
|
arg.FullName,
|
||||||
|
arg.Displayname,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteUser = `-- name: DeleteUser :exec
|
||||||
|
DELETE FROM users WHERE uid = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeleteUser(ctx context.Context, uid string) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, deleteUser, uid)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUser = `-- name: GetUser :one
|
||||||
|
SELECT id, uid, email, full_name, displayname, created_at, updated_at FROM users WHERE uid = $1 LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetUser(ctx context.Context, uid string) (User, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, getUser, uid)
|
||||||
|
var i User
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Uid,
|
||||||
|
&i.Email,
|
||||||
|
&i.FullName,
|
||||||
|
&i.Displayname,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUserById = `-- name: GetUserById :one
|
||||||
|
SELECT id, uid, email, full_name, displayname, created_at, updated_at FROM users WHERE id = $1 LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetUserById(ctx context.Context, id int32) (User, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, getUserById, id)
|
||||||
|
var i User
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Uid,
|
||||||
|
&i.Email,
|
||||||
|
&i.FullName,
|
||||||
|
&i.Displayname,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUserUid = `-- name: GetUserUid :one
|
||||||
|
SELECT uid FROM users WHERE id = $1 LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetUserUid(ctx context.Context, id int32) (string, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, getUserUid, id)
|
||||||
|
var uid string
|
||||||
|
err := row.Scan(&uid)
|
||||||
|
return uid, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateUserData = `-- name: UpdateUserData :exec
|
||||||
|
UPDATE users
|
||||||
|
SET email = COALESCE($2, email),
|
||||||
|
full_name = COALESCE($3, full_name),
|
||||||
|
displayname = COALESCE($4, displayname),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE uid = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateUserDataParams struct {
|
||||||
|
Uid string
|
||||||
|
Email sql.NullString
|
||||||
|
FullName sql.NullString
|
||||||
|
Displayname sql.NullString
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdateUserData(ctx context.Context, arg UpdateUserDataParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, updateUserData,
|
||||||
|
arg.Uid,
|
||||||
|
arg.Email,
|
||||||
|
arg.FullName,
|
||||||
|
arg.Displayname,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
35
modules/logger/logger.go
Normal file
35
modules/logger/logger.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Logger zerolog.Logger
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Logger = zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Info() *zerolog.Event {
|
||||||
|
return Logger.Info()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error() *zerolog.Event {
|
||||||
|
return Logger.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debug() *zerolog.Event {
|
||||||
|
return Logger.Debug()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatal() *zerolog.Event {
|
||||||
|
return Logger.Fatal()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLevel(level zerolog.Level) {
|
||||||
|
Logger = Logger.Level(level)
|
||||||
|
}
|
10
sqlc.yaml
Normal file
10
sqlc.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
version: "2"
|
||||||
|
sql:
|
||||||
|
- engine: "postgresql"
|
||||||
|
queries: "modules/db/*.sql"
|
||||||
|
schema: "migrations/*.sql"
|
||||||
|
gen:
|
||||||
|
go:
|
||||||
|
package: "db"
|
||||||
|
out: "modules/db/"
|
||||||
|
sql_package: "database/sql"
|
@ -1,87 +1,3 @@
|
|||||||
<h2>Welcome to My Go App</h2>
|
<h2>Welcome to My Go App</h2>
|
||||||
<p>This is the homepage.</p>
|
<p>This is the homepage.</p>
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
<p>This is the homepage.</p>
|
|
||||||
{{.T.about}}
|
{{.T.about}}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="stylesheet" href="static/css/styles.css" />
|
<link rel="stylesheet" href="/static/css/styles.css" />
|
||||||
<link rel="icon" href="/static/assets/favicon.ico" />
|
<link rel="icon" href="/static/assets/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#f28c18" />
|
<meta name="theme-color" content="#f28c18" />
|
||||||
|
Loading…
Reference in New Issue
Block a user