fixed some performance issues when pulling a large amount of messages
Signed-off-by: Michael <michael.lindman@gmail.com>
This commit is contained in:
parent
f12e865042
commit
6d4d7e3459
2
go.mod
2
go.mod
@ -5,6 +5,6 @@ go 1.16
|
||||
require (
|
||||
github.com/emersion/go-imap v1.2.0
|
||||
github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac // indirect
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63
|
||||
golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
)
|
||||
|
61
mail/mail.go
61
mail/mail.go
@ -3,11 +3,11 @@ package mail
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/client"
|
||||
@ -18,19 +18,6 @@ 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
|
||||
}
|
||||
|
||||
type Conn struct {
|
||||
Addr string
|
||||
Username string
|
||||
@ -76,20 +63,19 @@ func Login(conn Conn) (mail *Mail, err error) {
|
||||
return mail, nil
|
||||
}
|
||||
|
||||
func (mail *Mail) GetMessages(mailbox string, msgs int32) (*Messages, error) {
|
||||
var messages Messages
|
||||
func (mail *Mail) GetMessages(mailbox string, path string) error {
|
||||
mbox, err := mail.Client.Select(mailbox, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if mbox.Messages == 0 {
|
||||
return nil, errors.New("no messages in mailbox")
|
||||
return 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)
|
||||
imapMessages := make(chan *imap.Message, mbox.Messages)
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- mail.Client.Fetch(seqSet, []imap.FetchItem{imap.FetchEnvelope, section.FetchItem()}, imapMessages)
|
||||
@ -98,33 +84,26 @@ func (mail *Mail) GetMessages(mailbox string, msgs int32) (*Messages, error) {
|
||||
for msg := range imapMessages {
|
||||
body := msg.GetBody(§ion)
|
||||
if body == nil {
|
||||
return nil, errors.New("server didn't returned message body")
|
||||
return 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,
|
||||
fmt.Println(msg.Envelope.Subject)
|
||||
if err := Write(path, msg, body); err != nil {
|
||||
return err
|
||||
}
|
||||
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.Date.String()+".eml", body, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Write(path string, msg *imap.Message, literal imap.Literal) error {
|
||||
body, err := io.ReadAll(literal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(path+"/"+strconv.Itoa(int(msg.SeqNum))+"_"+msg.Envelope.Date.String()+".eml", body, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
13
main.go
13
main.go
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfgFile, mailbox, msgs := ui()
|
||||
cfgFile, mailbox := ui()
|
||||
cfg := NewConfig(*cfgFile)
|
||||
chErr, chDone := make(chan error), make(chan bool)
|
||||
for _, account := range cfg.Account {
|
||||
@ -34,17 +34,13 @@ func main() {
|
||||
}
|
||||
}
|
||||
defer conn.Client.Logout()
|
||||
messages, err := conn.GetMessages(*mailbox, int32(*msgs))
|
||||
if err != nil {
|
||||
chErr <- err
|
||||
}
|
||||
path := cfg.Path + username + "/" + time.Now().Format("2006-01-02-15:04:05")
|
||||
for _, p := range []string{cfg.Path + username, path} {
|
||||
if _, err := os.Stat(p); os.IsNotExist(err) {
|
||||
os.Mkdir(p, 0775)
|
||||
}
|
||||
}
|
||||
if err := mail.WriteMessages(path, messages); err != nil {
|
||||
if err = conn.GetMessages(*mailbox, path); err != nil {
|
||||
chErr <- err
|
||||
}
|
||||
}(account.Addr, account.Username, account.Password, chErr, chDone)
|
||||
@ -59,7 +55,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func ui() (cfgFile, mailbox *string, msgs *int) {
|
||||
func ui() (cfgFile, mailbox *string) {
|
||||
flag.Usage = func() {
|
||||
fmt.Printf("Usage of %s:\n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
@ -70,8 +66,7 @@ func ui() (cfgFile, mailbox *string, msgs *int) {
|
||||
}
|
||||
cfgFile = flag.String("cfgFile", home+"/.config/gomail/config.yaml", "path to config file")
|
||||
mailbox = flag.String("mailbox", "inbox", "mailbox to scan messages")
|
||||
msgs = flag.Int("msgs", 100, "Number of messages to pull")
|
||||
|
||||
flag.Parse()
|
||||
return cfgFile, mailbox, msgs
|
||||
return cfgFile, mailbox
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user