Files
ddc/internal/config/config.go
T
2026-10-25 20:24:50 -04:00

74 lines
2.1 KiB
Go
Executable File

package config
import (
"errors"
"fmt"
"path/filepath"
"time"
"ddc/internal/preferences"
)
const (
minPasswordLength = 12
defaultLibraryRoots = "/media/blob/TeaNet/Plex;/media/blob/ChaiNet/Plex"
)
type Settings struct {
ListenAddr string
Username string
Password string
CookieSecure bool
SessionTTL time.Duration
TrustProxyHeaders bool
DownloadDir string
LibraryRoots []string
Defaults preferences.Preferences
}
func Load() (Settings, error) {
reader := &envReader{}
settings := Settings{
ListenAddr: reader.text("LISTEN_ADDR", ":8080"),
Username: reader.text("AUTH_USERNAME", ""),
Password: reader.text("AUTH_PASSWORD", ""),
CookieSecure: reader.boolean("COOKIE_SECURE", true),
SessionTTL: time.Duration(reader.integer("SESSION_TTL_HOURS", 12)) * time.Hour,
TrustProxyHeaders: reader.boolean("TRUST_PROXY_HEADERS", false),
DownloadDir: filepath.Clean(reader.text("DOWNLOAD_DIR", "/data/downloads")),
Defaults: preferences.Preferences{
MaxConcurrentDownloads: reader.integer("MAX_CONCURRENT_DOWNLOADS", 2),
MinFreeGB: reader.integer("MIN_FREE_GB", 10),
AllowedPorts: reader.ports("ALLOWED_PORTS", "80,443"),
AutoExtract: true,
CleanupAfterMove: true,
},
}
rawRoots := reader.text("LIBRARY_ROOTS", defaultLibraryRoots)
if reader.err != nil {
return Settings{}, reader.err
}
roots, err := parseLibraryRoots(rawRoots)
if err != nil {
return Settings{}, err
}
settings.LibraryRoots = roots
return settings, settings.validate()
}
func (settings Settings) validate() error {
switch {
case settings.Username == "":
return errors.New("AUTH_USERNAME is required")
case len(settings.Password) < minPasswordLength:
return fmt.Errorf("AUTH_PASSWORD must be at least %d characters", minPasswordLength)
case !filepath.IsAbs(settings.DownloadDir):
return errors.New("DOWNLOAD_DIR must be an absolute path")
case settings.SessionTTL <= 0:
return errors.New("SESSION_TTL_HOURS must be greater than zero")
}
return settings.Defaults.Validate()
}