1package config23import (4 "context"5 "log/slog"6 "net/url"7 "os"8 "path"9 "time"1011 "github.com/BurntSushi/toml"12)1314type Config struct {15 Log struct {16 Level string `toml:"level"`17 } `toml:"log"`1819 Http struct {20 Home string `toml:"home"`21 Listen string `toml:"listen"`22 IndexPage string `toml:"index-page"`23 MetricsListen string `toml:"metrics-listen"`24 } `toml:"http"`2526 LMTP struct {27 Listen string `toml:"listen"`28 ConnTimeout time.Duration `toml:"connection-timeout"`29 MaxDataSize string `toml:"max-data-size"`30 } `toml:"lmtp"`3132 Storage struct {33 Driver string `toml:"driver"`34 DSN string `toml:"dsn"`35 } `toml:"storage"`3637 SMTP struct {38 Address string `toml:"address"`39 ConnType string `toml:"connection-type"`40 AuthUser string `toml:"username"`41 AuthPassword string `toml:"password"`42 Sender string `toml:"sender"`43 } `toml:"smtp"`44}4546var DefaultConfig = &Config{47 Log: struct {48 Level string `toml:"level"`49 }{"info"},50 Storage: struct {51 Driver string `toml:"driver"`52 DSN string `toml:"dsn"`53 }{"sqlite3", "./mlisting.db"},54}5556func (cfg *Config) NewLogger() Logger {57 var leveler slog.Leveler58 switch cfg.Log.Level {59 case "debug":60 leveler = slog.LevelDebug61 case "info":62 leveler = slog.LevelInfo63 case "warn":64 leveler = slog.LevelWarn65 case "error":66 leveler = slog.LevelError67 default:68 leveler = slog.LevelInfo69 }70 logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{71 Level: leveler,72 }))73 return logger74}7576func (cfg *Config) HttpRealUrl(abs string) (real string) {77 if len(abs) > 0 && abs[0] != '/' {78 panic("only can get real url from abs path")79 }8081 if cfg.Http.Home != "" {82 u, err := url.Parse(cfg.Http.Home)83 if err != nil {84 panic(err)85 }86 if abs == "/" {87 return u.Path88 } else {89 real = path.Join(u.Path, abs)90 }91 } else {92 if abs == "/" {93 return "/"94 } else {95 real = path.Join("/", abs)96 }97 }98 if abs[len(abs)-1] == '/' {99 real = real + "/"100 }101 return102}103104func ParseToml(fpath string) (*Config, error) {105 f, err := os.Open(fpath)106 if err != nil {107 return nil, err108 }109 defer f.Close()110111 var cfg = new(Config)112 if _, err := toml.NewDecoder(f).Decode(cfg); err != nil {113 return nil, err114 }115 return cfg, nil116}117118var ContextKey = struct{ key string }{"config"}119120func Context(ctx context.Context, cfg *Config) context.Context {121 return context.WithValue(ctx, ContextKey, cfg)122}123124func FromContext(ctx context.Context) *Config {125 cfg, ok := ctx.Value(ContextKey).(*Config)126 if !ok {127 return DefaultConfig128 }129 return cfg130}