config.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. toml "github.com/pelletier/go-toml"
  6. )
  7. type Validation struct {
  8. Param string
  9. CmdFlag string
  10. ConfFlag string
  11. }
  12. type ServerConfig struct {
  13. Address string `toml:address,omitempty`
  14. Port int64 `toml:port,omitempty`
  15. Encryption bool `toml:encryption,omitempty`
  16. User string `toml:user,omitempty`
  17. Password string `toml:password,omitempty`
  18. }
  19. func (s ServerConfig) String() string {
  20. return fmt.Sprintf(
  21. "\tAddress: %s\n\tPort: %d\n\tEncryption: %t\n\tUser: %s\n\tPassword: %s\n",
  22. s.Address,
  23. s.Port,
  24. s.Encryption,
  25. s.User,
  26. s.Password,
  27. )
  28. }
  29. type Config struct {
  30. Server *ServerConfig `toml:server,omitempty`
  31. From string `toml:from,omitempty`
  32. To []string `toml:to,omitempty`
  33. Cc []string `toml:cc,omitempty`
  34. Bcc []string `toml:bcc,omitempty`
  35. Subject string `toml:subject,omitempty`
  36. Text string `toml:text,omitempty`
  37. }
  38. func (c Config) String() string {
  39. return fmt.Sprintf(
  40. "From: %s\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\nText:\n%s\nServer:\n%s",
  41. c.From,
  42. c.To,
  43. c.Cc,
  44. c.Bcc,
  45. c.Subject,
  46. c.Text,
  47. c.Server,
  48. )
  49. }
  50. func NewConfig() *Config {
  51. server := &ServerConfig{}
  52. config := &Config{}
  53. config.Server = server
  54. return config
  55. }
  56. func (s *ServerConfig) Merge(key string, value interface{}) {
  57. Merge(key, value, s)
  58. }
  59. func (c *Config) Merge(key string, value interface{}) {
  60. Merge(key, value, c)
  61. }
  62. func readConfig(configPath, section string) (*Config, error) {
  63. config := NewConfig()
  64. tree, err := toml.LoadFile(configPath)
  65. if err != nil {
  66. return config, err
  67. }
  68. keys := tree.Keys()
  69. if !IsPresent(keys, section) {
  70. return config, errors.New("missing section")
  71. }
  72. sub := tree.Get(section).(*toml.Tree)
  73. err = sub.Unmarshal(config)
  74. return config, err
  75. }
  76. func checkValidity(validations *[]Validation, obj interface{}, name, cmd, param string) {
  77. if IsEmpty(obj) {
  78. *validations = append(*validations, Validation{name, cmd, param})
  79. }
  80. }
  81. func (c *Config) Validate() error {
  82. var validations = []Validation{}
  83. var msg string
  84. checkValidity(&validations, c.Server.Address, "server address", "server-address", "server.address")
  85. checkValidity(&validations, c.Server.Port, "server port", "server-port", "server.port")
  86. if !c.Server.Encryption {
  87. Warning.Ln("Warning: not using encryption!")
  88. }
  89. checkValidity(&validations, c.Server.User, "username", "user", "server.user")
  90. checkValidity(&validations, c.Server.Password, "password", "password", "server.password")
  91. checkValidity(&validations, c.From, "from", "from", "from")
  92. checkValidity(&validations, c.To, "to", "to", "to")
  93. checkValidity(&validations, c.Subject, "subject", "sub", "subject")
  94. checkValidity(&validations, c.Text, "body", "", "text")
  95. Debug.F("Lengths:\n\tTo: %d\n\tCc: %d\n\tBcc: %d", len(c.To), len(c.Cc), len(c.Bcc))
  96. if len(validations) > 0 {
  97. for _, v := range validations {
  98. if v.CmdFlag == "" {
  99. msg += fmt.Sprintf("%s: pass a value either via stdin or in configuration file section (%s)\n", v.Param, v.ConfFlag)
  100. } else {
  101. msg += fmt.Sprintf("%s: pass a value either via command line (-%s) or in configuration file section (%s)\n", v.Param, v.CmdFlag, v.ConfFlag)
  102. }
  103. }
  104. return errors.New(msg)
  105. }
  106. return nil
  107. }