Browse Source

Improve info verb commands

Blallo 3 years ago
parent
commit
f6a764ab7a
2 changed files with 70 additions and 21 deletions
  1. 54 15
      cli/papero/info.go
  2. 16 6
      imaputils/info.go

+ 54 - 15
cli/papero/info.go

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

+ 16 - 6
imaputils/info.go

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