85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type EpisodeAvailabilityMode string
|
|
|
|
const (
|
|
EpisodeAvailabilityModeAuto EpisodeAvailabilityMode = "auto"
|
|
EpisodeAvailabilityModeLegacy EpisodeAvailabilityMode = "legacy"
|
|
EpisodeAvailabilityModeJikan EpisodeAvailabilityMode = "jikan"
|
|
)
|
|
|
|
type Config struct {
|
|
Port string
|
|
|
|
// GinMode maps to gin.SetMode. When empty, the server uses release mode by default.
|
|
GinMode string
|
|
|
|
DatabaseFile string
|
|
|
|
// Allow any Origin for CORS. Intended for local dev / reverse proxy setups only.
|
|
CORSAllowAll bool
|
|
|
|
EpisodeAvailabilityMode EpisodeAvailabilityMode
|
|
|
|
// Optional. When empty, proxy token signing is disabled.
|
|
PlaybackProxySecret string
|
|
|
|
// Optional debug toggle for Jikan client tracing.
|
|
JikanTrace bool
|
|
}
|
|
|
|
func Load() (Config, error) {
|
|
cfg := Config{
|
|
Port: firstNonEmpty(strings.TrimSpace(os.Getenv("PORT")), "3000"),
|
|
GinMode: strings.TrimSpace(os.Getenv("GIN_MODE")),
|
|
DatabaseFile: firstNonEmpty(strings.TrimSpace(os.Getenv("DATABASE_FILE")), "mal.db"),
|
|
CORSAllowAll: strings.TrimSpace(os.Getenv("MAL_CORS_ALLOW_ALL")) == "1",
|
|
PlaybackProxySecret: strings.TrimSpace(os.Getenv("PLAYBACK_PROXY_SECRET")),
|
|
JikanTrace: truthy(strings.TrimSpace(os.Getenv("MAL_JIKAN_TRACE"))),
|
|
EpisodeAvailabilityMode: EpisodeAvailabilityModeAuto,
|
|
}
|
|
|
|
if raw := strings.ToLower(strings.TrimSpace(os.Getenv("EPISODE_AVAILABILITY_MODE"))); raw != "" {
|
|
switch EpisodeAvailabilityMode(raw) {
|
|
case EpisodeAvailabilityModeAuto, EpisodeAvailabilityModeLegacy, EpisodeAvailabilityModeJikan:
|
|
cfg.EpisodeAvailabilityMode = EpisodeAvailabilityMode(raw)
|
|
default:
|
|
return Config{}, fmt.Errorf("invalid EPISODE_AVAILABILITY_MODE: %q (expected auto|legacy|jikan)", raw)
|
|
}
|
|
}
|
|
|
|
if strings.TrimSpace(cfg.Port) == "" {
|
|
return Config{}, errors.New("PORT must not be empty")
|
|
}
|
|
if strings.TrimSpace(cfg.DatabaseFile) == "" {
|
|
return Config{}, errors.New("DATABASE_FILE must not be empty")
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func firstNonEmpty(values ...string) string {
|
|
for _, v := range values {
|
|
if strings.TrimSpace(v) != "" {
|
|
return v
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func truthy(v string) bool {
|
|
switch strings.ToLower(strings.TrimSpace(v)) {
|
|
case "1", "true", "yes", "y", "on":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|