config.go 3.6 KB

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