99 lines
2.1 KiB
Go
99 lines
2.1 KiB
Go
package mail
|
|
|
|
import (
|
|
"errors"
|
|
"io/ioutil"
|
|
"log"
|
|
"strconv"
|
|
"time"
|
|
|
|
"git.0cd.xyz/michael/gtools/colour"
|
|
"github.com/emersion/go-imap"
|
|
"github.com/emersion/go-imap/client"
|
|
)
|
|
|
|
type Mail struct {
|
|
Client *client.Client
|
|
}
|
|
|
|
type Message struct {
|
|
SeqNum uint32
|
|
Subject string
|
|
To []*imap.Address
|
|
From []*imap.Address
|
|
Date time.Time
|
|
Body imap.Literal
|
|
}
|
|
|
|
type Messages struct {
|
|
Message []Message
|
|
}
|
|
|
|
func Login(addr, username, password string) (mail *Mail, err error) {
|
|
colour.Green("Connecting to %s\n", addr)
|
|
client, err := client.DialTLS(addr, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err = client.Login(username, password); err != nil {
|
|
return nil, err
|
|
}
|
|
log.Println("Logged in as", username)
|
|
return &Mail{
|
|
Client: client,
|
|
}, nil
|
|
}
|
|
|
|
func (mail *Mail) GetMessages(mailbox string, msgs int32) (*Messages, error) {
|
|
var messages Messages
|
|
mbox, err := mail.Client.Select(mailbox, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if mbox.Messages == 0 {
|
|
return nil, errors.New("no messages in mailbox")
|
|
}
|
|
seqSet := new(imap.SeqSet)
|
|
seqSet.AddRange(1, mbox.Messages)
|
|
var section imap.BodySectionName
|
|
|
|
imapMessages := make(chan *imap.Message, msgs)
|
|
done := make(chan error, 1)
|
|
go func() {
|
|
done <- mail.Client.Fetch(seqSet, []imap.FetchItem{imap.FetchEnvelope, section.FetchItem()}, imapMessages)
|
|
}()
|
|
|
|
for msg := range imapMessages {
|
|
body := msg.GetBody(§ion)
|
|
if body == nil {
|
|
return nil, errors.New("server didn't returned message body")
|
|
}
|
|
message := Message{
|
|
SeqNum: msg.SeqNum,
|
|
Subject: msg.Envelope.Subject,
|
|
To: msg.Envelope.To,
|
|
From: msg.Envelope.From,
|
|
Date: msg.Envelope.Date,
|
|
Body: body,
|
|
}
|
|
messages.Message = append(messages.Message, message)
|
|
}
|
|
if err := <-done; err != nil {
|
|
return nil, err
|
|
}
|
|
return &messages, nil
|
|
}
|
|
|
|
func WriteMessages(path string, messages *Messages) error {
|
|
for _, msg := range messages.Message {
|
|
body, err := ioutil.ReadAll(msg.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := ioutil.WriteFile(path+"/"+strconv.Itoa(int(msg.SeqNum))+"_"+msg.To[0].Address()+".eml", body, 0644); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|