config.go
⎇
Raw
1package config
2
3import (
4 "fmt"
5 "log/slog"
6 "os"
7 "path/filepath"
8 "strconv"
9 "strings"
10)
11
12type Config struct {
13 Port int
14 DataDir string
15 DBPath string
16 LibraryDir string
17 TempDir string
18 YTDLPPath string
19 FFmpegPath string
20 FFprobePath string
21 BaseURL string
22 Workers int
23 SchedulerInterval int
24 LogLevel string
25 LogFormat string
26 Username string
27 PasswordHash string
28}
29
30func New() *Config {
31 dataDir := getEnv("VIDARCHIVE_DATA_DIR", "./data")
32
33 return &Config{
34 Port: getEnvInt("VIDARCHIVE_PORT", 8080, 1),
35 DataDir: dataDir,
36 DBPath: getEnv("VIDARCHIVE_DB_PATH", filepath.Join(dataDir, "vidarchive.db")),
37 LibraryDir: getEnv("VIDARCHIVE_LIBRARY_DIR", filepath.Join(dataDir, "library")),
38 TempDir: getEnv("VIDARCHIVE_TEMP_DIR", filepath.Join(dataDir, "temp")),
39 YTDLPPath: getEnv("VIDARCHIVE_YTDLP_PATH", "yt-dlp"),
40 FFmpegPath: getEnv("VIDARCHIVE_FFMPEG_PATH", "ffmpeg"),
41 FFprobePath: getEnv("VIDARCHIVE_FFPROBE_PATH", "ffprobe"),
42 BaseURL: getEnv("VIDARCHIVE_BASE_URL", ""),
43 Workers: getEnvInt("VIDARCHIVE_WORKERS", 2, 1),
44 SchedulerInterval: getEnvInt("VIDARCHIVE_SCHEDULER_INTERVAL", 60, 1),
45 LogLevel: getEnv("VIDARCHIVE_LOG_LEVEL", "info"),
46 LogFormat: getEnv("VIDARCHIVE_LOG_FORMAT", "text"),
47 Username: os.Getenv("VIDARCHIVE_USERNAME"),
48 PasswordHash: os.Getenv("VIDARCHIVE_PASSWORD_HASH"),
49 }
50}
51
52// SetupLogging also redirects the stdlib log package, so output from
53// dependencies is formatted and levelled the same way.
54func (c *Config) SetupLogging() {
55 var level slog.Level
56 if err := level.UnmarshalText([]byte(c.LogLevel)); err != nil {
57 fmt.Fprintf(os.Stderr, "invalid VIDARCHIVE_LOG_LEVEL %q: %v, using info\n", c.LogLevel, err)
58 level = slog.LevelInfo
59 }
60
61 opts := &slog.HandlerOptions{Level: level}
62 var h slog.Handler = slog.NewTextHandler(os.Stderr, opts)
63 if strings.EqualFold(c.LogFormat, "json") {
64 h = slog.NewJSONHandler(os.Stderr, opts)
65 }
66 slog.SetDefault(slog.New(h))
67}
68
69func (c *Config) IsHTTPS() bool {
70 return strings.HasPrefix(c.BaseURL, "https://")
71}
72
73func getEnv(key, defaultVal string) string {
74 if v := os.Getenv(key); v != "" {
75 return v
76 }
77 return defaultVal
78}
79
80// getEnvInt falls back to the default below min: a zero or negative worker
81// count, tick interval or port stalls downloads, spins the scheduler or fails to
82// bind.
83func getEnvInt(key string, defaultVal, min int) int {
84 v := os.Getenv(key)
85 if v == "" {
86 return defaultVal
87 }
88 i, err := strconv.Atoi(v)
89 if err != nil {
90 fmt.Fprintf(os.Stderr, "invalid %s: %v, using default %d\n", key, err, defaultVal)
91 return defaultVal
92 }
93 if i < min {
94 fmt.Fprintf(os.Stderr, "invalid %s: %d is below the minimum %d, using default %d\n", key, i, min, defaultVal)
95 return defaultVal
96 }
97 return i
98}
99