Selectively print header and body of message

This commit is contained in:
Blallo 2021-02-01 23:13:23 +01:00
parent 28e0b28a71
commit 75aae2c509
No known key found for this signature in database
GPG key ID: 0CBE577C9B72DC3F
2 changed files with 96 additions and 39 deletions

View file

@ -213,7 +213,11 @@ func (c CatMsgCmd) Func(args []string) error {
Log.Debug("enter info display-message") Log.Debug("enter info display-message")
} }
var idList []uint32 var idList []uint32
var withHeaders, withBody, markRead bool
flagset := flag.NewFlagSet(args[0], flag.ExitOnError) flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.BoolVar(&withHeaders, "headers", false, "toggle headers display")
flagset.BoolVar(&withBody, "no-body", false, "hide body")
flagset.BoolVar(&markRead, "seen", false, "mark as seen if not yet seen")
flagset.Usage = func() { c.Help(os.Stdout, flagset) } flagset.Usage = func() { c.Help(os.Stdout, flagset) }
flagset.Parse(args[1:]) flagset.Parse(args[1:])
@ -236,13 +240,24 @@ func (c CatMsgCmd) Func(args []string) error {
} }
} }
messages, err := imaputils.FetchMessages(Session.Config, mailbox, idList, Session.Info.Opts.Debug) opts := &imaputils.FetchOpts{
Mailbox: mailbox,
IdList: idList,
WithHeaders: withHeaders,
WithBody: !withBody,
Peek: !markRead,
}
if Session.Info.Opts.Debug {
Log.Debug(opts)
}
messages, err := imaputils.FetchMessages(Session.Config, opts, Session.Info.Opts.Debug)
if err != nil { if err != nil {
return err return err
} }
for _, m := range messages { for _, m := range messages {
err = printMessage(m) err = printMessage(m, opts)
if err != nil { if err != nil {
return err return err
} }
@ -271,9 +286,10 @@ func parseToUint32(s string) (uint32, error) {
return uint32(out), nil return uint32(out), nil
} }
func printMessage(m *imap.Message) error { func printMessage(m *imap.Message, opts *imaputils.FetchOpts) error {
var out string var out string
if opts.WithHeaders {
out += fmt.Sprintln(formatAddresses(m.Envelope.From, "From")) out += fmt.Sprintln(formatAddresses(m.Envelope.From, "From"))
out += fmt.Sprintln(formatAddresses(m.Envelope.Sender, "Sender")) out += fmt.Sprintln(formatAddresses(m.Envelope.Sender, "Sender"))
out += fmt.Sprintln(formatAddresses(m.Envelope.Cc, "Cc")) out += fmt.Sprintln(formatAddresses(m.Envelope.Cc, "Cc"))
@ -283,12 +299,24 @@ func printMessage(m *imap.Message) error {
out += fmt.Sprintf("Date: %v\n", m.Envelope.Date) out += fmt.Sprintf("Date: %v\n", m.Envelope.Date)
out += fmt.Sprintf("Subject: %s\n", m.Envelope.Subject) out += fmt.Sprintf("Subject: %s\n", m.Envelope.Subject)
bodyReader := m.GetBody(&imap.BodySectionName{BodyPartName: imap.BodyPartName{}, Peek: true}) headersSec := &imap.BodySectionName{Peek: opts.Peek, BodyPartName: imap.BodyPartName{Specifier: imap.HeaderSpecifier}}
headersReader := m.GetBody(headersSec)
headers, err := ioutil.ReadAll(headersReader)
if err != nil {
return err
}
out += fmt.Sprintln(string(headers))
}
if opts.WithBody {
bodySec := &imap.BodySectionName{Peek: opts.Peek, BodyPartName: imap.BodyPartName{Specifier: imap.TextSpecifier}}
bodyReader := m.GetBody(bodySec)
body, err := ioutil.ReadAll(bodyReader) body, err := ioutil.ReadAll(bodyReader)
if err != nil { if err != nil {
return err return err
} }
out += fmt.Sprintln(string(body)) out += fmt.Sprintln(string(body))
}
fmt.Println(out) fmt.Println(out)
return nil return nil

View file

@ -1,6 +1,8 @@
package imaputils package imaputils
import ( import (
"fmt"
"git.lattuga.net/blallo/papero/config" "git.lattuga.net/blallo/papero/config"
"github.com/emersion/go-imap" "github.com/emersion/go-imap"
) )
@ -81,7 +83,26 @@ func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit, size uin
return msgs, nil return msgs, nil
} }
func FetchMessages(conf *config.AccountData, mailbox string, idList []uint32, debug bool) ([]*imap.Message, error) { type FetchOpts struct {
Mailbox string
IdList []uint32
WithHeaders bool
WithBody bool
Peek bool
}
func (o *FetchOpts) String() string {
return fmt.Sprintf(
"FetchOpts{Mailbox: %s, IdList: %v, WithHeaders: %t, WithBody: %t, Peek: %t}",
o.Mailbox,
o.IdList,
o.WithHeaders,
o.WithBody,
o.Peek,
)
}
func FetchMessages(conf *config.AccountData, opts *FetchOpts, debug bool) ([]*imap.Message, error) {
var messages []*imap.Message var messages []*imap.Message
conn := NewConnection(conf) conn := NewConnection(conf)
@ -91,39 +112,47 @@ func FetchMessages(conf *config.AccountData, mailbox string, idList []uint32, de
} }
defer conn.Close() defer conn.Close()
mbox, err := conn.client.Select(mailbox, true) mbox, err := conn.client.Select(opts.Mailbox, true)
if err != nil { if err != nil {
return messages, err return messages, err
} }
for _, id := range idList { return fetchMessage(mbox, conn, opts)
m, err := fetchMessage(mbox, conn, id)
if err != nil {
return messages, err
}
messages = append(messages, m)
}
return messages, nil
} }
func fetchMessage(mbox *imap.MailboxStatus, conn *IMAPConnection, id uint32) (*imap.Message, error) { func fetchMessage(mbox *imap.MailboxStatus, conn *IMAPConnection, opts *FetchOpts) ([]*imap.Message, error) {
var message *imap.Message var messageAcc []*imap.Message
seqset := new(imap.SeqSet) messages := make(chan *imap.Message, len(opts.IdList))
messages := make(chan *imap.Message, 1)
done := make(chan error, 1) done := make(chan error, 1)
section := &imap.BodySectionName{}
section.Peek = true
items := []imap.FetchItem{imap.FetchEnvelope, section.FetchItem()}
seqset := new(imap.SeqSet)
for _, id := range opts.IdList {
seqset.AddNum(id) seqset.AddNum(id)
}
var items []imap.FetchItem
if opts.WithHeaders {
section := &imap.BodySectionName{Peek: opts.Peek, BodyPartName: imap.BodyPartName{Specifier: imap.HeaderSpecifier}}
items = append(items, section.FetchItem())
}
items = append(items, imap.FetchEnvelope)
if opts.WithBody {
section := &imap.BodySectionName{Peek: opts.Peek, BodyPartName: imap.BodyPartName{Specifier: imap.TextSpecifier}}
items = append(items, section.FetchItem())
}
go func() { go func() {
done <- conn.client.Fetch(seqset, items, messages) done <- conn.client.Fetch(seqset, items, messages)
}() }()
msg := <-messages for m := range messages {
if err := <-done; err != nil { messageAcc = append(messageAcc, m)
return message, err
} }
return msg, nil if err := <-done; err != nil {
return []*imap.Message{}, err
}
return messageAcc, nil
} }