// Copyright 2023 wanderer // SPDX-License-Identifier: AGPL-3.0-only package app import ( "embed" "io/fs" "git.dotya.ml/mirre-mt/pcmt/app/settings" "git.dotya.ml/mirre-mt/pcmt/ent" modfuncmap "git.dotya.ml/mirre-mt/pcmt/modules/funcmap" "git.dotya.ml/mirre-mt/pcmt/slogging" "github.com/labstack/echo/v4" gommonlog "github.com/labstack/gommon/log" "golang.org/x/exp/slog" ) type App struct { e *echo.Echo slogger *slogging.Slogger logger slogging.Slogger initialised bool embeds Embeds templatesPath string assetsPath string setting *settings.Settings jwtkey string //nolint:unused encryptionKey string //nolint:unused dbConnect string //nolint:unused db *ent.Client } type Embeds struct { templates embed.FS assets embed.FS } // Init allows setting App's important fields - once. func (a *App) Init(s *settings.Settings, logger *slogging.Slogger, dbclient *ent.Client) error { if !a.initialised { e := echo.New() a.e = e a.slogger = logger a.logger = *a.slogger a.logger.Logger = a.logger.Logger.With( slog.Group("pcmt extra", slog.String("module", "app")), ) a.setting = s if a.setting.IsDevel() { a.setDevel() } a.Logger().Infof("app version: %s", a.setting.Version()) a.Logger().Debug("saving db client object") a.db = dbclient if a.templatesPath == "" { a.templatesPath = "templates" a.setting.SetTemplatesPath("templates") } else { a.setting.SetTemplatesPath(a.templatesPath) } if a.assetsPath == "" { a.Logger().Debug("setting assets path as unset") a.assetsPath = "assets/public" a.setting.SetAssetsPath("assets") } else { a.setting.SetAssetsPath(a.assetsPath) } a.initialised = true a.Logger().Info("app initialised") return nil } return ErrAppAlreadyInitialised } // E returns app's *echo.Echo instance. func (a *App) E() *echo.Echo { return a.e } // Logger returns app's pointer to the global logger instance. func (a *App) Logger() *slogging.Slogger { return &a.logger } // PrintConfiguration outputs relevant settings of the application to console. func (a *App) PrintConfiguration() { if a.setting != nil { if a.setting.IsLive() { a.Logger().Debug("live mode enabled") } if a.setting.IsDevel() { a.Logger().Debug("devel mode enabled - make sure that browser-sync is running") } return } panic(ErrAppSettingsUnset) } func (a *App) SetSettings(s *settings.Settings) { a.setting = s } // SetEmbeds saves the embedded files to application state. func (a *App) SetEmbeds(templates, assets embed.FS) { if !a.setting.IsLive() { a.Logger().Debug("saving embeds in the app struct") a.embeds.templates = templates a.embeds.assets = assets var fsfs fs.FS = &assets // save pointer to assets to funcmap for integrity calculations. modfuncmap.SetEmbeds(&fsfs) } } // setDevel puts the app in devel mode, which loads a browser-sync script in // templates and expects browser-sync running. func (a *App) setDevel() { a.Logger().Debug("enabling debug logging for Echo") a.e.Debug = true a.e.Logger.SetLevel(gommonlog.DEBUG) }