feat: initial commit
This commit is contained in:
31
internal/setup/api_handler.go
Normal file
31
internal/setup/api_handler.go
Normal file
@ -0,0 +1,31 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/config"
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/http/handler/api"
|
||||
"github.com/bornholm/genai/llm/provider"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
_ "github.com/bornholm/genai/llm/provider/all"
|
||||
)
|
||||
|
||||
func NewAPIHandlerFromConfig(ctx context.Context, conf *config.Config) (*api.Handler, error) {
|
||||
store, err := getStoreFromConfig(ctx, conf)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
llm, err := provider.Create(ctx, provider.WithChatCompletionOptions(provider.ClientOptions{
|
||||
Provider: conf.LLM.Provider,
|
||||
BaseURL: conf.LLM.BaseURL,
|
||||
APIKey: conf.LLM.APIKey,
|
||||
Model: conf.LLM.Model,
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return api.NewHandler(store, llm, conf.Quiz.PlayInterval, conf.Quiz.PlayPeriod), nil
|
||||
}
|
34
internal/setup/helper.go
Normal file
34
internal/setup/helper.go
Normal file
@ -0,0 +1,34 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/config"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func createFromConfigOnce[T any](factory func(ctx context.Context, conf *config.Config) (T, error)) func(ctx context.Context, conf *config.Config) (T, error) {
|
||||
var (
|
||||
once sync.Once
|
||||
service T
|
||||
onceErr error
|
||||
)
|
||||
|
||||
return func(ctx context.Context, conf *config.Config) (T, error) {
|
||||
once.Do(func() {
|
||||
srv, err := factory(ctx, conf)
|
||||
if err != nil {
|
||||
onceErr = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
service = srv
|
||||
})
|
||||
if onceErr != nil {
|
||||
return *new(T), onceErr
|
||||
}
|
||||
|
||||
return service, nil
|
||||
}
|
||||
}
|
@ -2,25 +2,37 @@ package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/config"
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/http"
|
||||
kouizHTTP "forge.cadoles.com/wpetit/kouiz/internal/http"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func NewHTTPServerFromConfig(ctx context.Context, conf *config.Config) (*http.Server, error) {
|
||||
func NewHTTPServerFromConfig(ctx context.Context, conf *config.Config) (*kouizHTTP.Server, error) {
|
||||
// Configure Web UI handler
|
||||
webui, err := NewWebUIHandlerFromConfig(ctx, conf)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not configure webui handler from config")
|
||||
}
|
||||
|
||||
// Configure API handler
|
||||
api, err := NewAPIHandlerFromConfig(ctx, conf)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not configure webui handler from config")
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("/", webui)
|
||||
mux.Handle("/api/", http.StripPrefix("/api", api))
|
||||
|
||||
// Create HTTP server
|
||||
|
||||
server := http.NewServer(
|
||||
webui,
|
||||
http.WithAddress(conf.HTTP.Address),
|
||||
http.WithBaseURL(conf.HTTP.BaseURL),
|
||||
server := kouizHTTP.NewServer(
|
||||
mux,
|
||||
kouizHTTP.WithAddress(conf.HTTP.Address),
|
||||
kouizHTTP.WithBaseURL(conf.HTTP.BaseURL),
|
||||
)
|
||||
|
||||
return server, nil
|
||||
|
@ -3,34 +3,21 @@ package setup
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/config"
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/http/handler/webui/quiz"
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/store"
|
||||
"forge.cadoles.com/wpetit/kouiz/misc/quiz/openquizzdb"
|
||||
"github.com/glebarez/sqlite"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewQuizHandlerFromConfig(ctx context.Context, conf *config.Config) (*quiz.Handler, error) {
|
||||
db, err := gorm.Open(sqlite.Open(string(conf.Store.DSN)), &gorm.Config{
|
||||
NowFunc: func() time.Time {
|
||||
return time.Now().UTC()
|
||||
},
|
||||
})
|
||||
store, err := getStoreFromConfig(ctx, conf)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if conf.Store.Debug {
|
||||
db = db.Debug()
|
||||
}
|
||||
|
||||
store := store.New(db)
|
||||
|
||||
if err := loadEmbeddedQuizz(ctx, store); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
32
internal/setup/store.go
Normal file
32
internal/setup/store.go
Normal file
@ -0,0 +1,32 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/config"
|
||||
"forge.cadoles.com/wpetit/kouiz/internal/store"
|
||||
"github.com/glebarez/sqlite"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var getStoreFromConfig = createFromConfigOnce(func(ctx context.Context, conf *config.Config) (*store.Store, error) {
|
||||
db, err := gorm.Open(sqlite.Open(string(conf.Store.DSN)), &gorm.Config{
|
||||
NowFunc: func() time.Time {
|
||||
return time.Now().UTC()
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if conf.Store.Debug {
|
||||
db = db.Debug()
|
||||
}
|
||||
|
||||
store := store.New(db)
|
||||
|
||||
return store, nil
|
||||
|
||||
})
|
Reference in New Issue
Block a user