185 lines
4.7 KiB
Go
185 lines
4.7 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
|
|
mysqlDriver "github.com/go-sql-driver/mysql"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type Config struct {
|
|
Server ServerConfig `yaml:"server"`
|
|
Database DatabaseConfig `yaml:"database"`
|
|
Pricing PricingConfig `yaml:"pricing"`
|
|
Export ExportConfig `yaml:"export"`
|
|
Alerts AlertsConfig `yaml:"alerts"`
|
|
Notifications NotificationsConfig `yaml:"notifications"`
|
|
Logging LoggingConfig `yaml:"logging"`
|
|
Backup BackupConfig `yaml:"backup"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Host string `yaml:"host"`
|
|
Port int `yaml:"port"`
|
|
Mode string `yaml:"mode"`
|
|
ReadTimeout time.Duration `yaml:"read_timeout"`
|
|
WriteTimeout time.Duration `yaml:"write_timeout"`
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Host string `yaml:"host"`
|
|
Port int `yaml:"port"`
|
|
Name string `yaml:"name"`
|
|
User string `yaml:"user"`
|
|
Password string `yaml:"password"`
|
|
MaxOpenConns int `yaml:"max_open_conns"`
|
|
MaxIdleConns int `yaml:"max_idle_conns"`
|
|
ConnMaxLifetime time.Duration `yaml:"conn_max_lifetime"`
|
|
}
|
|
|
|
func (d *DatabaseConfig) DSN() string {
|
|
cfg := mysqlDriver.NewConfig()
|
|
cfg.User = d.User
|
|
cfg.Passwd = d.Password
|
|
cfg.Net = "tcp"
|
|
cfg.Addr = net.JoinHostPort(d.Host, strconv.Itoa(d.Port))
|
|
cfg.DBName = d.Name
|
|
cfg.ParseTime = true
|
|
cfg.Loc = time.Local
|
|
cfg.Params = map[string]string{
|
|
"charset": "utf8mb4",
|
|
}
|
|
return cfg.FormatDSN()
|
|
}
|
|
|
|
type PricingConfig struct {
|
|
DefaultMethod string `yaml:"default_method"`
|
|
DefaultPeriodDays int `yaml:"default_period_days"`
|
|
FreshnessGreenDays int `yaml:"freshness_green_days"`
|
|
FreshnessYellowDays int `yaml:"freshness_yellow_days"`
|
|
FreshnessRedDays int `yaml:"freshness_red_days"`
|
|
MinQuotesForMedian int `yaml:"min_quotes_for_median"`
|
|
PopularityDecayDays int `yaml:"popularity_decay_days"`
|
|
}
|
|
|
|
type ExportConfig struct {
|
|
TempDir string `yaml:"temp_dir"`
|
|
MaxFileAge time.Duration `yaml:"max_file_age"`
|
|
CompanyName string `yaml:"company_name"`
|
|
}
|
|
|
|
type AlertsConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
CheckInterval time.Duration `yaml:"check_interval"`
|
|
HighDemandThreshold int `yaml:"high_demand_threshold"`
|
|
TrendingThresholdPercent int `yaml:"trending_threshold_percent"`
|
|
}
|
|
|
|
type NotificationsConfig struct {
|
|
EmailEnabled bool `yaml:"email_enabled"`
|
|
SMTPHost string `yaml:"smtp_host"`
|
|
SMTPPort int `yaml:"smtp_port"`
|
|
SMTPUser string `yaml:"smtp_user"`
|
|
SMTPPassword string `yaml:"smtp_password"`
|
|
FromAddress string `yaml:"from_address"`
|
|
}
|
|
|
|
type LoggingConfig struct {
|
|
Level string `yaml:"level"`
|
|
Format string `yaml:"format"`
|
|
Output string `yaml:"output"`
|
|
FilePath string `yaml:"file_path"`
|
|
}
|
|
|
|
type BackupConfig struct {
|
|
Time string `yaml:"time"`
|
|
}
|
|
|
|
func Load(path string) (*Config, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("reading config file: %w", err)
|
|
}
|
|
|
|
var cfg Config
|
|
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
|
return nil, fmt.Errorf("parsing config file: %w", err)
|
|
}
|
|
|
|
cfg.setDefaults()
|
|
|
|
return &cfg, nil
|
|
}
|
|
|
|
func (c *Config) setDefaults() {
|
|
if c.Server.Host == "" {
|
|
c.Server.Host = "127.0.0.1"
|
|
}
|
|
if c.Server.Port == 0 {
|
|
c.Server.Port = 8080
|
|
}
|
|
if c.Server.Mode == "" {
|
|
c.Server.Mode = "release"
|
|
}
|
|
if c.Server.ReadTimeout == 0 {
|
|
c.Server.ReadTimeout = 30 * time.Second
|
|
}
|
|
if c.Server.WriteTimeout == 0 {
|
|
c.Server.WriteTimeout = 30 * time.Second
|
|
}
|
|
|
|
if c.Database.Port == 0 {
|
|
c.Database.Port = 3306
|
|
}
|
|
if c.Database.MaxOpenConns == 0 {
|
|
c.Database.MaxOpenConns = 25
|
|
}
|
|
if c.Database.MaxIdleConns == 0 {
|
|
c.Database.MaxIdleConns = 5
|
|
}
|
|
if c.Database.ConnMaxLifetime == 0 {
|
|
c.Database.ConnMaxLifetime = 5 * time.Minute
|
|
}
|
|
|
|
if c.Pricing.DefaultMethod == "" {
|
|
c.Pricing.DefaultMethod = "weighted_median"
|
|
}
|
|
if c.Pricing.DefaultPeriodDays == 0 {
|
|
c.Pricing.DefaultPeriodDays = 90
|
|
}
|
|
if c.Pricing.FreshnessGreenDays == 0 {
|
|
c.Pricing.FreshnessGreenDays = 30
|
|
}
|
|
if c.Pricing.FreshnessYellowDays == 0 {
|
|
c.Pricing.FreshnessYellowDays = 60
|
|
}
|
|
if c.Pricing.FreshnessRedDays == 0 {
|
|
c.Pricing.FreshnessRedDays = 90
|
|
}
|
|
if c.Pricing.MinQuotesForMedian == 0 {
|
|
c.Pricing.MinQuotesForMedian = 3
|
|
}
|
|
|
|
if c.Logging.Level == "" {
|
|
c.Logging.Level = "info"
|
|
}
|
|
if c.Logging.Format == "" {
|
|
c.Logging.Format = "json"
|
|
}
|
|
if c.Logging.Output == "" {
|
|
c.Logging.Output = "stdout"
|
|
}
|
|
|
|
if c.Backup.Time == "" {
|
|
c.Backup.Time = "00:00"
|
|
}
|
|
}
|
|
|
|
func (c *Config) Address() string {
|
|
return net.JoinHostPort(c.Server.Host, strconv.Itoa(c.Server.Port))
|
|
}
|