infoalloggi-monorepo/apps/backend/config/config.go

127 lines
2.6 KiB
Go

package config
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strconv"
"sync"
"github.com/joho/godotenv"
"github.com/labstack/gommon/log"
)
// Config holds all application configuration
type Config struct {
Database struct {
Host string
Port int
User string
Password string
DBName string
SSLMode string
}
Images struct {
Enabled bool
ConcurrentLimit int
Path string
}
Videos struct {
Enabled bool
ConcurrentLimit int
Path string
}
Storage struct {
Endpoint string
Token string
}
Server struct {
Port int
}
}
var (
Cfg Config
once sync.Once
)
// Load initializes configuration once
func Load() *Config {
once.Do(func() {
// Try loading from .env file first
_ = godotenv.Load()
pwd, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Database config
Cfg.Database.Host = getEnv("PGHOST", "localhost")
Cfg.Database.Port = getEnvAsInt("PGPORT", 5432)
Cfg.Database.User = getEnv("POSTGRES_USER", "postgres")
Cfg.Database.Password = getEnv("POSTGRES_PASSWORD", "")
Cfg.Database.DBName = getEnv("POSTGRES_DB", "postgres")
Cfg.Database.SSLMode = getEnv("PGSSLMODE", "true")
// Image processing config
Cfg.Images.Enabled = getEnvAsBool("IMAGEOPTION", true)
Cfg.Images.ConcurrentLimit = getEnvAsInt("CONCURRENT_IMAGES", 5)
Cfg.Images.Path = filepath.Join(pwd, "images")
// Video processing config
Cfg.Videos.Enabled = getEnvAsBool("VIDEOOPTION", true)
Cfg.Videos.ConcurrentLimit = getEnvAsInt("CONCURRENT_VIDEOS", 2)
Cfg.Videos.Path = filepath.Join(pwd, "videos")
// Storage config
Cfg.Storage.Endpoint = getEnv("STORAGE_URL", "")
Cfg.Storage.Token = getEnv("STORAGE_TOKEN", "")
// Server config
Cfg.Server.Port = getEnvAsInt("PORT", 1323)
// Validate required config
if Cfg.Database.Password == "" {
fmt.Printf("required environment variable POSTGRES_PASSWORD not set\n")
}
})
if err := exec.Command("ffmpeg", "-version").Run(); err != nil {
log.Errorf("FFmpeg not found: %v", err)
Cfg.Videos.Enabled = false
}
return &Cfg
}
// Helper functions
func getEnv(key, fallback string) string {
if value, exists := os.LookupEnv(key); exists {
return value
}
return fallback
}
func getEnvAsInt(key string, fallback int) int {
if strValue := getEnv(key, ""); strValue != "" {
if value, err := strconv.Atoi(strValue); err == nil {
return value
}
}
return fallback
}
func getEnvAsBool(key string, fallback bool) bool {
if strValue := getEnv(key, ""); strValue != "" {
if value, err := strconv.ParseBool(strValue); err == nil {
return value
}
}
return fallback
}