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 { 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) } // 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) }) 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 }