~sircmpwn/aerc

143289bbd0736d72553a3c2a080aa3d125366b38 — Drew DeVault 2 years ago 1f23868
Don't parse mail in worker; send a reader instead
6 files changed, 13 insertions(+), 57 deletions(-)

D commands/account/fetch-msg.go
M commands/account/pipe.go
M go.mod
M lib/msgstore.go
M worker/imap/fetch.go
M worker/types/messages.go
D commands/account/fetch-msg.go => commands/account/fetch-msg.go +0 -29
@@ 1,29 0,0 @@
package account

import (
	"errors"

	"github.com/mohamedattahri/mail"

	"git.sr.ht/~sircmpwn/aerc2/widgets"
)

func init() {
	register("fetch-message", FetchMessage)
}

func FetchMessage(aerc *widgets.Aerc, args []string) error {
	if len(args) != 1 {
		return errors.New("Usage: :fetch-message")
	}
	acct := aerc.SelectedAccount()
	if acct == nil {
		return errors.New("No account selected")
	}
	store := acct.Messages().Store()
	msg := acct.Messages().Selected()
	store.FetchBodies([]uint32{msg.Uid}, func(msg *mail.Message) {
		aerc.SetStatus("got message body, woohoo")
	})
	return nil
}

M commands/account/pipe.go => commands/account/pipe.go +2 -5
@@ 1,7 1,6 @@
package account

import (
	"bytes"
	"errors"
	"io"
	"os/exec"


@@ 10,7 9,6 @@ import (
	"git.sr.ht/~sircmpwn/aerc2/widgets"

	"github.com/gdamore/tcell"
	"github.com/mohamedattahri/mail"
)

func init() {


@@ 27,7 25,7 @@ func Pipe(aerc *widgets.Aerc, args []string) error {
	}
	store := acct.Messages().Store()
	msg := acct.Messages().Selected()
	store.FetchBodies([]uint32{msg.Uid}, func(msg *mail.Message) {
	store.FetchBodies([]uint32{msg.Uid}, func(reader io.Reader) {
		cmd := exec.Command(args[1], args[2:]...)
		pipe, err := cmd.StdinPipe()
		if err != nil {


@@ 41,7 39,7 @@ func Pipe(aerc *widgets.Aerc, args []string) error {
				Color(tcell.ColorDefault, tcell.ColorRed)
			return
		}
		name := msg.Subject()
		name := msg.Envelope.Subject
		if len(name) > 12 {
			name = name[:12]
		}


@@ 58,7 56,6 @@ func Pipe(aerc *widgets.Aerc, args []string) error {
		}
		term.OnStart = func() {
			go func() {
				reader := bytes.NewBuffer(msg.Bytes())
				_, err := io.Copy(pipe, reader)
				if err != nil {
					aerc.PushStatus(" "+err.Error(), 10*time.Second).

M go.mod => go.mod +0 -2
@@ 15,10 15,8 @@ require (
	github.com/mattn/go-isatty v0.0.3
	github.com/mattn/go-runewidth v0.0.2
	github.com/mitchellh/go-homedir v1.1.0
	github.com/mohamedattahri/mail v0.0.0-20150907213728-52bc9c59063f
	github.com/nsf/termbox-go v0.0.0-20180129072728-88b7b944be8b
	github.com/riywo/loginshell v0.0.0-20181227004642-c2f4167b2303
	github.com/stretchr/testify v1.3.0
	golang.org/x/text v0.3.0
	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
)

M lib/msgstore.go => lib/msgstore.go +6 -7
@@ 1,10 1,10 @@
package lib

import (
	"io"
	"time"

	"github.com/emersion/go-imap"
	"github.com/mohamedattahri/mail"

	"git.sr.ht/~sircmpwn/aerc2/worker/types"
)


@@ 16,7 16,7 @@ type MessageStore struct {
	// Ordered list of known UIDs
	Uids []uint32

	bodyCallbacks   map[uint32][]func(*mail.Message)
	bodyCallbacks   map[uint32][]func(io.Reader)
	headerCallbacks map[uint32][]func(*types.MessageInfo)

	// Map of uids we've asked the worker to fetch


@@ 33,7 33,7 @@ func NewMessageStore(worker *types.Worker,
		Deleted: make(map[uint32]interface{}),
		DirInfo: *dirInfo,

		bodyCallbacks:   make(map[uint32][]func(*mail.Message)),
		bodyCallbacks:   make(map[uint32][]func(io.Reader)),
		headerCallbacks: make(map[uint32][]func(*types.MessageInfo)),

		pendingBodies:  make(map[uint32]interface{}),


@@ 66,8 66,7 @@ func (store *MessageStore) FetchHeaders(uids []uint32,
	}
}

func (store *MessageStore) FetchBodies(uids []uint32,
	cb func(*mail.Message)) {
func (store *MessageStore) FetchBodies(uids []uint32, cb func(io.Reader)) {

	// TODO: this could be optimized by pre-allocating toFetch and trimming it
	// at the end. In practice we expect to get most messages back in one frame.


@@ 80,7 79,7 @@ func (store *MessageStore) FetchBodies(uids []uint32,
				if list, ok := store.bodyCallbacks[uid]; ok {
					store.bodyCallbacks[uid] = append(list, cb)
				} else {
					store.bodyCallbacks[uid] = []func(*mail.Message){cb}
					store.bodyCallbacks[uid] = []func(io.Reader){cb}
				}
			}
		}


@@ 149,7 148,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
			delete(store.pendingBodies, msg.Uid)
			if cbs, ok := store.bodyCallbacks[msg.Uid]; ok {
				for _, cb := range cbs {
					cb(msg.Mail)
					cb(msg.Reader)
				}
			}
		}

M worker/imap/fetch.go => worker/imap/fetch.go +2 -10
@@ 2,7 2,6 @@ package imap

import (
	"github.com/emersion/go-imap"
	"github.com/mohamedattahri/mail"

	"git.sr.ht/~sircmpwn/aerc2/worker/types"
)


@@ 45,16 44,9 @@ func (imapw *IMAPWorker) handleFetchMessages(
			for _msg := range messages {
				imapw.seqMap[_msg.SeqNum-1] = _msg.Uid
				if reader := _msg.GetBody(section); reader != nil {
					email, err := mail.ReadMessage(reader)
					if err != nil {
						imapw.worker.PostMessage(&types.Error{
							Message: types.RespondTo(msg),
							Error:   err,
						}, nil)
					}
					imapw.worker.PostMessage(&types.MessageBody{
						Mail: email,
						Uid:  _msg.Uid,
						Reader: reader,
						Uid:    _msg.Uid,
					}, nil)
				} else {
					imapw.worker.PostMessage(&types.MessageInfo{

M worker/types/messages.go => worker/types/messages.go +3 -4
@@ 6,7 6,6 @@ import (
	"time"

	"github.com/emersion/go-imap"
	"github.com/mohamedattahri/mail"

	"git.sr.ht/~sircmpwn/aerc2/config"
)


@@ 137,13 136,13 @@ type MessageInfo struct {

type MessageBody struct {
	Message
	Mail *mail.Message
	Uid  uint32
	Reader io.Reader
	Uid    uint32
}

type MessageBodyPart struct {
	Message
	Reader *io.Reader
	Reader io.Reader
	Uid    uint32
}