about summary refs log tree commit diff stats
path: root/html/apps/survey.subx.html
Commit message (Expand)AuthorAgeFilesLines
* 6119Kartik Agaram2020-03-101-1/+1
* 6091Kartik Agaram2020-03-061-3/+3
* 6084Kartik Agaram2020-03-061-7/+7
* 6015Kartik Agaram2020-02-171-41/+41
* 6001Kartik Agaram2020-02-091-7/+7
* 5925Kartik Agaram2020-01-271-52/+52
* 5901Kartik Agaram2020-01-191-11/+11
* 5897 - rename comparison instructionsKartik Agaram2020-01-161-35/+35
* 5884Kartik Agaram2020-01-121-82/+82
* 5876 - address -> addrKartik Agaram2020-01-031-28/+28
* 5835Kartik Agaram2019-12-281-5/+5
* 5806Kartik Agaram2019-12-091-247/+247
* 5783Kartik Agaram2019-11-301-3/+3
* 5716Kartik Agaram2019-10-261-3453/+3438
* 5701Kartik Agaram2019-10-171-70/+70
* 5684Kartik Agaram2019-09-211-39/+39
* 5683Kartik Agaram2019-09-201-100/+100
* 5661Kartik Agaram2019-09-151-2/+2
* 5607Kartik Agaram2019-09-011-2/+2
* 5600Kartik Agaram2019-08-311-3612/+3614
* 5592 - switch register names to lowercaseKartik Agaram2019-08-261-1092/+1092
* 5590Kartik Agaram2019-08-251-1/+1
* 5589Kartik Agaram2019-08-251-1/+1
* 5582Kartik Agaram2019-08-251-3341/+3344
* 5499Kartik Agaram2019-07-311-1/+1
* 5490Kartik Agaram2019-07-271-2/+2
* 5485 - promote SubX to top-levelKartik Agaram2019-07-271-0/+3732
ref='/akspecs/aerc/commit/commands/msg/pipe.go?id=363aab5cc19135599cae93f6c9c7abcd23c111c9'>363aab5 ^
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
121
122
123
124
125
126
127
128
129
130
131
132







                              
                 
                 
              


                                           


                                    

















                                                                    


                               

                                                                     
                                                        




                                   

                                         




























                                                                                       





















                                                                             



                                                                           




                                                                                
                         










                                                                                                   





                                                                                
                         




                  
package msg

import (
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"mime/quotedprintable"
	"os/exec"
	"strings"
	"time"

	"git.sr.ht/~sircmpwn/aerc/commands"
	"git.sr.ht/~sircmpwn/aerc/widgets"

	"git.sr.ht/~sircmpwn/getopt"
	"github.com/gdamore/tcell"
)

type Pipe struct{}

func init() {
	register(Pipe{})
}

func (_ Pipe) Aliases() []string {
	return []string{"pipe"}
}

func (_ Pipe) Complete(aerc *widgets.Aerc, args []string) []string {
	return nil
}

func (_ Pipe) Execute(aerc *widgets.Aerc, args []string) error {
	var (
		background bool
		pipeFull   bool
		pipePart   bool
	)
	// TODO: let user specify part by index or preferred mimetype
	opts, optind, err := getopt.Getopts(args, "bmp")
	if err != nil {
		return err
	}
	for _, opt := range opts {
		switch opt.Option {
		case 'b':
			background = true
		case 'm':
			if pipePart {
				return errors.New("-m and -p are mutually exclusive")
			}
			pipeFull = true
		case 'p':
			if pipeFull {
				return errors.New("-m and -p are mutually exclusive")
			}
			pipePart = true
		}
	}
	cmd := args[optind:]
	if len(cmd) == 0 {
		return errors.New("Usage: pipe [-mp] <cmd> [args...]")
	}

	provider := aerc.SelectedTab().(widgets.ProvidesMessage)
	if !pipeFull && !pipePart {
		if _, ok := provider.(*widgets.MessageViewer); ok {
			pipePart = true
		} else if _, ok := provider.(*widgets.AccountView); ok {
			pipeFull = true
		} else {
			return errors.New(
				"Neither -m nor -p specified and cannot infer default")
		}
	}

	doTerm := func(reader io.Reader, name string) {
		term, err := commands.QuickTerm(aerc, cmd, reader)
		if err != nil {
			aerc.PushError(" " + err.Error())
			return
		}
		aerc.NewTab(term, name)
	}

	doExec := func(reader io.Reader) {
		ecmd := exec.Command(cmd[0], cmd[1:]...)
		err := ecmd.Run()
		if err != nil {
			aerc.PushStatus(" "+err.Error(), 10*time.Second).
				Color(tcell.ColorDefault, tcell.ColorRed)
		} else {
			aerc.PushStatus(fmt.Sprintf(
				"%s: complete", args[0]), 10*time.Second).
				Color(tcell.ColorDefault, tcell.ColorDefault)
		}
	}

	if pipeFull {
		store := provider.Store()
		msg := provider.SelectedMessage()
		store.FetchFull([]uint32{msg.Uid}, func(reader io.Reader) {
			if background {
				doExec(reader)
			} else {
				doTerm(reader, fmt.Sprintf(
					"%s <%s", cmd[0], msg.Envelope.Subject))
			}
		})
	} else if pipePart {
		p := provider.SelectedMessagePart()
		p.Store.FetchBodyPart(p.Msg.Uid, p.Index, func(reader io.Reader) {
			// email parts are encoded as 7bit (plaintext), quoted-printable, or base64
			if strings.EqualFold(p.Part.Encoding, "base64") {
				reader = base64.NewDecoder(base64.StdEncoding, reader)
			} else if strings.EqualFold(p.Part.Encoding, "quoted-printable") {
				reader = quotedprintable.NewReader(reader)
			}

			if background {
				doExec(reader)
			} else {
				name := fmt.Sprintf("%s <%s/[%d]",
					cmd[0], p.Msg.Envelope.Subject, p.Index)
				doTerm(reader, name)
			}
		})
	}

	return nil
}