121 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/base64"
 | 
						|
	"fmt"
 | 
						|
	"net/smtp"
 | 
						|
	"sort"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	log "github.com/sirupsen/logrus"
 | 
						|
)
 | 
						|
 | 
						|
type Email struct {
 | 
						|
	startTime time.Time
 | 
						|
	items     []string
 | 
						|
}
 | 
						|
 | 
						|
func NewEmail(now time.Time) *Email {
 | 
						|
	log.WithFields(log.Fields{"now": now}).Debugf("starting")
 | 
						|
	defer log.WithFields(log.Fields{"now": now}).Debugf("done")
 | 
						|
 | 
						|
	return &Email{startTime: now, items: make([]string, 0)}
 | 
						|
}
 | 
						|
 | 
						|
func (e *Email) AddItem(item string) {
 | 
						|
	log.WithFields(log.Fields{"item": item}).Debugf("starting")
 | 
						|
	defer log.WithFields(log.Fields{"item": item}).Debugf("done")
 | 
						|
	if cfg.Email.Active {
 | 
						|
		e.items = append(e.items, item)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (e *Email) Send(addr, from string, to []string) error {
 | 
						|
	log.WithFields(log.Fields{}).Debugf("starting")
 | 
						|
	defer log.WithFields(log.Fields{}).Debugf("done")
 | 
						|
 | 
						|
	if len(e.items) == 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	sort.Slice(e.items, func(i, j int) bool {
 | 
						|
		return e.items[i] < e.items[j]
 | 
						|
	})
 | 
						|
 | 
						|
	body := e.items[0]
 | 
						|
	for _, item := range e.items[1:] {
 | 
						|
		body = body + "\r\n" + item
 | 
						|
	}
 | 
						|
 | 
						|
	subject := fmt.Sprintf("Autobackup report (%s)", e.startTime)
 | 
						|
 | 
						|
	if err := SendMail(addr, from, subject, body, to); err != nil {
 | 
						|
		log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "SendMail", "error": err}).Errorf("")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
func SendMail(addr, from, subject, body string, to []string) error {
 | 
						|
	log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject}).Debugf("starting")
 | 
						|
	defer log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject}).Debugf("done")
 | 
						|
 | 
						|
	r := strings.NewReplacer("\r\n", "", "\r", "", "\n", "", "%0a", "", "%0d", "")
 | 
						|
 | 
						|
	c, err := smtp.Dial(addr)
 | 
						|
	if err != nil {
 | 
						|
		log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "smtp.Dial", "error": err}).Errorf("")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	defer c.Close()
 | 
						|
 | 
						|
	if err = c.Mail(r.Replace(from)); err != nil {
 | 
						|
		log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "client.Mail", "error": err}).Errorf("")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	for i := range to {
 | 
						|
		to[i] = r.Replace(to[i])
 | 
						|
		if err = c.Rcpt(to[i]); err != nil {
 | 
						|
			log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "client.Rcpt", "attr": to[i], "error": err}).Errorf("")
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	w, err := c.Data()
 | 
						|
	if err != nil {
 | 
						|
		log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "client.Date", "error": err}).Errorf("")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	msg := "Date: " + time.Now().Format("Mon, 02 Jan 2006 15:04:05 -0700") + "\r\n" +
 | 
						|
		"To: " + strings.Join(to, ",") + "\r\n" +
 | 
						|
		"From: " + from + "\r\n" +
 | 
						|
		"Subject: " + subject + "\r\n" +
 | 
						|
		"Content-Type: text/plain; charset=\"UTF-8\"\r\n" +
 | 
						|
		"Content-Transfer-Encoding: base64\r\n" +
 | 
						|
		"\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
 | 
						|
 | 
						|
	_, err = w.Write([]byte(msg))
 | 
						|
	if err != nil {
 | 
						|
		log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "writer.Write", "error": err}).Errorf("")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	err = w.Close()
 | 
						|
	if err != nil {
 | 
						|
		log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "writer.Close", "error": err}).Errorf("")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	if err = c.Quit(); err != nil {
 | 
						|
		log.WithFields(log.Fields{"addr": addr, "from": from, "subject": subject, "call": "client.Quit", "error": err}).Errorf("")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 |