diff options
Diffstat (limited to 'commands/msg')
-rw-r--r-- | commands/msg/envelope.go | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/commands/msg/envelope.go b/commands/msg/envelope.go new file mode 100644 index 00000000..616798d8 --- /dev/null +++ b/commands/msg/envelope.go @@ -0,0 +1,152 @@ +package msg + +import ( + "errors" + "fmt" + "strings" + + "git.sr.ht/~rjarry/aerc/lib/format" + "git.sr.ht/~rjarry/aerc/logging" + "git.sr.ht/~rjarry/aerc/models" + "git.sr.ht/~rjarry/aerc/widgets" + "git.sr.ht/~sircmpwn/getopt" + "github.com/emersion/go-message/mail" +) + +type Envelope struct{} + +func init() { + register(Envelope{}) +} + +func (Envelope) Aliases() []string { + return []string{"envelope"} +} + +func (Envelope) Complete(aerc *widgets.Aerc, args []string) []string { + return nil +} + +func (Envelope) Execute(aerc *widgets.Aerc, args []string) error { + header := false + fmtStr := "%-20.20s: %s" + opts, _, err := getopt.Getopts(args, "hs:") + if err != nil { + return err + } + for _, opt := range opts { + switch opt.Option { + case 's': + fmtStr = opt.Value + case 'h': + header = true + } + } + + acct := aerc.SelectedAccount() + if acct == nil { + return errors.New("No account selected") + } + + var list []string + if msg, err := acct.SelectedMessage(); err != nil { + return err + } else { + if msg != nil { + if header { + list = parseHeader(msg, fmtStr) + } else { + list = parseEnvelope(msg, fmtStr, + acct.UiConfig().TimestampFormat) + } + } else { + return fmt.Errorf("Selected message is empty.") + } + } + + n := len(list) + aerc.AddDialog(widgets.NewDialog( + widgets.NewListBox( + "Message Envelope. Press <Esc> or <Enter> to close. "+ + "Start typing to filter.", + list, + aerc.SelectedAccountUiConfig(), + func(_ string) { + aerc.CloseDialog() + }, + ), + // start pos on screen + func(h int) int { + if n < h/8*6 { + return h/2 - n/2 - 1 + } + return h / 8 + }, + // dialog height + func(h int) int { + if n < h/8*6 { + return n + 2 + } + return h / 8 * 6 + }, + )) + + return nil +} + +func parseEnvelope(msg *models.MessageInfo, fmtStr, fmtTime string, +) (result []string) { + if envlp := msg.Envelope; envlp != nil { + addStr := func(key, text string) { + result = append(result, fmt.Sprintf(fmtStr, key, text)) + } + addAddr := func(key string, ls []*mail.Address) { + for _, l := range ls { + result = append(result, + fmt.Sprintf(fmtStr, key, + format.AddressForHumans(l))) + } + } + + addStr("Date", envlp.Date.Format(fmtTime)) + addStr("Subject", envlp.Subject) + addStr("Message-Id", envlp.MessageId) + + addAddr("From", envlp.From) + addAddr("To", envlp.To) + addAddr("ReplyTo", envlp.ReplyTo) + addAddr("Cc", envlp.Cc) + addAddr("Bcc", envlp.Bcc) + } + return +} + +func parseHeader(msg *models.MessageInfo, fmtStr string) (result []string) { + if h := msg.RFC822Headers; h != nil { + hf := h.Fields() + for hf.Next() { + text, err := hf.Text() + if err != nil { + logging.Errorf(err.Error()) + text = hf.Value() + } + result = append(result, + headerExpand(fmtStr, hf.Key(), text)...) + } + } + return +} + +func headerExpand(fmtStr, key, text string) []string { + var result []string + switch strings.ToLower(key) { + case "to", "from", "bcc", "cc": + for _, item := range strings.Split(text, ",") { + result = append(result, fmt.Sprintf(fmtStr, key, + strings.TrimSpace(item))) + } + default: + result = append(result, fmt.Sprintf(fmtStr, key, text)) + } + return result +} |