all repos — mx @ 403e2401a361d5108e6646ad2c1c740d99bf77fb

work in progress MUA

commands/list.go (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
package commands

import (
	"net/mail"
	"path/filepath"
	"sort"
	"strings"
	"time"

	gomaildir "github.com/emersion/go-maildir"
	"github.com/jedib0t/go-pretty/v6/table"
	"github.com/jedib0t/go-pretty/v6/text"

	"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
		}

		// TODO: remove text.Trim and have this configured in column
		// config (WidthMaxEnforcer)
		// ref: https://github.com/jedib0t/go-pretty/issues/170
		if len(addr.Name) > 0 {
			ll.from = text.Trim(addr.Name, 20)
		} else {
			ll.from = text.Trim(addr.Address, 20)
		}
		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
}