all repos — mx @ 12fc7b4d3cf1c04ee2075775a683b7bc6227ee1f

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