8f9bb2b289
Signed and/or encrypted PGP messages did not behave properly for pipe, open, and save commands. Specifically, the proper Message Part would not be passed to the command in the MessageViewer. This is due to the encapsulation of the body structure. This patch fixes the behavior for piping|opening|saving of message parts. Fixes: https://todo.sr.ht/~rjarry/aerc/47 Reported-by: ~ph14nix Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Moritz Poldrack <moritz@poldrack.dev> Acked-by: Robin Jarry <robin@jarry.cc>
99 lines
2 KiB
Go
99 lines
2 KiB
Go
package msgview
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"mime"
|
|
"os"
|
|
"time"
|
|
|
|
"git.sr.ht/~rjarry/aerc/commands"
|
|
"git.sr.ht/~rjarry/aerc/lib"
|
|
"git.sr.ht/~rjarry/aerc/logging"
|
|
"git.sr.ht/~rjarry/aerc/widgets"
|
|
)
|
|
|
|
type Open struct{}
|
|
|
|
func init() {
|
|
register(Open{})
|
|
}
|
|
|
|
func (Open) Aliases() []string {
|
|
return []string{"open", "open-link"}
|
|
}
|
|
|
|
func (Open) Complete(aerc *widgets.Aerc, args []string) []string {
|
|
mv := aerc.SelectedTab().(*widgets.MessageViewer)
|
|
if mv != nil {
|
|
if p := mv.SelectedMessagePart(); p != nil {
|
|
return commands.CompletionFromList(aerc, p.Links, args)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (Open) Execute(aerc *widgets.Aerc, args []string) error {
|
|
mv := aerc.SelectedTab().(*widgets.MessageViewer)
|
|
p := mv.SelectedMessagePart()
|
|
|
|
if args[0] == "open-link" && len(args) > 1 {
|
|
if link := args[1]; link != "" {
|
|
go func() {
|
|
if err := lib.NewXDGOpen(link).Start(); err != nil {
|
|
aerc.PushError(fmt.Sprintf("%s: %s", args[0], err.Error()))
|
|
}
|
|
}()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
mv.MessageView().FetchBodyPart(p.Index, func(reader io.Reader) {
|
|
extension := ""
|
|
// try to determine the correct extension based on mimetype
|
|
if part, err := p.Msg.BodyStructure.PartAtIndex(p.Index); err == nil {
|
|
mimeType := fmt.Sprintf("%s/%s", part.MIMEType, part.MIMESubType)
|
|
|
|
if exts, _ := mime.ExtensionsByType(mimeType); len(exts) > 0 {
|
|
extension = exts[0]
|
|
}
|
|
}
|
|
|
|
tmpFile, err := ioutil.TempFile(os.TempDir(), "aerc-*"+extension)
|
|
if err != nil {
|
|
aerc.PushError(err.Error())
|
|
return
|
|
}
|
|
defer tmpFile.Close()
|
|
|
|
_, err = io.Copy(tmpFile, reader)
|
|
if err != nil {
|
|
aerc.PushError(err.Error())
|
|
return
|
|
}
|
|
|
|
xdg := lib.NewXDGOpen(tmpFile.Name())
|
|
// pass through any arguments the user provided to the underlying handler
|
|
if len(args) > 1 {
|
|
xdg.SetArgs(args[1:])
|
|
}
|
|
err = xdg.Start()
|
|
if err != nil {
|
|
aerc.PushError(err.Error())
|
|
return
|
|
}
|
|
go func() {
|
|
defer logging.PanicHandler()
|
|
|
|
err := xdg.Wait()
|
|
if err != nil {
|
|
aerc.PushError(err.Error())
|
|
}
|
|
}()
|
|
|
|
aerc.PushStatus("Opened", 10*time.Second)
|
|
})
|
|
|
|
return nil
|
|
}
|