Improve info verb commands
This commit is contained in:
parent
49a211d3d8
commit
f6a764ab7a
2 changed files with 70 additions and 21 deletions
|
@ -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"))
|
||||||
|
|
|
@ -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)
|
||||||
}()
|
}()
|
||||||
|
|
Loading…
Reference in a new issue