Improve info verb commands

This commit is contained in:
Blallo 2021-03-18 23:45:06 +01:00
parent 49a211d3d8
commit f6a764ab7a
No known key found for this signature in database
GPG key ID: 0CBE577C9B72DC3F
2 changed files with 70 additions and 21 deletions

View file

@ -21,13 +21,11 @@ const maxUInt32 = int(^uint32(0))
var infoVerbs cli.CommandMap var infoVerbs cli.CommandMap
func init() { func init() {
lsMailbox := LsMailboxCmd{}
lsMessages := LsMsgCmd{}
catMessage := CatMsgCmd{}
infoVerbs = cli.CommandMap{ infoVerbs = cli.CommandMap{
"list-mailboxes": lsMailbox, "list-mailboxes": LsMailboxCmd{},
"list-messages": lsMessages, // "list-subscribed": LsSubscribedCmd{},
"display-message": catMessage, "list-messages": LsMsgCmd{},
"display-message": CatMsgCmd{},
} }
} }
@ -123,7 +121,7 @@ func (l LsMsgCmd) Func(args []string) error {
Log.Debug("enter info list-messages") Log.Debug("enter info list-messages")
} }
var limit uint var limit uint
var withSeq, withFrom, withDate bool var withSeq, withFrom, withDate, withFlags bool
var sep string var sep string
flagset := flag.NewFlagSet(args[0], flag.ExitOnError) flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.StringVar(&sep, "sep", "\t", "separator between fields") flagset.StringVar(&sep, "sep", "\t", "separator between fields")
@ -131,6 +129,7 @@ func (l LsMsgCmd) Func(args []string) error {
flagset.BoolVar(&withSeq, "seq", false, "show sequence number") flagset.BoolVar(&withSeq, "seq", false, "show sequence number")
flagset.BoolVar(&withFrom, "from", false, "show From address") flagset.BoolVar(&withFrom, "from", false, "show From address")
flagset.BoolVar(&withDate, "date", false, "show message date") flagset.BoolVar(&withDate, "date", false, "show message date")
flagset.BoolVar(&withFlags, "flags", false, "show message flags")
flagset.Usage = func() { l.Help(os.Stdout, flagset) } flagset.Usage = func() { l.Help(os.Stdout, flagset) }
flagset.Parse(args[1:]) flagset.Parse(args[1:])
@ -140,11 +139,18 @@ func (l LsMsgCmd) Func(args []string) error {
os.Exit(1) os.Exit(1)
} }
msgs, err := imaputils.ListMessages(Session.Config, uint32(limit), Session.Info.Opts.Debug, subArgs[0]) msgs, err := imaputils.ListMessages(
Session.Config,
&imaputils.ListMessagesOpts{
Mailbox: subArgs[0],
Limit: uint32(limit),
},
Session.Info.Opts.Debug,
)
if err != nil { if err != nil {
return err return err
} }
printMsgs(msgs, withSeq, withFrom, withDate, sep) printMsgs(msgs, withSeq, withFrom, withDate, withFlags, sep)
return nil return nil
} }
@ -158,9 +164,9 @@ func numberSize(n uint32) int {
return int(math.Floor(math.Log10(float64(n)))) return int(math.Floor(math.Log10(float64(n))))
} }
func printMsgs(msgs []*imap.Message, withSeq, withFrom, withDate bool, sep string) { func printMsgs(msgs []*imap.Message, withSeq, withFrom, withDate, withFlags bool, sep string) {
var maxSeq, maxDateLen, maxFromLen int var maxSeq, maxDateLen, maxFromLen, maxFlagsLen int
var out, seqFmtStr, dateFmtStr, fromFmtStr string var out, seqFmtStr, dateFmtStr, fromFmtStr, flagsFmtStr string
for _, msg := range msgs { for _, msg := range msgs {
if seqSize := numberSize(msg.SeqNum); withSeq && seqSize > maxSeq { if seqSize := numberSize(msg.SeqNum); withSeq && seqSize > maxSeq {
maxSeq = seqSize maxSeq = seqSize
@ -178,6 +184,16 @@ func printMsgs(msgs []*imap.Message, withSeq, withFrom, withDate bool, sep strin
} }
} }
} }
if withFlags {
var flags string
for _, f := range msg.Flags {
flags += fmt.Sprintf("%s ", f)
}
flags = strings.TrimRight(flags, " ")
if flagsLen := len(flags); flagsLen > maxFlagsLen {
maxFlagsLen = flagsLen
}
}
} }
if withSeq { if withSeq {
@ -189,6 +205,9 @@ func printMsgs(msgs []*imap.Message, withSeq, withFrom, withDate bool, sep strin
if withFrom { if withFrom {
fromFmtStr = fmt.Sprintf("%%-%dv%s", maxFromLen, sep) fromFmtStr = fmt.Sprintf("%%-%dv%s", maxFromLen, sep)
} }
if withFlags {
flagsFmtStr = fmt.Sprintf("%%-%dv%s", maxFlagsLen, sep)
}
for _, msg := range msgs { for _, msg := range msgs {
var line string var line string
if withSeq { if withSeq {
@ -200,6 +219,13 @@ func printMsgs(msgs []*imap.Message, withSeq, withFrom, withDate bool, sep strin
if withFrom { if withFrom {
line += fmt.Sprintf(fromFmtStr, msg.Envelope.From[0].Address()) line += fmt.Sprintf(fromFmtStr, msg.Envelope.From[0].Address())
} }
if withFlags {
var flags string
for _, f := range msg.Flags {
flags += fmt.Sprintf("%s ", f)
}
line += fmt.Sprintf(flagsFmtStr, strings.TrimRight(flags, " "))
}
line += msg.Envelope.Subject line += msg.Envelope.Subject
out += fmt.Sprintln(line) out += fmt.Sprintln(line)
} }
@ -213,10 +239,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 var withHeaders, withBody, withFlags, 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(&withHeaders, "headers", false, "toggle headers display")
flagset.BoolVar(&withBody, "no-body", false, "hide body") flagset.BoolVar(&withBody, "no-body", false, "hide body")
flagset.BoolVar(&withFlags, "flags", false, "show flags")
flagset.BoolVar(&markRead, "seen", false, "mark as seen if not yet seen") 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:])
@ -245,6 +272,7 @@ func (c CatMsgCmd) Func(args []string) error {
IdList: idList, IdList: idList,
WithHeaders: withHeaders, WithHeaders: withHeaders,
WithBody: !withBody, WithBody: !withBody,
WithFlags: withFlags,
Peek: !markRead, Peek: !markRead,
} }
if Session.Info.Opts.Debug { if Session.Info.Opts.Debug {
@ -257,7 +285,7 @@ func (c CatMsgCmd) Func(args []string) error {
} }
for _, m := range messages { for _, m := range messages {
err = printMessage(m, opts) err = printMessage(m, opts, withFlags)
if err != nil { if err != nil {
return err return err
} }
@ -286,9 +314,20 @@ func parseToUint32(s string) (uint32, error) {
return uint32(out), nil return uint32(out), nil
} }
func printMessage(m *imap.Message, opts *imaputils.FetchOpts) error { func printMessage(m *imap.Message, opts *imaputils.FetchOpts, withFlags bool) error {
var out string var out string
if withFlags {
if Session.Info.Opts.Debug {
Log.Debug(m.Flags)
}
for _, f := range m.Flags {
out += fmt.Sprintf("%s ", f)
}
out = strings.TrimRight(out, " ")
out += "\n"
}
if opts.WithHeaders { 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"))

View file

@ -34,7 +34,12 @@ func ListMailboxes(conf *config.AccountData, debug bool) ([]*imap.MailboxInfo, e
return mailboxes, nil return mailboxes, nil
} }
func ListMessages(conf *config.AccountData, limit uint32, debug bool, mailbox string) ([]*imap.Message, error) { type ListMessagesOpts struct {
Mailbox string
Limit uint32
}
func ListMessages(conf *config.AccountData, opts *ListMessagesOpts, debug bool) ([]*imap.Message, error) {
var messages []*imap.Message var messages []*imap.Message
conn := NewConnection(conf) conn := NewConnection(conf)
@ -44,19 +49,19 @@ func ListMessages(conf *config.AccountData, limit uint32, debug bool, mailbox st
} }
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
} }
return getMessages(mbox, conn, limit, 10) return getMessages(mbox, conn, opts.Limit)
} }
func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit, size uint32) ([]*imap.Message, error) { func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit uint32) ([]*imap.Message, error) {
var start uint32 var start uint32
var msgs []*imap.Message var msgs []*imap.Message
seqset := new(imap.SeqSet) seqset := new(imap.SeqSet)
messages := make(chan *imap.Message, size) messages := make(chan *imap.Message, 10)
done := make(chan error, 1) done := make(chan error, 1)
switch { switch {
@ -70,7 +75,7 @@ func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit, size uin
seqset.AddRange(start, mbox.Messages) seqset.AddRange(start, mbox.Messages)
go func() { go func() {
done <- conn.client.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope}, messages) done <- conn.client.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope, imap.FetchFlags}, messages)
}() }()
for msg := range messages { for msg := range messages {
@ -88,6 +93,7 @@ type FetchOpts struct {
IdList []uint32 IdList []uint32
WithHeaders bool WithHeaders bool
WithBody bool WithBody bool
WithFlags bool
Peek bool Peek bool
} }
@ -144,6 +150,10 @@ func fetchMessage(mbox *imap.MailboxStatus, conn *IMAPConnection, opts *FetchOpt
items = append(items, section.FetchItem()) items = append(items, section.FetchItem())
} }
if opts.WithFlags {
items = append(items, imap.FetchFlags)
}
go func() { go func() {
done <- conn.client.Fetch(seqset, items, messages) done <- conn.client.Fetch(seqset, items, messages)
}() }()