Files
keikos.work/app/app.go

147 lines
2.9 KiB
Go

package app
import (
"context"
"errors"
"fmt"
"log/slog"
"net/http"
"forge.capytal.company/capytalcode/project-comicverse/lib/middleware"
"forge.capytal.company/capytalcode/project-comicverse/lib/router"
"forge.capytal.company/capytalcode/project-comicverse/lib/router/rerrors"
"github.com/minio/minio-go/v7"
"keikos.work/assets"
"keikos.work/configs"
"keikos.work/handlers/pages"
)
type App interface {
Start() error
Stop() error
}
type Options struct {
Port uint
Development bool
Log *slog.Logger
S3 *minio.Client
Assets http.Handler
}
type app struct {
log *slog.Logger
s3 *minio.Client
assets http.Handler
server *http.Server
}
func (a *app) Start() error {
if err := a.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
return err
}
return nil
}
func (a *app) Stop() error {
if err := a.server.Shutdown(context.Background()); err != nil {
return err
}
return nil
}
func NewWeb(opts Options) App {
r := router.NewRouter()
r.Use(middleware.NewLoggerMiddleware(opts.Log))
if opts.Development {
configs.DEVELOPMENT = true
r.Use(middleware.DevMiddleware)
} else {
r.Use(middleware.CacheMiddleware)
}
r.Use(rerrors.NewErrorMiddleware(pages.ErrorPage{}.Component, opts.Log))
r.Handle("/", &pages.Home{})
r.Handle("/assets/", opts.Assets)
robots, err := assets.ASSETS.ReadFile("robots.txt")
if err != nil {
panic(err)
}
r.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
if _, err := w.Write(robots); err != nil {
rerrors.InternalError(err).ServeHTTP(w, r)
}
})
ai, err := assets.ASSETS.ReadFile("ai.txt")
if err != nil {
panic(err)
}
r.HandleFunc("/ai.txt", func(w http.ResponseWriter, r *http.Request) {
if _, err := w.Write(ai); err != nil {
rerrors.InternalError(err).ServeHTTP(w, r)
}
})
// imgs := &pages.Images{S3: opts.S3}
// r.HandleFunc("GET /images", imgs.List)
// r.HandleFunc("GET /images/{name}", imgs.Get)
srv := http.Server{
Addr: fmt.Sprintf(":%d", opts.Port),
Handler: r,
}
return &app{
log: opts.Log,
s3: opts.S3,
assets: opts.Assets,
server: &srv,
}
}
func NewAdmin(opts Options) App {
r := router.NewRouter()
r.Use(middleware.NewLoggerMiddleware(opts.Log))
if opts.Development {
configs.DEVELOPMENT = true
r.Use(middleware.DevMiddleware)
} else {
r.Use(middleware.CacheMiddleware)
}
r.Use(rerrors.NewErrorMiddleware(pages.ErrorPage{}.Component, opts.Log))
r.Handle("/", &pages.Dashboard{})
r.Handle("/assets/", opts.Assets)
imgs := &pages.Images{S3: opts.S3}
r.HandleFunc("GET /images", imgs.List)
r.HandleFunc("GET /images/{name}", imgs.Get)
r.HandleFunc("POST /images", imgs.Create)
r.HandleFunc("PUT /images/{name}", imgs.Update)
r.HandleFunc("DELETE /images/{name}", imgs.Delete)
srv := http.Server{
Addr: fmt.Sprintf(":%d", opts.Port),
Handler: r,
}
return &app{
log: opts.Log,
s3: opts.S3,
assets: opts.Assets,
server: &srv,
}
}