package commands import ( "net/mail" "path/filepath" "sort" "strings" "time" gomaildir "github.com/emersion/go-maildir" "github.com/jedib0t/go-pretty/v6/table" "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 flagToString(flags []gomaildir.Flag) []string { if len(flags) > 0 { r := make([]string, len(flags)) for i, f := range flags { r[i] = maildir.FlagMap[f] } return r } return []string{"N"} } func formatDate(date time.Time) string { return date.Format("2006-02-01 15:04") } type ListLine struct { from string date time.Time flags string subject string } func (ll *ListLine) makeListLines(keys []string, dir gomaildir.Dir) ([]ListLine, error) { 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 nil, err } strflags := strings.Join(flagToString(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 nil, err } if len(addr.Name) > 0 { ll.from = addr.Name } else { ll.from = addr.Address } ll.date = date ll.flags = strflags ll.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) }) return lines, 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 } tbl := GetTable() ll := ListLine{} lines, err := ll.makeListLines(keys, dir) for index, line := range lines { tbl.AppendRow(table.Row{ line.flags, index, line.from, formatDate(line.date), line.subject, }) } tbl.Render() return err }