package commands import ( "fmt" "net/mail" "os" "path/filepath" "sort" "text/tabwriter" "time" gomaildir "github.com/emersion/go-maildir" "git.icyphox.sh/mx/config" "git.icyphox.sh/mx/maildir" ) func init() { Register(List{}) } type List struct{} func (List) Aliases() []string { return []string{ "header", "he", "list", "ls", } } func flagToRune(flags []gomaildir.Flag) []rune { r := make([]rune, len(flags)) for i, f := range flags { r[i] = rune(f) } return r } type ListLine struct { from string date time.Time flags string subject string } func printListLine(lines []ListLine) error { // w, h, err := term.GetSize() // if err != nil { // return err // } writer := tabwriter.NewWriter(os.Stdout, 0, 0, 5, '\t', 0) layout := "2006-01-02 15:04" for index, ll := range lines { dt := time.Time.Format(ll.date, layout) fmt.Fprintln(writer, index, ll.flags, dt, ll.from, ll.subject) } // fmt.Printf("%s%d %s %-20s %-s\n", ll.flags, ll.index, ll.date, ll.from, ll.subject) return nil } func (List) Execute(cmd string) error { basePath := config.Config.Maildir.Base mailbox := config.Config.Maildir.Inbox dir := gomaildir.Dir(filepath.Join(basePath, mailbox)) keys, err := dir.Keys() if err != nil { return err } lines := []ListLine{} for _, k := range keys { m := maildir.Message{} flags := []gomaildir.Flag{} m.Key = k m.Dir = dir flags, err = m.Flags() if err != nil { return err } strflags := string(flagToRune(flags)) datestr, err := m.GetHeader("Date") date, err := mail.ParseDate(datestr) subject, err := m.GetHeader("Subject") from, err := m.GetHeader("From") addr, err := mail.ParseAddress(from) if err != nil { return err } ll := ListLine{ from: addr.Name, date: date, flags: strflags, subject: subject, } lines = append(lines, ll) } // sort lines by date sort.Slice(lines, func(i, j int) bool { return lines[i].date.Before(lines[j].date) }) printListLine(lines) return nil }