Selectively print header and body of message
This commit is contained in:
parent
28e0b28a71
commit
75aae2c509
2 changed files with 96 additions and 39 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue