pipe: use go-mbox for writing multiple messages
Use go-mbox for piping out multiple messages in the mbox format. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
parent
e572087e58
commit
5102d32cea
|
@ -11,6 +11,7 @@ import (
|
||||||
"git.sr.ht/~rjarry/aerc/commands"
|
"git.sr.ht/~rjarry/aerc/commands"
|
||||||
"git.sr.ht/~rjarry/aerc/logging"
|
"git.sr.ht/~rjarry/aerc/logging"
|
||||||
"git.sr.ht/~rjarry/aerc/widgets"
|
"git.sr.ht/~rjarry/aerc/widgets"
|
||||||
|
mboxer "git.sr.ht/~rjarry/aerc/worker/mbox"
|
||||||
"git.sr.ht/~rjarry/aerc/worker/types"
|
"git.sr.ht/~rjarry/aerc/worker/types"
|
||||||
|
|
||||||
"git.sr.ht/~sircmpwn/getopt"
|
"git.sr.ht/~sircmpwn/getopt"
|
||||||
|
@ -174,7 +175,7 @@ func (Pipe) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return infoi.Envelope.MessageId < infoj.Envelope.MessageId
|
return infoi.Envelope.MessageId < infoj.Envelope.MessageId
|
||||||
})
|
})
|
||||||
|
|
||||||
reader := newMessagesReader(messages)
|
reader := newMessagesReader(messages, len(messages) > 1)
|
||||||
if background {
|
if background {
|
||||||
doExec(reader)
|
doExec(reader)
|
||||||
} else {
|
} else {
|
||||||
|
@ -204,43 +205,17 @@ func (Pipe) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The actual sender address does not matter, nor does the date. This is mostly indended
|
func newMessagesReader(messages []*types.FullMessage, useMbox bool) io.Reader {
|
||||||
// for git am which requires separators to look like something valid.
|
pr, pw := io.Pipe()
|
||||||
// https://github.com/git/git/blame/v2.35.1/builtin/mailsplit.c#L15-L44
|
go func() {
|
||||||
var mboxSeparator []byte = []byte("From ???@??? Tue Jun 23 16:32:49 1981\n")
|
defer pw.Close()
|
||||||
|
for _, msg := range messages {
|
||||||
type messagesReader struct {
|
if useMbox {
|
||||||
messages []*types.FullMessage
|
mboxer.Write(pw, msg.Content.Reader, "", time.Now())
|
||||||
mbox bool
|
} else {
|
||||||
separatorNeeded bool
|
io.Copy(pw, msg.Content.Reader)
|
||||||
}
|
|
||||||
|
|
||||||
func newMessagesReader(messages []*types.FullMessage) io.Reader {
|
|
||||||
needMboxSeparator := len(messages) > 1
|
|
||||||
return &messagesReader{messages, needMboxSeparator, needMboxSeparator}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mr *messagesReader) Read(p []byte) (n int, err error) {
|
|
||||||
for len(mr.messages) > 0 {
|
|
||||||
if mr.separatorNeeded {
|
|
||||||
offset := copy(p, mboxSeparator)
|
|
||||||
n, err = mr.messages[0].Content.Reader.Read(p[offset:])
|
|
||||||
n += offset
|
|
||||||
mr.separatorNeeded = false
|
|
||||||
} else {
|
|
||||||
n, err = mr.messages[0].Content.Reader.Read(p)
|
|
||||||
}
|
|
||||||
if err == io.EOF {
|
|
||||||
mr.messages = mr.messages[1:]
|
|
||||||
mr.separatorNeeded = mr.mbox
|
|
||||||
}
|
|
||||||
if n > 0 || err != io.EOF {
|
|
||||||
if err == io.EOF && len(mr.messages) > 0 {
|
|
||||||
// Don't return EOF yet. More messages remain.
|
|
||||||
err = nil
|
|
||||||
}
|
}
|
||||||
return n, err
|
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
return 0, io.EOF
|
return pr
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue