diff --git a/email.go b/email.go new file mode 100644 index 0000000..750e479 --- /dev/null +++ b/email.go @@ -0,0 +1,157 @@ +package webutility + +// TODO(markO): test test test test test (and open source?) + +import ( + "crypto/tls" + "errors" + "fmt" + "net/smtp" + "strings" +) + +type EmailConfig struct { + ServerName string + Identity string + Username string + Password string + Host string + Port int +} + +func NewEmailConfig(ident, uname, pword, host string, port int) *EmailConfig { + return &EmailConfig{ + ServerName: host + fmt.Sprintf(":%d", port), + Identity: ident, + Username: uname, + Password: pword, + Host: host, + Port: port, + } +} + +type Email struct { + To []string + From string + Subject string + Body string +} + +func NewEmail(to []string, from, subject, body string) *Email { + return &Email{ + To: to, + From: from, + Subject: subject, + Body: body, + } +} + +func SendEmail(email *Email, conf *EmailConfig) error { + if email == nil { + return errors.New("no email to send") + + } + + if conf == nil { + // use (some?) default settings + conf = NewEmailConfig("", "marko.tikvic@to-net.rs", "quantumleap010", "mail.to-net.rs", 25) + } + + c, err := smtp.Dial(conf.ServerName) + if err != nil { + return err + } + + defer c.Close() + + // not sure if this is needed + //if err = c.Hello(conf.ServerName); err != nil { + // return err + //} + + if ok, _ := c.Extension("STARTTLS"); ok { + // disable stupid tls check for self-signed certificates + config := &tls.Config{ + ServerName: conf.ServerName, + InsecureSkipVerify: true, + } + // for golang testing + //if testHookStartTLS != nil { + // testHookStartTLS(config) + //} + if err = c.StartTLS(config); err != nil { + return err + } + } + + /* + // don't know what to do with this + if a != nil && c.ext != nil { + if _, ok := c.ext["AUTH"]; !ok { + return errors.New("smtp: server doesn't support AUTH") + } + if err = c.Auth(a); err != nil { + return err + } + } + */ + + // Set up authentication information. + auth := smtp.PlainAuth(conf.Identity, conf.Username, conf.Password, conf.Host) + if err = c.Auth(auth); err != nil { + return err + } + + if err = c.Mail(email.From); err != nil { + return err + } + + for _, addr := range email.To { + if err = c.Rcpt(addr); err != nil { + return err + } + } + + w, err := c.Data() + if err != nil { + return err + } + + _, err = w.Write(email.Bytes()) + if err != nil { + return err + } + + err = w.Close() + if err != nil { + return err + } + + return c.Quit() +} + +func (e *Email) String() string { + var str strings.Builder + + str.WriteString("From:" + e.From + "\r\n") + + str.WriteString("To:") + for i, _ := range e.To { + if i > 0 { + str.WriteString(",") + } + str.WriteString(e.To[i]) + } + str.WriteString("\r\n") + + str.WriteString("Subject:" + e.Subject + "\r\n") + + // body + str.WriteString("\r\n" + e.Body + "\r\n") + + return str.String() +} + +func (e *Email) Bytes() []byte { + return []byte(e.String()) +} diff --git a/filtering.go b/filtering.go index 4f11fa4..8ad95ac 100644 --- a/filtering.go +++ b/filtering.go @@ -73,8 +73,7 @@ func MakeFilterString(prefix string, filters Filter, validFilters []string) (res } c := string(v[0]) if c == "<" || c == ">" { - symbol = c - v = string(v[1:]) + symbol = "" // examples: >3, >=3 } else { symbol = "=" }