notion2ical/internal/config/config.go

100 lines
3.1 KiB
Go

package config
import (
"bufio"
"context"
"os"
"strings"
"time"
"github.com/fmartingr/notion2ical/internal/notion"
"github.com/sethvargo/go-envconfig"
"go.uber.org/zap"
)
// readDotEnv reads the configuration from variables in a .env file (only for contributing)
func readDotEnv(logger *zap.Logger) map[string]string {
file, err := os.Open(".env")
if err != nil {
return nil
}
defer file.Close()
result := make(map[string]string)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "#") {
continue
}
keyval := strings.SplitN(line, "=", 2)
result[keyval[0]] = keyval[1]
}
if err := scanner.Err(); err != nil {
logger.Fatal("error reading dotenv", zap.Error(err))
}
return result
}
type Config struct {
Hostname string `env:"HOSTNAME,required"`
LogLevel string `env:"LOG_LEVEL,default=info"`
Http struct {
Enabled bool `env:"HTTP_ENABLED,default=True"`
Port int `env:"HTTP_PORT,default=8080"`
PublicHostname string `env:"HTTP_PUBLIC_HOSTNAME,required"`
// Fiber Specific
BodyLimit int `env:"HTTP_BODY_LIMIT,default=1024"`
ReadTimeout time.Duration `env:"HTTP_READ_TIMEOUT,default=10s"`
WriteTimeout time.Duration `env:"HTTP_WRITE_TIMEOUT,default=10s"`
IDLETimeout time.Duration `env:"HTTP_IDLE_TIMEOUT,default=10s"`
DisableKeepAlive bool `env:"HTTP_DISABLE_KEEP_ALIVE,default=true"`
DisablePreParseMultipartForm bool `env:"HTTP_DISABLE_PARSE_MULTIPART_FORM,default=true"`
}
Branding struct {
ThanksMessage string `env:"BRANDING_THANKS_MESSAGE"`
FooterExtraMessage string `env:"BRANDING_FOOTER_EXTRA"`
}
Notion struct {
IntegrationToken string `env:"NOTION_INTEGRATION_TOKEN,required"`
MaxPagination int `env:"NOTION_MAX_PAGINATION,default=2"`
Client *notion.NotionClient // Must be manually set up
}
Routes struct {
Calendar struct {
CacheExpiration time.Duration `env:"ROUTES_CACHE_EXPIRATION,default=24h"`
CacheControl bool `env:"ROUTES_CACHE_CONTROL,default=true"`
LimiterMaxRequest int `env:"ROUTES_CALENDAR_LIMITER_MAX_REQUESTS,default=2"`
LimiterExpiration time.Duration `env:"ROUTES_CALENDAR_LIMITER_DURATION,default=1s"`
}
Static struct {
Path string `env:"ROUTES_STATIC_PATH,default=/static"`
MaxAge time.Duration `env:"ROUTES_STATIC_MAX_AGE,default=720h"`
}
System struct {
Path string `env:"ROUTES_SYSTEM_PATH,default=/system"`
}
}
}
func ParseServerConfiguration(ctx context.Context, logger *zap.Logger) *Config {
var cfg Config
lookuper := envconfig.MultiLookuper(
envconfig.MapLookuper(map[string]string{"HOSTNAME": os.Getenv("HOSTNAME")}),
envconfig.MapLookuper(readDotEnv(logger)),
envconfig.PrefixLookuper("NOTION2ICAL_", envconfig.OsLookuper()),
envconfig.OsLookuper(),
)
if err := envconfig.ProcessWith(ctx, &cfg, lookuper); err != nil {
logger.Fatal("Error parsing configuration: %s", zap.Error(err))
}
return &cfg
}